diff options
Diffstat (limited to 'firmware/target/arm/iriver/h10/lcd-h10_20gb.c')
-rw-r--r-- | firmware/target/arm/iriver/h10/lcd-h10_20gb.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/firmware/target/arm/iriver/h10/lcd-h10_20gb.c b/firmware/target/arm/iriver/h10/lcd-h10_20gb.c index 403c1c19e0..c7e339295d 100644 --- a/firmware/target/arm/iriver/h10/lcd-h10_20gb.c +++ b/firmware/target/arm/iriver/h10/lcd-h10_20gb.c | |||
@@ -36,6 +36,8 @@ static unsigned short disp_control_rev; | |||
36 | /* Contrast setting << 8 */ | 36 | /* Contrast setting << 8 */ |
37 | static int lcd_contrast; | 37 | static int lcd_contrast; |
38 | 38 | ||
39 | static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0; | ||
40 | |||
39 | /* Forward declarations */ | 41 | /* Forward declarations */ |
40 | #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) | 42 | #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) |
41 | static void lcd_display_off(void); | 43 | static void lcd_display_off(void); |
@@ -396,6 +398,94 @@ bool lcd_active(void) | |||
396 | 398 | ||
397 | /*** update functions ***/ | 399 | /*** update functions ***/ |
398 | 400 | ||
401 | void lcd_yuv_set_options(unsigned options) | ||
402 | { | ||
403 | lcd_yuv_options = options; | ||
404 | } | ||
405 | |||
406 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ | ||
407 | extern void lcd_write_yuv420_lines(unsigned char const * const src[3], | ||
408 | int width, | ||
409 | int stride); | ||
410 | extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3], | ||
411 | int width, | ||
412 | int stride, | ||
413 | int x_screen, /* To align dither pattern */ | ||
414 | int y_screen); | ||
415 | |||
416 | /* Performance function to blit a YUV bitmap directly to the LCD */ | ||
417 | void lcd_blit_yuv(unsigned char * const src[3], | ||
418 | int src_x, int src_y, int stride, | ||
419 | int x, int y, int width, int height) | ||
420 | { | ||
421 | const unsigned char *yuv_src[3]; | ||
422 | const unsigned char *ysrc_max; | ||
423 | int y0; | ||
424 | int options; | ||
425 | |||
426 | if (!display_on) | ||
427 | return; | ||
428 | |||
429 | width &= ~1; | ||
430 | height &= ~1; | ||
431 | |||
432 | /* calculate the drawing region */ | ||
433 | |||
434 | /* The 20GB LCD is actually 128x160 but rotated 90 degrees so the origin | ||
435 | * is actually the bottom left and horizontal and vertical are swapped. | ||
436 | * Rockbox expects the origin to be the top left so we need to use | ||
437 | * 127 - y instead of just y */ | ||
438 | |||
439 | /* max vert << 8 | start vert */ | ||
440 | lcd_write_reg(R_VERT_RAM_ADDR_POS, ((x + width - 1) << 8) | x); | ||
441 | |||
442 | y0 = LCD_HEIGHT - 1 - y + y_offset; | ||
443 | |||
444 | /* DIT=0, BGR=1, HWM=0, I/D1-0=10, AM=0, LG2-0=000 */ | ||
445 | lcd_write_reg(R_ENTRY_MODE, 0x1020); | ||
446 | |||
447 | yuv_src[0] = src[0] + src_y * stride + src_x; | ||
448 | yuv_src[1] = src[1] + (src_y * stride >> 2) + (src_x >> 1); | ||
449 | yuv_src[2] = src[2] + (yuv_src[1] - src[1]); | ||
450 | ysrc_max = yuv_src[0] + height * stride; | ||
451 | |||
452 | options = lcd_yuv_options; | ||
453 | |||
454 | do | ||
455 | { | ||
456 | /* max horiz << 8 | start horiz */ | ||
457 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (y0 << 8) | (y0 - 1)); | ||
458 | |||
459 | /* position cursor (set AD0-AD15) */ | ||
460 | /* start vert << 8 | start horiz */ | ||
461 | lcd_write_reg(R_RAM_ADDR_SET, (x << 8) | y0); | ||
462 | |||
463 | /* start drawing */ | ||
464 | lcd_send_cmd(R_WRITE_DATA_2_GRAM); | ||
465 | |||
466 | if (options & LCD_YUV_DITHER) | ||
467 | { | ||
468 | lcd_write_yuv420_lines_odither(yuv_src, width, stride, | ||
469 | x, y); | ||
470 | y -= 2; | ||
471 | } | ||
472 | else | ||
473 | { | ||
474 | lcd_write_yuv420_lines(yuv_src, width, stride); | ||
475 | } | ||
476 | |||
477 | y0 -= 2; | ||
478 | yuv_src[0] += stride << 1; | ||
479 | yuv_src[1] += stride >> 1; | ||
480 | yuv_src[2] += stride >> 1; | ||
481 | } | ||
482 | while (yuv_src[0] < ysrc_max); | ||
483 | |||
484 | /* DIT=0, BGR=1, HWM=0, I/D1-0=10, AM=1, LG2-0=000 */ | ||
485 | lcd_write_reg(R_ENTRY_MODE, 0x1028); | ||
486 | } | ||
487 | |||
488 | |||
399 | /* Update a fraction of the display. */ | 489 | /* Update a fraction of the display. */ |
400 | void lcd_update_rect(int x0, int y0, int width, int height) | 490 | void lcd_update_rect(int x0, int y0, int width, int height) |
401 | { | 491 | { |