diff options
| author | Jens Arnold <amiconn@rockbox.org> | 2008-03-25 23:21:36 +0000 |
|---|---|---|
| committer | Jens Arnold <amiconn@rockbox.org> | 2008-03-25 23:21:36 +0000 |
| commit | 40919d7db29d036033f57fe6fbf9e3f562e61c0d (patch) | |
| tree | b04fa272f6cee51639b7307ee5fcd9b4f9737fde /apps/plugins/lib | |
| parent | 6ceaf321f3aadc804b1daa8fb10607a7ae209351 (diff) | |
| download | rockbox-40919d7db29d036033f57fe6fbf9e3f562e61c0d.zip rockbox-40919d7db29d036033f57fe6fbf9e3f562e61c0d.tar.gz rockbox-40919d7db29d036033f57fe6fbf9e3f562e61c0d.tar.bz2 rockbox-40919d7db29d036033f57fe6fbf9e3f562e61c0d.tar.xz | |
iAudio M3: Optimised LCD driver, with more/better assembly code. Speedup is ~80% when boosted, ~15% when unboosted. Also implemented grey phase blitting. * Adapted the greyscale library, and the plugins using it. * Fixed a bug in greyscale scroll down for vertically packed pixels.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16809 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/lib')
| -rw-r--r-- | apps/plugins/lib/SOURCES | 3 | ||||
| -rw-r--r-- | apps/plugins/lib/grey.h | 6 | ||||
| -rw-r--r-- | apps/plugins/lib/grey_coldfire.S | 27 | ||||
| -rw-r--r-- | apps/plugins/lib/grey_core.c | 87 | ||||
| -rw-r--r-- | apps/plugins/lib/grey_draw.c | 8 | ||||
| -rw-r--r-- | apps/plugins/lib/grey_parm.c | 4 | ||||
| -rw-r--r-- | apps/plugins/lib/grey_scroll.c | 11 |
7 files changed, 113 insertions, 33 deletions
diff --git a/apps/plugins/lib/SOURCES b/apps/plugins/lib/SOURCES index f1aded6..6a44c80 100644 --- a/apps/plugins/lib/SOURCES +++ b/apps/plugins/lib/SOURCES @@ -3,8 +3,7 @@ configfile.c fixedpoint.c playback_control.c rgb_hsv.c -#if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH < 4) \ - && !defined(IAUDIO_M3) /* TODO: Test whether it can be implemented */ +#if defined(HAVE_LCD_BITMAP) && (LCD_DEPTH < 4) grey_core.c grey_draw.c grey_parm.c diff --git a/apps/plugins/lib/grey.h b/apps/plugins/lib/grey.h index ce37e17..4298ae3 100644 --- a/apps/plugins/lib/grey.h +++ b/apps/plugins/lib/grey.h @@ -134,8 +134,8 @@ void grey_ub_scroll_down(int count); #if LCD_PIXELFORMAT == HORIZONTAL_PACKING #define _GREY_BSHIFT 0 -#else -#if LCD_DEPTH == 1 +#else /* vertical packing or vertical interleaved */ +#if (LCD_DEPTH == 1) || (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED) #define _GREY_BSHIFT 3 #elif LCD_DEPTH == 2 #define _GREY_BSHIFT 2 @@ -155,7 +155,7 @@ struct _grey_info #if LCD_PIXELFORMAT == HORIZONTAL_PACKING int bx; /* 8-pixel units */ int bwidth; /* 8-pixel units */ -#else /* vertical packing */ +#else /* vertical packing or vertical interleaved */ int by; /* 4-pixel or 8-pixel units */ int bheight; /* 4-pixel or 8-pixel units */ #endif diff --git a/apps/plugins/lib/grey_coldfire.S b/apps/plugins/lib/grey_coldfire.S index 39df087..a040193 100644 --- a/apps/plugins/lib/grey_coldfire.S +++ b/apps/plugins/lib/grey_coldfire.S @@ -31,7 +31,14 @@ .global _grey_line1 .type _grey_line1, @function -#if (LCD_PIXELFORMAT == VERTICAL_PACKING) && (LCD_DEPTH == 2) +#if (LCD_PIXELFORMAT == VERTICAL_PACKING) \ + || (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED) + +#if (LCD_DEPTH == 1) || (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED) +#define GREY_BSIZE 8 +#elif LCD_DEPTH == 2 +#define GREY_BSIZE 4 +#endif /**************************************************************************** * void _grey_line1(int width, @@ -52,7 +59,7 @@ _grey_line1: move.b (%a1)+, %d0 move.b (%d0.l, %a2), (%a0) - addq.l #4, %a0 + addq.l #GREY_BSIZE, %a0 subq.l #1, %d2 .p1_h_end: @@ -66,10 +73,10 @@ _grey_line1: move.w %d1, %d0 lsr.l #8, %d0 move.b (%d0.l, %a2), (%a0) - addq.l #4, %a0 + addq.l #GREY_BSIZE, %a0 move.b %d1, %d0 move.b (%d0.l, %a2), (%a0) - addq.l #4, %a0 + addq.l #GREY_BSIZE, %a0 subq.l #2, %d2 .p2_h_end: @@ -82,18 +89,18 @@ _grey_line1: move.w %d1, %d0 lsr.l #8, %d0 move.b (%d0.l, %a2), (%a0) - addq.l #4, %a0 + addq.l #GREY_BSIZE, %a0 move.b %d1, %d0 move.b (%d0.l, %a2), (%a0) - addq.l #4, %a0 + addq.l #GREY_BSIZE, %a0 swap %d1 move.w %d1, %d0 lsr.l #8, %d0 move.b (%d0.l, %a2), (%a0) - addq.l #4, %a0 + addq.l #GREY_BSIZE, %a0 move.b %d1, %d0 move.b (%d0.l, %a2), (%a0) - addq.l #4, %a0 + addq.l #GREY_BSIZE, %a0 subq.l #4, %d2 bhs.s .p4_loop @@ -107,10 +114,10 @@ _grey_line1: move.w %d1, %d0 lsr.l #8, %d0 move.b (%d0.l, %a2), (%a0) - addq.l #4, %a0 + addq.l #GREY_BSIZE, %a0 move.b %d1, %d0 move.b (%d0.l, %a2), (%a0) - addq.l #4, %a0 + addq.l #GREY_BSIZE, %a0 .p2_t_end: btst.l #0, %d2 diff --git a/apps/plugins/lib/grey_core.c b/apps/plugins/lib/grey_core.c index caa7af2..8a30faa 100644 --- a/apps/plugins/lib/grey_core.c +++ b/apps/plugins/lib/grey_core.c @@ -26,7 +26,8 @@ #include "plugin.h" #include "grey.h" -#if defined(CPU_PP) && defined(HAVE_ADJUSTABLE_CPU_FREQ) +#if defined(HAVE_ADJUSTABLE_CPU_FREQ) && \ + (defined(CPU_PP) || (CONFIG_LCD == LCD_TL0350A)) #define NEED_BOOST #endif @@ -143,6 +144,42 @@ static const unsigned char lcdlinear[256] = { 203, 206, 209, 212, 215, 219, 222, 226, 229, 233, 236, 240, 244, 248, 251, 255 }; +#elif CONFIG_LCD == LCD_TL0350A +/* measured and interpolated curve for iaudio remote */ +static const unsigned char lcdlinear[256] = { + 5, 9, 13, 17, 21, 25, 29, 33, + 36, 39, 42, 45, 48, 51, 54, 57, + 60, 62, 65, 67, 70, 72, 75, 77, + 80, 82, 84, 86, 87, 89, 91, 93, + 94, 95, 96, 97, 97, 98, 99, 99, + 100, 100, 101, 102, 103, 103, 104, 105, + 106, 106, 107, 108, 108, 109, 110, 111, + 112, 112, 113, 113, 114, 114, 115, 115, + 116, 116, 117, 117, 118, 118, 119, 119, + 120, 120, 121, 121, 122, 122, 123, 123, + 124, 124, 124, 125, 125, 126, 126, 126, + 127, 127, 127, 128, 128, 129, 129, 129, + 130, 130, 131, 131, 132, 132, 133, 133, + 134, 134, 135, 135, 136, 136, 137, 137, + 138, 138, 139, 139, 140, 140, 141, 141, + 142, 142, 143, 143, 144, 144, 145, 145, + 146, 146, 147, 147, 148, 149, 149, 150, + 151, 151, 152, 152, 153, 154, 154, 155, + 156, 156, 157, 157, 158, 159, 159, 160, + 161, 161, 162, 163, 164, 164, 165, 166, + 167, 167, 168, 169, 170, 170, 171, 172, + 173, 173, 174, 175, 176, 176, 177, 178, + 179, 179, 180, 181, 182, 182, 183, 184, + 185, 186, 187, 188, 188, 189, 191, 191, + 192, 193, 194, 195, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 240, 241, 242, 243, 243, 244, 245, + 246, 246, 247, 248, 249, 250, 251, 252 +}; #endif #else /* SIMULATOR */ /* undo a (generic) PC display gamma of 2.0 to simulate target behaviour */ @@ -225,7 +262,7 @@ static unsigned long _grey_get_pixel(int x, int y) int yg = y - _grey_info.y; #if LCD_PIXELFORMAT == HORIZONTAL_PACKING int idx = _grey_info.width * yg + xg; -#else +#else /* vertical packing or vertical interleaved */ int idx = _grey_info.width * (yg & ~_GREY_BMASK) + (xg << _GREY_BSHIFT) + (~yg & _GREY_BMASK); #endif @@ -243,7 +280,7 @@ static void _timer_isr(void) _grey_info.bx, _grey_info.y, _grey_info.bwidth, _grey_info.height, _grey_info.width); -#else +#else /* vertical packing or vertical interleaved */ _grey_info.rb->lcd_blit_grey_phase(_grey_info.values, _grey_info.phases, _grey_info.x, _grey_info.by, _grey_info.width, _grey_info.bheight, @@ -355,8 +392,8 @@ bool grey_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, #if LCD_PIXELFORMAT == HORIZONTAL_PACKING bdim = (width + 7) >> 3; width = bdim << 3; -#else /* vertical packing */ -#if LCD_DEPTH == 1 +#else /* vertical packing or vertical interleaved */ +#if (LCD_DEPTH == 1) || (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED) bdim = (height + 7) >> 3; height = bdim << 3; #elif LCD_DEPTH == 2 @@ -408,7 +445,7 @@ bool grey_init(struct plugin_api* newrb, unsigned char *gbuf, long gbuf_size, #if LCD_PIXELFORMAT == HORIZONTAL_PACKING _grey_info.bx = 0; _grey_info.bwidth = bdim; -#else +#else /* vertical packing or vertical interleaved */ _grey_info.by = 0; _grey_info.bheight = bdim; #endif @@ -491,6 +528,9 @@ void grey_show(bool enable) _grey_info.rb->timer_register(1, NULL, TIMER_FREQ / 83, 1, _timer_isr); #elif CONFIG_LCD == LCD_MROBE100 _grey_info.rb->timer_register(1, NULL, TIMER_FREQ / 83, 1, _timer_isr); /* not calibrated/tested */ +#elif CONFIG_LCD == LCD_TL0350A + _grey_info.rb->timer_register(1, NULL, TIMER_FREQ / 75, 1, _timer_isr); /* verified */ + /* This is half of the actual frame frequency, but 150Hz is too much */ #endif /* CONFIG_LCD */ #endif /* !SIMULATOR */ _grey_info.rb->screen_dump_set_hook(grey_screendump_hook); @@ -607,8 +647,11 @@ static void grey_screendump_hook(int fd) #elif LCD_DEPTH == 2 int shift; #endif -#endif /* LCD_PIXELFORMAT == VERTICAL_PACKING */ - unsigned char *lcdptr; +#elif LCD_PIXELFORMAT == VERTICAL_INTERLEAVED + unsigned data; + int shift; +#endif /* LCD_PIXELFORMAT */ + fb_data *lcdptr; unsigned char *clut_entry; unsigned char linebuf[MAX(4*BMP_VARCOLORS,BMP_LINESIZE)]; @@ -660,7 +703,7 @@ static void grey_screendump_hook(int fd) lcdptr++; } #endif /* LCD_DEPTH */ -#else /* LCD_PIXELFORMAT == VERTICAL_PACKING */ +#elif LCD_PIXELFORMAT == VERTICAL_PACKING #if LCD_DEPTH == 1 mask = 1 << (y & 7); lcdptr = _grey_info.rb->lcd_framebuffer + _GREY_MULUQ(LCD_WIDTH, y >> 3); @@ -708,6 +751,32 @@ static void grey_screendump_hook(int fd) lcdptr++; } #endif /* LCD_DEPTH */ +#elif LCD_PIXELFORMAT == VERTICAL_INTERLEAVED +#if LCD_DEPTH == 2 + shift = y & 7; + lcdptr = _grey_info.rb->lcd_framebuffer + _GREY_MULUQ(LCD_WIDTH, y >> 3); + + for (x = 0; x < LCD_WIDTH; x++) + { + gx = x - _grey_info.x; + + if (((unsigned)gy < (unsigned)_grey_info.height) + && ((unsigned)gx < (unsigned)_grey_info.width)) + { + linebuf[x] = BMP_FIXEDCOLORS + + _grey_info.values[_GREY_MULUQ(_grey_info.width, + gy & ~_GREY_BMASK) + + (gx << _GREY_BSHIFT) + + (~gy & _GREY_BMASK)]; + } + else + { + data = (*lcdptr >> shift) & 0x0101; + linebuf[x] = ((data >> 7) | data) & 3; + } + lcdptr++; + } +#endif /* LCD_DEPTH */ #endif /* LCD_PIXELFORMAT */ _grey_info.rb->write(fd, linebuf, BMP_LINESIZE); diff --git a/apps/plugins/lib/grey_draw.c b/apps/plugins/lib/grey_draw.c index 7b24ba4..6c25083 100644 --- a/apps/plugins/lib/grey_draw.c +++ b/apps/plugins/lib/grey_draw.c @@ -630,14 +630,14 @@ void grey_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y, { #if LCD_PIXELFORMAT == HORIZONTAL_PACKING int idx = _GREY_MULUQ(_grey_info.width, yc); -#else +#else /* vertical packing or vertical interleaved */ int idx = _GREY_MULUQ(_grey_info.width, yc & ~_GREY_BMASK) + (~yc & _GREY_BMASK); #endif /* LCD_PIXELFORMAT */ -#if (LCD_PIXELFORMAT == VERTICAL_PACKING) && \ - ((LCD_DEPTH == 2) && defined(CPU_COLDFIRE) \ - || (LCD_DEPTH == 1) && (CONFIG_CPU == SH7034)) +#if ((LCD_PIXELFORMAT == VERTICAL_PACKING) && (LCD_DEPTH == 1) && (CONFIG_CPU == SH7034)) \ + || ((LCD_PIXELFORMAT == VERTICAL_PACKING) && (LCD_DEPTH == 2) && defined(CPU_COLDFIRE)) \ + || ((LCD_PIXELFORMAT == VERTICAL_INTERLEAVED) && defined(CPU_COLDFIRE)) _grey_line1(width, dst + idx, src, _grey_info.gvalue); #else unsigned char *dst_row = dst + idx; diff --git a/apps/plugins/lib/grey_parm.c b/apps/plugins/lib/grey_parm.c index 63d09df..e4aaec3 100644 --- a/apps/plugins/lib/grey_parm.c +++ b/apps/plugins/lib/grey_parm.c @@ -34,8 +34,8 @@ void grey_set_position(int x, int y) #if LCD_PIXELFORMAT == HORIZONTAL_PACKING _grey_info.bx = (x + 4) >> 3; x = 8 * _grey_info.bx; -#else -#if LCD_DEPTH == 1 +#else /* vertical packing or vertical interleaved */ +#if (LCD_DEPTH == 1) || (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED) _grey_info.by = (y + 4) >> 3; y = 8 * _grey_info.by; #elif LCD_DEPTH == 2 diff --git a/apps/plugins/lib/grey_scroll.c b/apps/plugins/lib/grey_scroll.c index 12a27da..56021d1 100644 --- a/apps/plugins/lib/grey_scroll.c +++ b/apps/plugins/lib/grey_scroll.c @@ -191,7 +191,8 @@ void grey_ub_scroll_up(int count) _grey_info.fg_brightness : _grey_info.bg_brightness]; -#if LCD_PIXELFORMAT == VERTICAL_PACKING +#if (LCD_PIXELFORMAT == VERTICAL_PACKING) \ + || (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED) if (count & _GREY_BMASK) { /* Scrolling by fractional blocks - move pixel wise. */ @@ -262,7 +263,8 @@ void grey_ub_scroll_down(int count) _grey_info.fg_brightness : _grey_info.bg_brightness]; -#if LCD_PIXELFORMAT == VERTICAL_PACKING +#if (LCD_PIXELFORMAT == VERTICAL_PACKING) \ + || (LCD_PIXELFORMAT == VERTICAL_INTERLEAVED) if (count & _GREY_BMASK) { /* Scrolling by fractional blocks - move pixel wise. */ @@ -302,6 +304,9 @@ void grey_ub_scroll_down(int count) } while (dst < line_end); } + /* Top pixel in a block has the highest address, but dst must point + * to the lowest address in that block for the subsequent fill. */ + dst -= _GREY_BMASK; } else #endif @@ -311,7 +316,7 @@ void grey_ub_scroll_down(int count) dst -= blen; _grey_info.rb->memmove(dst, start, blen); } - _grey_info.rb->memset(start, blank, dst - start); + _grey_info.rb->memset(start, blank, dst - start); /* Fill remainder at once. */ #ifdef SIMULATOR _grey_info.rb->sim_lcd_ex_update_rect(_grey_info.x, _grey_info.y, |