From 6a56c14e17f6ba113ec0d4d40e75bffd61b293cc Mon Sep 17 00:00:00 2001 From: Jens Arnold Date: Wed, 9 Jan 2008 23:48:26 +0000 Subject: Greyscale library: Changed the internal data format once more (separated pixel values and phases), allowing for further optimisation of drawing, scrolling etc. * Optimised grey phase blitting in the core reduces CPU load on all architectures, most significantly on coldfire. Previous version was too slow to keep up at 45MHz, leading to unwanted graininess (update frequency was halved). Also fixed screendump on 2bpp targets with vertical pixel packing. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16043 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/arm/ipod/lcd-gray.c | 134 ++++++++++++++---------------------- 1 file changed, 52 insertions(+), 82 deletions(-) (limited to 'firmware/target/arm/ipod/lcd-gray.c') diff --git a/firmware/target/arm/ipod/lcd-gray.c b/firmware/target/arm/ipod/lcd-gray.c index c7f4074c0b..5734480bee 100644 --- a/firmware/target/arm/ipod/lcd-gray.c +++ b/firmware/target/arm/ipod/lcd-gray.c @@ -301,118 +301,88 @@ void lcd_blit(const unsigned char* data, int bx, int y, int bwidth, /* Performance function that works with an external buffer note that bx and bwidth are in 8-pixel units! */ -void lcd_grey_phase_blit(const struct grey_data *data, int bx, int y, - int bwidth, int height, int stride) +void lcd_grey_phase_blit(unsigned char *values, unsigned char *phases, + int bx, int y, int bwidth, int height, int stride) { - const struct grey_data *addr; - int width; - + unsigned char *val, *ph; + int bw; + while (height--) { lcd_cmd_and_data(R_RAM_ADDR_SET, (y++ << 5) + addr_offset - bx); lcd_prepare_cmd(R_RAM_DATA); - addr = data; - width = bwidth; + val = values; + ph = phases; + bw = bwidth; asm volatile ( "10: \n" - "ldmia %[addr]!, {r0-r3} \n" /* r0 = v1p1v0p0 ... */ + "ldmia %[ph], {r0-r1} \n" /* Fetch 8 pixel phases */ + "ldmia %[val]!, {r2-r3} \n" /* Fetch 8 pixel values */ #ifdef IPOD_MINI2G - "mov r5, #0x7600 \n" + "mov r4, #0x7600 \n" #else - "mov r5, #0 \n" + "mov r4, #0 \n" #endif - - "and r4, r0, %[mask] \n" /* r4 = --p1--p0 */ - "and r0, %[mask], r0, lsr #8 \n" /* r0 = --v1--v0 */ - - "tst r4, #0x80 \n" - "orreq r5, r5, #0xc0 \n" - "tst r4, #0x800000 \n" - "orreq r5, r5, #0x30 \n" - "bic r4, r4, %[clbt] \n" - - "add r4, r0, r4 \n" /* p0 += v0; p1 += v1; */ - "strb r4, [%[addr], #-16] \n" - "mov r4, r4, lsr #16 \n" - "strb r4, [%[addr], #-14] \n" - - "and r4, r1, %[mask] \n" - "and r1, %[mask], r1, lsr #8 \n" - - "tst r4, #0x80 \n" - "orreq r5, r5, #0x0c \n" - "tst r4, #0x800000 \n" - "orreq r5, r5, #0x03 \n" - "bic r4, r4, %[clbt] \n" - - "add r4, r1, r4 \n" - "strb r4, [%[addr], #-12] \n" - "mov r4, r4, lsr #16 \n" - "strb r4, [%[addr], #-10] \n" + "tst r0, #0x80 \n" + "orreq r4, r4, #0xc0 \n" + "tst r0, #0x8000 \n" + "orreq r4, r4, #0x30 \n" + "tst r0, #0x800000 \n" + "orreq r4, r4, #0x0c \n" + "tst r0, #0x80000000 \n" + "orreq r4, r4, #0x03 \n" + "bic r0, r0, %[clbt] \n" + "add r0, r0, r2 \n" #ifdef IPOD_MINI2G - "mov r5, r5, lsl #8 \n" + "mov r4, r4, lsl #8 \n" #else "1: \n" - "ldr r4, [%[lcdb]] \n" - "tst r4, #0x8000 \n" + "ldr r2, [%[lcdb]] \n" + "tst r2, #0x8000 \n" "bne 1b \n" - "str r5, [%[lcdb], #0x10] \n" - "mov r5, #0 \n" + "str r4, [%[lcdb], #0x10] \n" + "mov r4, #0 \n" #endif - "and r4, r2, %[mask] \n" - "and r2, %[mask], r2, lsr #8 \n" - - "tst r4, #0x80 \n" - "orreq r5, r5, #0xc0 \n" - "tst r4, #0x800000 \n" - "orreq r5, r5, #0x30 \n" - "bic r4, r4, %[clbt] \n" - - "add r4, r2, r4 \n" - "strb r4, [%[addr], #-8] \n" - "mov r4, r4, lsr #16 \n" - "strb r4, [%[addr], #-6] \n" - - "and r4, r3, %[mask] \n" - "and r3, %[mask], r3, lsr #8 \n" - - "tst r4, #0x80 \n" - "orreq r5, r5, #0x0c \n" - "tst r4, #0x800000 \n" - "orreq r5, r5, #0x03 \n" - "bic r4, r4, %[clbt] \n" - - "add r4, r3, r4 \n" - "strb r4, [%[addr], #-4] \n" - "mov r4, r4, lsr #16 \n" - "strb r4, [%[addr], #-2] \n" - + "tst r1, #0x80 \n" + "orreq r4, r4, #0xc0 \n" + "tst r1, #0x8000 \n" + "orreq r4, r4, #0x30 \n" + "tst r1, #0x800000 \n" + "orreq r4, r4, #0x0c \n" + "tst r1, #0x80000000 \n" + "orreq r4, r4, #0x03 \n" + "bic r1, r1, %[clbt] \n" + "add r1, r1, r3 \n" + + "stmia %[ph]!, {r0-r1} \n" + "1: \n" - "ldr r4, [%[lcdb]] \n" - "tst r4, #0x8000 \n" + "ldr r2, [%[lcdb]] \n" + "tst r2, #0x8000 \n" "bne 1b \n" #ifdef IPOD_MINI2G - "str r5, [%[lcdb], #0x08] \n" + "str r4, [%[lcdb], #0x08] \n" #else - "str r5, [%[lcdb], #0x10] \n" + "str r4, [%[lcdb], #0x10] \n" #endif - "subs %[wdth], %[wdth], #1 \n" + "subs %[bw], %[bw], #1 \n" "bne 10b \n" : /* outputs */ - [addr]"+r"(addr), - [wdth]"+r"(width) + [val]"+r"(val), + [ph] "+r"(ph), + [bw] "+r"(bw) : /* inputs */ - [mask]"r"(0x00ff00ff), - [clbt]"r"(0x00800080), + [clbt]"r"(0x80808080), [lcdb]"r"(LCD1_BASE) : /* clobbers */ - "r0", "r1", "r2", "r3", "r4", "r5" + "r0", "r1", "r2", "r3", "r4" ); - data += stride; + values += stride; + phases += stride; } } -- cgit v1.2.3