diff options
Diffstat (limited to 'firmware/target/arm/philips/hdd1630/lcd-hdd1630.c')
-rw-r--r-- | firmware/target/arm/philips/hdd1630/lcd-hdd1630.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/firmware/target/arm/philips/hdd1630/lcd-hdd1630.c b/firmware/target/arm/philips/hdd1630/lcd-hdd1630.c index d9570600bc..c26c0bc963 100644 --- a/firmware/target/arm/philips/hdd1630/lcd-hdd1630.c +++ b/firmware/target/arm/philips/hdd1630/lcd-hdd1630.c | |||
@@ -81,6 +81,7 @@ | |||
81 | static bool lcd_enabled; | 81 | static bool lcd_enabled; |
82 | 82 | ||
83 | /* Display status */ | 83 | /* Display status */ |
84 | static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0; | ||
84 | static unsigned mad_ctrl = 0; | 85 | static unsigned mad_ctrl = 0; |
85 | 86 | ||
86 | /* wait for LCD */ | 87 | /* wait for LCD */ |
@@ -312,6 +313,86 @@ void lcd_set_flip(bool yesno) | |||
312 | lcd_send_data(mad_ctrl); | 313 | lcd_send_data(mad_ctrl); |
313 | } | 314 | } |
314 | 315 | ||
316 | void lcd_yuv_set_options(unsigned options) | ||
317 | { | ||
318 | lcd_yuv_options = options; | ||
319 | } | ||
320 | |||
321 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ | ||
322 | extern void lcd_write_yuv420_lines(unsigned char const * const src[3], | ||
323 | int width, int stride); | ||
324 | |||
325 | extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3], | ||
326 | int width, int stride, | ||
327 | int x_screen, int y_screen); | ||
328 | |||
329 | /* Performance function to blit a YUV bitmap directly to the LCD */ | ||
330 | void lcd_blit_yuv(unsigned char * const src[3], | ||
331 | int src_x, int src_y, int stride, | ||
332 | int x, int y, int width, int height) | ||
333 | { | ||
334 | unsigned char const * yuv_src[3]; | ||
335 | off_t z; | ||
336 | |||
337 | /* Sorry, but width and height must be >= 2 or else */ | ||
338 | width &= ~1; | ||
339 | height >>= 1; | ||
340 | |||
341 | z = stride*src_y; | ||
342 | yuv_src[0] = src[0] + z + src_x; | ||
343 | yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); | ||
344 | yuv_src[2] = src[2] + (yuv_src[1] - src[1]); | ||
345 | |||
346 | /* Set vertical address mode */ | ||
347 | lcd_send_cmd(MADCTR); | ||
348 | lcd_send_data(mad_ctrl | (1<<5)); | ||
349 | |||
350 | lcd_send_cmd(RASET); | ||
351 | lcd_send_data(x); | ||
352 | lcd_send_data(x + width - 1); | ||
353 | |||
354 | if (lcd_yuv_options & LCD_YUV_DITHER) | ||
355 | { | ||
356 | do | ||
357 | { | ||
358 | lcd_send_cmd(CASET); | ||
359 | lcd_send_data(y); | ||
360 | lcd_send_data(y + 1); | ||
361 | |||
362 | lcd_send_cmd(RAMWR); | ||
363 | |||
364 | lcd_write_yuv420_lines_odither(yuv_src, width, stride, x, y); | ||
365 | yuv_src[0] += stride << 1; /* Skip down two luma lines */ | ||
366 | yuv_src[1] += stride >> 1; /* Skip down one chroma line */ | ||
367 | yuv_src[2] += stride >> 1; | ||
368 | y += 2; | ||
369 | } | ||
370 | while (--height > 0); | ||
371 | } | ||
372 | else | ||
373 | { | ||
374 | do | ||
375 | { | ||
376 | lcd_send_cmd(CASET); | ||
377 | lcd_send_data(y); | ||
378 | lcd_send_data(y + 1); | ||
379 | |||
380 | lcd_send_cmd(RAMWR); | ||
381 | |||
382 | lcd_write_yuv420_lines(yuv_src, width, stride); | ||
383 | yuv_src[0] += stride << 1; /* Skip down two luma lines */ | ||
384 | yuv_src[1] += stride >> 1; /* Skip down one chroma line */ | ||
385 | yuv_src[2] += stride >> 1; | ||
386 | y += 2; | ||
387 | } | ||
388 | while (--height > 0); | ||
389 | } | ||
390 | |||
391 | /* Restore the address mode */ | ||
392 | lcd_send_cmd(MADCTR); | ||
393 | lcd_send_data(mad_ctrl); | ||
394 | } | ||
395 | |||
315 | /* Update the display. | 396 | /* Update the display. |
316 | This must be called after all other LCD functions that change the display. */ | 397 | This must be called after all other LCD functions that change the display. */ |
317 | void lcd_update(void) | 398 | void lcd_update(void) |