From 418169aff8faf2cf90124cd95dba0af821cea73d Mon Sep 17 00:00:00 2001 From: Solomon Peachy Date: Thu, 13 Oct 2022 11:03:53 -0400 Subject: Revert "Remove YUV blitting functions and LCD modes" This reverts commit fe6aa21e9eb88f49005863efd2003d0982920048. Change-Id: I8bb1e5d6c52ed1478002d2140ef494ec5d62b8e3 --- firmware/target/arm/philips/hdd6330/lcd-hdd6330.c | 98 +++++++++++++++++++++++ 1 file changed, 98 insertions(+) (limited to 'firmware/target/arm/philips/hdd6330/lcd-hdd6330.c') diff --git a/firmware/target/arm/philips/hdd6330/lcd-hdd6330.c b/firmware/target/arm/philips/hdd6330/lcd-hdd6330.c index 9d2fdc8519..cdd3064bba 100644 --- a/firmware/target/arm/philips/hdd6330/lcd-hdd6330.c +++ b/firmware/target/arm/philips/hdd6330/lcd-hdd6330.c @@ -37,6 +37,9 @@ /* whether the lcd is currently enabled or not */ static bool lcd_enabled; +/* Display status */ +static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0; + /* Value used for flipping. Must be remembered when display is turned off. */ static unsigned short flip; @@ -144,6 +147,101 @@ void lcd_set_flip(bool yesno) lcd_send_data(0x08 | flip); } +void lcd_yuv_set_options(unsigned options) +{ + lcd_yuv_options = options; +} + +#define CSUB_X 2 +#define CSUB_Y 2 + +/* YUV- > RGB565 conversion + * |R| |1.000000 -0.000001 1.402000| |Y'| + * |G| = |1.000000 -0.334136 -0.714136| |Pb| + * |B| |1.000000 1.772000 0.000000| |Pr| + * Scaled, normalized, rounded and tweaked to yield RGB 565: + * |R| |74 0 101| |Y' - 16| >> 9 + * |G| = |74 -24 -51| |Cb - 128| >> 8 + * |B| |74 128 0| |Cr - 128| >> 9 +*/ + +extern void lcd_yuv_write_inner_loop(unsigned char const * const ysrc, + unsigned char const * const usrc, + unsigned char const * const vsrc, + int width); + +/* Performance function to blit a YUV bitmap directly to the LCD */ +void lcd_blit_yuv(unsigned char * const src[3], + int src_x, int src_y, int stride, + int x, int y, int width, int height) +{ + int h; + + width = (width + 1) & ~1; + + lcd_send_reg(LCD_REG_HORIZ_ADDR_START); + lcd_send_data(y); + + lcd_send_reg(LCD_REG_HORIZ_ADDR_END); + lcd_send_data(y + height - 1); + + lcd_send_reg(LCD_REG_VERT_ADDR_START); + lcd_send_data(x + x_offset); + + lcd_send_reg(LCD_REG_VERT_ADDR_END); + lcd_send_data(x + width - 1 + x_offset); + + lcd_send_reg(LCD_REG_WRITE_DATA_2_GRAM); + + const int stride_div_csub_x = stride/CSUB_X; + + h=0; + while (1) + { + /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */ + const unsigned char *ysrc = src[0] + stride * src_y + src_x; + + const int uvoffset = stride_div_csub_x * (src_y/CSUB_Y) + + (src_x/CSUB_X); + + const unsigned char *usrc = src[1] + uvoffset; + const unsigned char *vsrc = src[2] + uvoffset; + + int pixels_to_write; + + if (h==0) + { + while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_READY)); + LCD2_BLOCK_CONFIG = 0; + + if (height == 0) break; + + pixels_to_write = (width * height) * 2; + h = height; + + /* calculate how much we can do in one go */ + if (pixels_to_write > 0x10000) + { + h = (0x10000/2) / width; + pixels_to_write = (width * h) * 2; + } + + height -= h; + LCD2_BLOCK_CTRL = 0x10000080; + LCD2_BLOCK_CONFIG = 0xc0010000 | (pixels_to_write - 1); + LCD2_BLOCK_CTRL = 0x34000000; + } + + lcd_yuv_write_inner_loop(ysrc,usrc,vsrc,width); + + src_y++; + h--; + } + + while (!(LCD2_BLOCK_CTRL & LCD2_BLOCK_READY)); + LCD2_BLOCK_CONFIG = 0; +} + /* Update the display. This must be called after all other LCD functions that change the display. */ void lcd_update(void) -- cgit v1.2.3