diff options
author | Jens Arnold <amiconn@rockbox.org> | 2008-01-09 23:48:26 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2008-01-09 23:48:26 +0000 |
commit | 6a56c14e17f6ba113ec0d4d40e75bffd61b293cc (patch) | |
tree | 64bcdd8d5d4afa2ca6dd1aa0976cdafa9a346b26 /firmware/target/arm/ipod/lcd-gray.c | |
parent | 75380fd27d175bab1818ef35a9100e74fc6a461b (diff) | |
download | rockbox-6a56c14e17f6ba113ec0d4d40e75bffd61b293cc.tar.gz rockbox-6a56c14e17f6ba113ec0d4d40e75bffd61b293cc.zip |
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
Diffstat (limited to 'firmware/target/arm/ipod/lcd-gray.c')
-rw-r--r-- | firmware/target/arm/ipod/lcd-gray.c | 134 |
1 files changed, 52 insertions, 82 deletions
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, | |||
301 | 301 | ||
302 | /* Performance function that works with an external buffer | 302 | /* Performance function that works with an external buffer |
303 | note that bx and bwidth are in 8-pixel units! */ | 303 | note that bx and bwidth are in 8-pixel units! */ |
304 | void lcd_grey_phase_blit(const struct grey_data *data, int bx, int y, | 304 | void lcd_grey_phase_blit(unsigned char *values, unsigned char *phases, |
305 | int bwidth, int height, int stride) | 305 | int bx, int y, int bwidth, int height, int stride) |
306 | { | 306 | { |
307 | const struct grey_data *addr; | 307 | unsigned char *val, *ph; |
308 | int width; | 308 | int bw; |
309 | 309 | ||
310 | while (height--) { | 310 | while (height--) { |
311 | lcd_cmd_and_data(R_RAM_ADDR_SET, (y++ << 5) + addr_offset - bx); | 311 | lcd_cmd_and_data(R_RAM_ADDR_SET, (y++ << 5) + addr_offset - bx); |
312 | lcd_prepare_cmd(R_RAM_DATA); | 312 | lcd_prepare_cmd(R_RAM_DATA); |
313 | 313 | ||
314 | addr = data; | 314 | val = values; |
315 | width = bwidth; | 315 | ph = phases; |
316 | bw = bwidth; | ||
316 | asm volatile ( | 317 | asm volatile ( |
317 | "10: \n" | 318 | "10: \n" |
318 | "ldmia %[addr]!, {r0-r3} \n" /* r0 = v1p1v0p0 ... */ | 319 | "ldmia %[ph], {r0-r1} \n" /* Fetch 8 pixel phases */ |
320 | "ldmia %[val]!, {r2-r3} \n" /* Fetch 8 pixel values */ | ||
319 | #ifdef IPOD_MINI2G | 321 | #ifdef IPOD_MINI2G |
320 | "mov r5, #0x7600 \n" | 322 | "mov r4, #0x7600 \n" |
321 | #else | 323 | #else |
322 | "mov r5, #0 \n" | 324 | "mov r4, #0 \n" |
323 | #endif | 325 | #endif |
324 | 326 | "tst r0, #0x80 \n" | |
325 | "and r4, r0, %[mask] \n" /* r4 = --p1--p0 */ | 327 | "orreq r4, r4, #0xc0 \n" |
326 | "and r0, %[mask], r0, lsr #8 \n" /* r0 = --v1--v0 */ | 328 | "tst r0, #0x8000 \n" |
327 | 329 | "orreq r4, r4, #0x30 \n" | |
328 | "tst r4, #0x80 \n" | 330 | "tst r0, #0x800000 \n" |
329 | "orreq r5, r5, #0xc0 \n" | 331 | "orreq r4, r4, #0x0c \n" |
330 | "tst r4, #0x800000 \n" | 332 | "tst r0, #0x80000000 \n" |
331 | "orreq r5, r5, #0x30 \n" | 333 | "orreq r4, r4, #0x03 \n" |
332 | "bic r4, r4, %[clbt] \n" | 334 | "bic r0, r0, %[clbt] \n" |
333 | 335 | "add r0, r0, r2 \n" | |
334 | "add r4, r0, r4 \n" /* p0 += v0; p1 += v1; */ | ||
335 | "strb r4, [%[addr], #-16] \n" | ||
336 | "mov r4, r4, lsr #16 \n" | ||
337 | "strb r4, [%[addr], #-14] \n" | ||
338 | |||
339 | "and r4, r1, %[mask] \n" | ||
340 | "and r1, %[mask], r1, lsr #8 \n" | ||
341 | |||
342 | "tst r4, #0x80 \n" | ||
343 | "orreq r5, r5, #0x0c \n" | ||
344 | "tst r4, #0x800000 \n" | ||
345 | "orreq r5, r5, #0x03 \n" | ||
346 | "bic r4, r4, %[clbt] \n" | ||
347 | |||
348 | "add r4, r1, r4 \n" | ||
349 | "strb r4, [%[addr], #-12] \n" | ||
350 | "mov r4, r4, lsr #16 \n" | ||
351 | "strb r4, [%[addr], #-10] \n" | ||
352 | 336 | ||
353 | #ifdef IPOD_MINI2G | 337 | #ifdef IPOD_MINI2G |
354 | "mov r5, r5, lsl #8 \n" | 338 | "mov r4, r4, lsl #8 \n" |
355 | #else | 339 | #else |
356 | "1: \n" | 340 | "1: \n" |
357 | "ldr r4, [%[lcdb]] \n" | 341 | "ldr r2, [%[lcdb]] \n" |
358 | "tst r4, #0x8000 \n" | 342 | "tst r2, #0x8000 \n" |
359 | "bne 1b \n" | 343 | "bne 1b \n" |
360 | 344 | ||
361 | "str r5, [%[lcdb], #0x10] \n" | 345 | "str r4, [%[lcdb], #0x10] \n" |
362 | "mov r5, #0 \n" | 346 | "mov r4, #0 \n" |
363 | #endif | 347 | #endif |
364 | 348 | ||
365 | "and r4, r2, %[mask] \n" | 349 | "tst r1, #0x80 \n" |
366 | "and r2, %[mask], r2, lsr #8 \n" | 350 | "orreq r4, r4, #0xc0 \n" |
367 | 351 | "tst r1, #0x8000 \n" | |
368 | "tst r4, #0x80 \n" | 352 | "orreq r4, r4, #0x30 \n" |
369 | "orreq r5, r5, #0xc0 \n" | 353 | "tst r1, #0x800000 \n" |
370 | "tst r4, #0x800000 \n" | 354 | "orreq r4, r4, #0x0c \n" |
371 | "orreq r5, r5, #0x30 \n" | 355 | "tst r1, #0x80000000 \n" |
372 | "bic r4, r4, %[clbt] \n" | 356 | "orreq r4, r4, #0x03 \n" |
373 | 357 | "bic r1, r1, %[clbt] \n" | |
374 | "add r4, r2, r4 \n" | 358 | "add r1, r1, r3 \n" |
375 | "strb r4, [%[addr], #-8] \n" | 359 | |
376 | "mov r4, r4, lsr #16 \n" | 360 | "stmia %[ph]!, {r0-r1} \n" |
377 | "strb r4, [%[addr], #-6] \n" | 361 | |
378 | |||
379 | "and r4, r3, %[mask] \n" | ||
380 | "and r3, %[mask], r3, lsr #8 \n" | ||
381 | |||
382 | "tst r4, #0x80 \n" | ||
383 | "orreq r5, r5, #0x0c \n" | ||
384 | "tst r4, #0x800000 \n" | ||
385 | "orreq r5, r5, #0x03 \n" | ||
386 | "bic r4, r4, %[clbt] \n" | ||
387 | |||
388 | "add r4, r3, r4 \n" | ||
389 | "strb r4, [%[addr], #-4] \n" | ||
390 | "mov r4, r4, lsr #16 \n" | ||
391 | "strb r4, [%[addr], #-2] \n" | ||
392 | |||
393 | "1: \n" | 362 | "1: \n" |
394 | "ldr r4, [%[lcdb]] \n" | 363 | "ldr r2, [%[lcdb]] \n" |
395 | "tst r4, #0x8000 \n" | 364 | "tst r2, #0x8000 \n" |
396 | "bne 1b \n" | 365 | "bne 1b \n" |
397 | #ifdef IPOD_MINI2G | 366 | #ifdef IPOD_MINI2G |
398 | "str r5, [%[lcdb], #0x08] \n" | 367 | "str r4, [%[lcdb], #0x08] \n" |
399 | #else | 368 | #else |
400 | "str r5, [%[lcdb], #0x10] \n" | 369 | "str r4, [%[lcdb], #0x10] \n" |
401 | #endif | 370 | #endif |
402 | 371 | ||
403 | "subs %[wdth], %[wdth], #1 \n" | 372 | "subs %[bw], %[bw], #1 \n" |
404 | "bne 10b \n" | 373 | "bne 10b \n" |
405 | : /* outputs */ | 374 | : /* outputs */ |
406 | [addr]"+r"(addr), | 375 | [val]"+r"(val), |
407 | [wdth]"+r"(width) | 376 | [ph] "+r"(ph), |
377 | [bw] "+r"(bw) | ||
408 | : /* inputs */ | 378 | : /* inputs */ |
409 | [mask]"r"(0x00ff00ff), | 379 | [clbt]"r"(0x80808080), |
410 | [clbt]"r"(0x00800080), | ||
411 | [lcdb]"r"(LCD1_BASE) | 380 | [lcdb]"r"(LCD1_BASE) |
412 | : /* clobbers */ | 381 | : /* clobbers */ |
413 | "r0", "r1", "r2", "r3", "r4", "r5" | 382 | "r0", "r1", "r2", "r3", "r4" |
414 | ); | 383 | ); |
415 | data += stride; | 384 | values += stride; |
385 | phases += stride; | ||
416 | } | 386 | } |
417 | } | 387 | } |
418 | 388 | ||