From 00ac809cc71e3747c81bf01be95d5cf21d93d9a0 Mon Sep 17 00:00:00 2001 From: Jens Arnold Date: Sat, 12 Apr 2008 07:53:33 +0000 Subject: LCD drivers: * Automatically optimise horizontal and vertical lines drawn via _drawline(), with debug message to show possible optimisations in the caller. * Get rid of the extra ICODE function declarations by putting the attribute into the definition. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17081 a1c6a512-1295-4272-9138-f99709370657 --- firmware/drivers/lcd-16bit.c | 54 ++++++++++----------- firmware/drivers/lcd-1bit-vert.c | 13 +++++ firmware/drivers/lcd-2bit-horz.c | 90 +++++++++++++++++------------------ firmware/drivers/lcd-2bit-vert.c | 88 ++++++++++++++++------------------ firmware/drivers/lcd-2bit-vi.c | 13 +++++ firmware/drivers/lcd-remote-1bit-v.c | 1 + firmware/drivers/lcd-remote-2bit-vi.c | 1 + 7 files changed, 140 insertions(+), 120 deletions(-) diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c index 20d30c572c..dab29efef7 100644 --- a/firmware/drivers/lcd-16bit.c +++ b/firmware/drivers/lcd-16bit.c @@ -204,32 +204,27 @@ int lcd_getstringsize(const unsigned char *str, int *w, int *h) #define LCDADDR(x, y) (&lcd_framebuffer[(y)][(x)]) -static void setpixel(fb_data *address) ICODE_ATTR; -static void setpixel(fb_data *address) +static void ICODE_ATTR setpixel(fb_data *address) { *address = current_vp->fg_pattern; } -static void clearpixel(fb_data *address) ICODE_ATTR; -static void clearpixel(fb_data *address) +static void ICODE_ATTR clearpixel(fb_data *address) { *address = current_vp->bg_pattern; } -static void clearimgpixel(fb_data *address) ICODE_ATTR; -static void clearimgpixel(fb_data *address) +static void ICODE_ATTR clearimgpixel(fb_data *address) { *address = *(fb_data *)((long)address + lcd_backdrop_offset); } -static void flippixel(fb_data *address) ICODE_ATTR; -static void flippixel(fb_data *address) +static void ICODE_ATTR flippixel(fb_data *address) { *address = ~(*address); } -static void nopixel(fb_data *address) ICODE_ATTR; -static void nopixel(fb_data *address) +static void ICODE_ATTR nopixel(fb_data *address) { (void)address; } @@ -349,8 +344,20 @@ void lcd_drawline(int x1, int y1, int x2, int y2) int y, yinc1, yinc2; lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode]; - deltax = abs(x2 - x1); deltay = abs(y2 - y1); + if (deltay == 0) + { + DEBUGF("lcd_drawline() called for horizontal line - optimisation.\n"); + lcd_hline(x1, x2, y1); + return; + } + deltax = abs(x2 - x1); + if (deltax == 0) + { + DEBUGF("lcd_drawline() called for vertical line - optimisation.\n"); + lcd_vline(x1, y1, y2); + return; + } xinc2 = 1; yinc2 = 1; @@ -699,11 +706,9 @@ static void lcd_gradient_rect_scroll(int x1, int x2, int y, int h, /* Draw a partial monochrome bitmap */ -void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, - int stride, int x, int y, int width, int height) - ICODE_ATTR; -void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, - int stride, int x, int y, int width, int height) +void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, + int src_y, int stride, int x, int y, + int width, int height) { const unsigned char *src_end; bool has_backdrop; @@ -798,11 +803,9 @@ void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width, int heig } /* Draw a partial native bitmap */ -void lcd_bitmap_part(const fb_data *src, int src_x, int src_y, - int stride, int x, int y, int width, int height) - ICODE_ATTR; -void lcd_bitmap_part(const fb_data *src, int src_x, int src_y, - int stride, int x, int y, int width, int height) +void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y, + int stride, int x, int y, int width, + int height) { fb_data *dst, *dst_end; @@ -851,12 +854,9 @@ void lcd_bitmap(const fb_data *src, int x, int y, int width, int height) #if !defined(TOSHIBA_GIGABEAT_F) && !defined(TOSHIBA_GIGABEAT_S) \ || defined(SIMULATOR) /* Draw a partial native bitmap */ -void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y, - int stride, int x, int y, int width, - int height) ICODE_ATTR; -void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y, - int stride, int x, int y, int width, - int height) +void ICODE_ATTR lcd_bitmap_transparent_part(const fb_data *src, int src_x, + int src_y, int stride, int x, + int y, int width, int height) { fb_data *dst, *dst_end; diff --git a/firmware/drivers/lcd-1bit-vert.c b/firmware/drivers/lcd-1bit-vert.c index 3a6e59c461..c6fe40cdb7 100644 --- a/firmware/drivers/lcd-1bit-vert.c +++ b/firmware/drivers/lcd-1bit-vert.c @@ -36,6 +36,7 @@ #define LCDFN(fn) lcd_ ## fn #define FBFN(fn) fb_ ## fn #define LCDM(ma) LCD_ ## ma +#define LCDNAME "lcd_" #define MAIN_LCD #endif @@ -290,7 +291,19 @@ void LCDFN(drawline)(int x1, int y1, int x2, int y2) LCDFN(pixelfunc_type) *pfunc = LCDFN(pixelfuncs)[current_vp->drawmode]; deltax = abs(x2 - x1); + if (deltax == 0) + { + DEBUGF(LCDNAME "drawline() called for vertical line - optimisation.\n"); + LCDFN(vline)(x1, y1, y2); + return; + } deltay = abs(y2 - y1); + if (deltay == 0) + { + DEBUGF(LCDNAME "drawline() called for horizontal line - optimisation.\n"); + LCDFN(hline)(x1, x2, y1); + return; + } xinc2 = 1; yinc2 = 1; diff --git a/firmware/drivers/lcd-2bit-horz.c b/firmware/drivers/lcd-2bit-horz.c index 195885c072..30901efb98 100644 --- a/firmware/drivers/lcd-2bit-horz.c +++ b/firmware/drivers/lcd-2bit-horz.c @@ -239,43 +239,38 @@ lcd_pixelfunc_type* const * lcd_pixelfuncs = lcd_pixelfuncs_bgcolor; /* 'mask' and 'bits' contain 2 bits per pixel */ -static void flipblock(fb_data *address, unsigned mask, unsigned bits) - ICODE_ATTR; -static void flipblock(fb_data *address, unsigned mask, unsigned bits) +static void ICODE_ATTR flipblock(fb_data *address, unsigned mask, + unsigned bits) { *address ^= bits & mask; } -static void bgblock(fb_data *address, unsigned mask, unsigned bits) - ICODE_ATTR; -static void bgblock(fb_data *address, unsigned mask, unsigned bits) +static void ICODE_ATTR bgblock(fb_data *address, unsigned mask, + unsigned bits) { unsigned data = *address; *address = data ^ ((data ^ bg_pattern) & mask & ~bits); } -static void bgimgblock(fb_data *address, unsigned mask, unsigned bits) - ICODE_ATTR; -static void bgimgblock(fb_data *address, unsigned mask, unsigned bits) +static void ICODE_ATTR bgimgblock(fb_data *address, unsigned mask, + unsigned bits) { unsigned data = *address; *address = data ^ ((data ^ *(address + lcd_backdrop_offset)) & mask & ~bits); } -static void fgblock(fb_data *address, unsigned mask, unsigned bits) - ICODE_ATTR; -static void fgblock(fb_data *address, unsigned mask, unsigned bits) +static void ICODE_ATTR fgblock(fb_data *address, unsigned mask, + unsigned bits) { unsigned data = *address; *address = data ^ ((data ^ fg_pattern) & mask & bits); } -static void solidblock(fb_data *address, unsigned mask, unsigned bits) - ICODE_ATTR; -static void solidblock(fb_data *address, unsigned mask, unsigned bits) +static void ICODE_ATTR solidblock(fb_data *address, unsigned mask, + unsigned bits) { unsigned data = *address; unsigned bgp = bg_pattern; @@ -284,9 +279,8 @@ static void solidblock(fb_data *address, unsigned mask, unsigned bits) *address = data ^ ((data ^ bits) & mask); } -static void solidimgblock(fb_data *address, unsigned mask, unsigned bits) - ICODE_ATTR; -static void solidimgblock(fb_data *address, unsigned mask, unsigned bits) +static void ICODE_ATTR solidimgblock(fb_data *address, unsigned mask, + unsigned bits) { unsigned data = *address; unsigned bgp = *(address + lcd_backdrop_offset); @@ -295,43 +289,38 @@ static void solidimgblock(fb_data *address, unsigned mask, unsigned bits) *address = data ^ ((data ^ bits) & mask); } -static void flipinvblock(fb_data *address, unsigned mask, unsigned bits) - ICODE_ATTR; -static void flipinvblock(fb_data *address, unsigned mask, unsigned bits) +static void ICODE_ATTR flipinvblock(fb_data *address, unsigned mask, + unsigned bits) { *address ^= ~bits & mask; } -static void bginvblock(fb_data *address, unsigned mask, unsigned bits) - ICODE_ATTR; -static void bginvblock(fb_data *address, unsigned mask, unsigned bits) +static void ICODE_ATTR bginvblock(fb_data *address, unsigned mask, + unsigned bits) { unsigned data = *address; *address = data ^ ((data ^ bg_pattern) & mask & bits); } -static void bgimginvblock(fb_data *address, unsigned mask, unsigned bits) - ICODE_ATTR; -static void bgimginvblock(fb_data *address, unsigned mask, unsigned bits) +static void ICODE_ATTR bgimginvblock(fb_data *address, unsigned mask, + unsigned bits) { unsigned data = *address; *address = data ^ ((data ^ *(address + lcd_backdrop_offset)) & mask & bits); } -static void fginvblock(fb_data *address, unsigned mask, unsigned bits) - ICODE_ATTR; -static void fginvblock(fb_data *address, unsigned mask, unsigned bits) +static void ICODE_ATTR fginvblock(fb_data *address, unsigned mask, + unsigned bits) { unsigned data = *address; *address = data ^ ((data ^ fg_pattern) & mask & ~bits); } -static void solidinvblock(fb_data *address, unsigned mask, unsigned bits) - ICODE_ATTR; -static void solidinvblock(fb_data *address, unsigned mask, unsigned bits) +static void ICODE_ATTR solidinvblock(fb_data *address, unsigned mask, + unsigned bits) { unsigned data = *address; unsigned fgp = fg_pattern; @@ -340,9 +329,8 @@ static void solidinvblock(fb_data *address, unsigned mask, unsigned bits) *address = data ^ ((data ^ bits) & mask); } -static void solidimginvblock(fb_data *address, unsigned mask, unsigned bits) - ICODE_ATTR; -static void solidimginvblock(fb_data *address, unsigned mask, unsigned bits) +static void ICODE_ATTR solidimginvblock(fb_data *address, unsigned mask, + unsigned bits) { unsigned data = *address; unsigned fgp = fg_pattern; @@ -459,8 +447,20 @@ void lcd_drawline(int x1, int y1, int x2, int y2) int y, yinc1, yinc2; lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[current_vp->drawmode]; - deltax = abs(x2 - x1); deltay = abs(y2 - y1); + if (deltay == 0) + { + DEBUGF("lcd_drawline() called for horizontal line - optimisation.\n"); + lcd_hline(x1, x2, y1); + return; + } + deltax = abs(x2 - x1); + if (deltax == 0) + { + DEBUGF("lcd_drawline() called for vertical line - optimisation.\n"); + lcd_vline(x1, y1, y2); + return; + } xinc2 = 1; yinc2 = 1; @@ -702,11 +702,9 @@ void lcd_fillrect(int x, int y, int width, int height) * 0..7, the second row defines pixel row 8..15 etc. */ /* Draw a partial monochrome bitmap */ -void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, - int stride, int x, int y, int width, int height) - ICODE_ATTR; -void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, - int stride, int x, int y, int width, int height) +void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, + int src_y, int stride, int x, int y, + int width, int height) { int ny, nx, ymax; const unsigned char * src_end; @@ -795,11 +793,9 @@ void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width, int heig * This is the same as the internal lcd hw format. */ /* Draw a partial native bitmap */ -void lcd_bitmap_part(const unsigned char *src, int src_x, int src_y, - int stride, int x, int y, int width, int height) - ICODE_ATTR; -void lcd_bitmap_part(const unsigned char *src, int src_x, int src_y, - int stride, int x, int y, int width, int height) +void ICODE_ATTR lcd_bitmap_part(const unsigned char *src, int src_x, + int src_y, int stride, int x, int y, + int width, int height) { int shift, nx; unsigned char *dst, *dst_end; diff --git a/firmware/drivers/lcd-2bit-vert.c b/firmware/drivers/lcd-2bit-vert.c index 5373bb9f0a..d43bf6cc81 100644 --- a/firmware/drivers/lcd-2bit-vert.c +++ b/firmware/drivers/lcd-2bit-vert.c @@ -242,43 +242,38 @@ lcd_pixelfunc_type* const lcd_pixelfuncs_backdrop[8] = { lcd_pixelfunc_type* const * lcd_pixelfuncs = lcd_pixelfuncs_bgcolor; /* 'mask' and 'bits' contain 2 bits per pixel */ -static void flipblock(fb_data *address, unsigned mask, unsigned bits) - ICODE_ATTR; -static void flipblock(fb_data *address, unsigned mask, unsigned bits) +static void ICODE_ATTR flipblock(fb_data *address, unsigned mask, + unsigned bits) { *address ^= bits & mask; } -static void bgblock(fb_data *address, unsigned mask, unsigned bits) - ICODE_ATTR; -static void bgblock(fb_data *address, unsigned mask, unsigned bits) +static void ICODE_ATTR bgblock(fb_data *address, unsigned mask, + unsigned bits) { unsigned data = *address; *address = data ^ ((data ^ bg_pattern) & mask & ~bits); } -static void bgimgblock(fb_data *address, unsigned mask, unsigned bits) - ICODE_ATTR; -static void bgimgblock(fb_data *address, unsigned mask, unsigned bits) +static void ICODE_ATTR bgimgblock(fb_data *address, unsigned mask, + unsigned bits) { unsigned data = *address; *address = data ^ ((data ^ *(address + lcd_backdrop_offset)) & mask & ~bits); } -static void fgblock(fb_data *address, unsigned mask, unsigned bits) - ICODE_ATTR; -static void fgblock(fb_data *address, unsigned mask, unsigned bits) +static void ICODE_ATTR fgblock(fb_data *address, unsigned mask, + unsigned bits) { unsigned data = *address; *address = data ^ ((data ^ fg_pattern) & mask & bits); } -static void solidblock(fb_data *address, unsigned mask, unsigned bits) - ICODE_ATTR; -static void solidblock(fb_data *address, unsigned mask, unsigned bits) +static void ICODE_ATTR solidblock(fb_data *address, unsigned mask, + unsigned bits) { unsigned data = *address; unsigned bgp = bg_pattern; @@ -287,9 +282,8 @@ static void solidblock(fb_data *address, unsigned mask, unsigned bits) *address = data ^ ((data ^ bits) & mask); } -static void solidimgblock(fb_data *address, unsigned mask, unsigned bits) - ICODE_ATTR; -static void solidimgblock(fb_data *address, unsigned mask, unsigned bits) +static void ICODE_ATTR solidimgblock(fb_data *address, unsigned mask, + unsigned bits) { unsigned data = *address; unsigned bgp = *(address + lcd_backdrop_offset); @@ -298,43 +292,38 @@ static void solidimgblock(fb_data *address, unsigned mask, unsigned bits) *address = data ^ ((data ^ bits) & mask); } -static void flipinvblock(fb_data *address, unsigned mask, unsigned bits) - ICODE_ATTR; -static void flipinvblock(fb_data *address, unsigned mask, unsigned bits) +static void ICODE_ATTR flipinvblock(fb_data *address, unsigned mask, + unsigned bits) { *address ^= ~bits & mask; } -static void bginvblock(fb_data *address, unsigned mask, unsigned bits) - ICODE_ATTR; -static void bginvblock(fb_data *address, unsigned mask, unsigned bits) +static void ICODE_ATTR bginvblock(fb_data *address, unsigned mask, + unsigned bits) { unsigned data = *address; *address = data ^ ((data ^ bg_pattern) & mask & bits); } -static void bgimginvblock(fb_data *address, unsigned mask, unsigned bits) - ICODE_ATTR; -static void bgimginvblock(fb_data *address, unsigned mask, unsigned bits) +static void ICODE_ATTR bgimginvblock(fb_data *address, unsigned mask, + unsigned bits) { unsigned data = *address; *address = data ^ ((data ^ *(address + lcd_backdrop_offset)) & mask & bits); } -static void fginvblock(fb_data *address, unsigned mask, unsigned bits) - ICODE_ATTR; -static void fginvblock(fb_data *address, unsigned mask, unsigned bits) +static void ICODE_ATTR fginvblock(fb_data *address, unsigned mask, + unsigned bits) { unsigned data = *address; *address = data ^ ((data ^ fg_pattern) & mask & ~bits); } -static void solidinvblock(fb_data *address, unsigned mask, unsigned bits) - ICODE_ATTR; -static void solidinvblock(fb_data *address, unsigned mask, unsigned bits) +static void ICODE_ATTR solidinvblock(fb_data *address, unsigned mask, + unsigned bits) { unsigned data = *address; unsigned fgp = fg_pattern; @@ -343,9 +332,8 @@ static void solidinvblock(fb_data *address, unsigned mask, unsigned bits) *address = data ^ ((data ^ bits) & mask); } -static void solidimginvblock(fb_data *address, unsigned mask, unsigned bits) - ICODE_ATTR; -static void solidimginvblock(fb_data *address, unsigned mask, unsigned bits) +static void ICODE_ATTR solidimginvblock(fb_data *address, unsigned mask, + unsigned bits) { unsigned data = *address; unsigned fgp = fg_pattern; @@ -463,7 +451,19 @@ void lcd_drawline(int x1, int y1, int x2, int y2) lcd_pixelfunc_type *pfunc = lcd_pixelfuncs[current_vp->drawmode]; deltax = abs(x2 - x1); + if (deltax == 0) + { + DEBUGF("lcd_drawline() called for vertical line - optimisation.\n"); + lcd_vline(x1, y1, y2); + return; + } deltay = abs(y2 - y1); + if (deltay == 0) + { + DEBUGF("lcd_drawline() called for horizontal line - optimisation.\n"); + lcd_hline(x1, x2, y1); + return; + } xinc2 = 1; yinc2 = 1; @@ -729,11 +729,9 @@ void lcd_fillrect(int x, int y, int width, int height) * This is similar to the internal lcd hw format. */ /* Draw a partial monochrome bitmap */ -void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, - int stride, int x, int y, int width, int height) - ICODE_ATTR; -void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, - int stride, int x, int y, int width, int height) +void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x, + int src_y, int stride, int x, int y, + int width, int height) { int shift, ny; fb_data *dst, *dst_end; @@ -901,11 +899,9 @@ void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width, int heig * This is the same as the internal lcd hw format. */ /* Draw a partial native bitmap */ -void lcd_bitmap_part(const fb_data *src, int src_x, int src_y, - int stride, int x, int y, int width, int height) - ICODE_ATTR; -void lcd_bitmap_part(const fb_data *src, int src_x, int src_y, - int stride, int x, int y, int width, int height) +void ICODE_ATTR lcd_bitmap_part(const fb_data *src, int src_x, int src_y, + int stride, int x, int y, int width, + int height) { int shift, ny; fb_data *dst, *dst_end; diff --git a/firmware/drivers/lcd-2bit-vi.c b/firmware/drivers/lcd-2bit-vi.c index 0878258e84..7d97f19174 100644 --- a/firmware/drivers/lcd-2bit-vi.c +++ b/firmware/drivers/lcd-2bit-vi.c @@ -39,6 +39,7 @@ #define LCDFN(fn) lcd_ ## fn #define FBFN(fn) fb_ ## fn #define LCDM(ma) LCD_ ## ma +#define LCDNAME "lcd_" #define MAIN_LCD #endif @@ -476,7 +477,19 @@ void LCDFN(drawline)(int x1, int y1, int x2, int y2) LCDFN(pixelfunc_type) *pfunc = LCDFN(pixelfuncs)[current_vp->drawmode]; deltax = abs(x2 - x1); + if (deltax == 0) + { + DEBUGF(LCDNAME "drawline() called for vertical line - optimisation.\n"); + LCDFN(vline)(x1, y1, y2); + return; + } deltay = abs(y2 - y1); + if (deltay == 0) + { + DEBUGF(LCDNAME "drawline() called for horizontal line - optimisation.\n"); + LCDFN(hline)(x1, x2, y1); + return; + } xinc2 = 1; yinc2 = 1; diff --git a/firmware/drivers/lcd-remote-1bit-v.c b/firmware/drivers/lcd-remote-1bit-v.c index bed7cc6671..8e6898a8a2 100644 --- a/firmware/drivers/lcd-remote-1bit-v.c +++ b/firmware/drivers/lcd-remote-1bit-v.c @@ -23,5 +23,6 @@ #define LCDFN(fn) lcd_remote_ ## fn #define FBFN(fn) fb_remote_ ## fn #define LCDM(ma) LCD_REMOTE_ ## ma +#define LCDNAME "lcd_remote_" #include "lcd-1bit-vert.c" diff --git a/firmware/drivers/lcd-remote-2bit-vi.c b/firmware/drivers/lcd-remote-2bit-vi.c index d2440a6296..d050143468 100644 --- a/firmware/drivers/lcd-remote-2bit-vi.c +++ b/firmware/drivers/lcd-remote-2bit-vi.c @@ -25,5 +25,6 @@ #define LCDFN(fn) lcd_remote_ ## fn #define FBFN(fn) fb_remote_ ## fn #define LCDM(ma) LCD_REMOTE_ ## ma +#define LCDNAME "lcd_remote_" #include "lcd-2bit-vi.c" -- cgit v1.2.3