summaryrefslogtreecommitdiff
path: root/apps/plugins/lib
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2008-03-25 23:21:36 +0000
committerJens Arnold <amiconn@rockbox.org>2008-03-25 23:21:36 +0000
commit40919d7db29d036033f57fe6fbf9e3f562e61c0d (patch)
treeb04fa272f6cee51639b7307ee5fcd9b4f9737fde /apps/plugins/lib
parent6ceaf321f3aadc804b1daa8fb10607a7ae209351 (diff)
downloadrockbox-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/SOURCES3
-rw-r--r--apps/plugins/lib/grey.h6
-rw-r--r--apps/plugins/lib/grey_coldfire.S27
-rw-r--r--apps/plugins/lib/grey_core.c87
-rw-r--r--apps/plugins/lib/grey_draw.c8
-rw-r--r--apps/plugins/lib/grey_parm.c4
-rw-r--r--apps/plugins/lib/grey_scroll.c11
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,