diff options
Diffstat (limited to 'firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c')
-rw-r--r-- | firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c b/firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c index 141340c003..f69ad48793 100644 --- a/firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c +++ b/firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c | |||
@@ -336,6 +336,104 @@ bool lcd_active(void) | |||
336 | 336 | ||
337 | /*** update functions ***/ | 337 | /*** update functions ***/ |
338 | 338 | ||
339 | static unsigned lcd_yuv_options = 0; | ||
340 | |||
341 | void lcd_yuv_set_options(unsigned options) | ||
342 | { | ||
343 | lcd_yuv_options = options; | ||
344 | } | ||
345 | |||
346 | |||
347 | #ifndef BOOTLOADER | ||
348 | static void lcd_window_blit(int xmin, int ymin, int xmax, int ymax) | ||
349 | { | ||
350 | if (!display_flipped) | ||
351 | { | ||
352 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, | ||
353 | ((LCD_WIDTH-1 - xmin) << 8) | (LCD_WIDTH-1 - xmax)); | ||
354 | lcd_write_reg(R_VERT_RAM_ADDR_POS, (ymax << 8) | ymin); | ||
355 | lcd_write_reg(R_RAM_ADDR_SET, | ||
356 | (ymin << 8) | (LCD_WIDTH-1 - xmin)); | ||
357 | } | ||
358 | else | ||
359 | { | ||
360 | lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (xmax << 8) | xmin); | ||
361 | lcd_write_reg(R_VERT_RAM_ADDR_POS, (ymax << 8) | ymin); | ||
362 | lcd_write_reg(R_RAM_ADDR_SET, (ymax << 8) | xmin); | ||
363 | } | ||
364 | } | ||
365 | |||
366 | /* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */ | ||
367 | extern void lcd_write_yuv420_lines(unsigned char const * const src[3], | ||
368 | int width, | ||
369 | int stride); | ||
370 | extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3], | ||
371 | int width, | ||
372 | int stride, | ||
373 | int x_screen, /* To align dither pattern */ | ||
374 | int y_screen); | ||
375 | |||
376 | /* Performance function to blit a YUV bitmap directly to the LCD | ||
377 | * src_x, src_y, width and height should be even | ||
378 | * x, y, width and height have to be within LCD bounds | ||
379 | */ | ||
380 | void lcd_blit_yuv(unsigned char * const src[3], | ||
381 | int src_x, int src_y, int stride, | ||
382 | int x, int y, int width, int height) | ||
383 | { | ||
384 | unsigned char const * yuv_src[3]; | ||
385 | off_t z; | ||
386 | |||
387 | /* Sorry, but width and height must be >= 2 or else */ | ||
388 | width &= ~1; | ||
389 | height >>= 1; | ||
390 | |||
391 | z = stride*src_y; | ||
392 | yuv_src[0] = src[0] + z + src_x; | ||
393 | yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); | ||
394 | yuv_src[2] = src[2] + (yuv_src[1] - src[1]); | ||
395 | |||
396 | lcd_write_reg(R_ENTRY_MODE, | ||
397 | display_flipped ? R_ENTRY_MODE_VIDEO_FLIPPED : R_ENTRY_MODE_VIDEO_NORMAL | ||
398 | ); | ||
399 | |||
400 | if (lcd_yuv_options & LCD_YUV_DITHER) | ||
401 | { | ||
402 | do | ||
403 | { | ||
404 | lcd_window_blit(y, x, y+1, x+width-1); | ||
405 | |||
406 | lcd_write_cmd(R_WRITE_DATA_2_GRAM); | ||
407 | |||
408 | lcd_write_yuv420_lines_odither(yuv_src, width, stride, x, y); | ||
409 | yuv_src[0] += stride << 1; /* Skip down two luma lines */ | ||
410 | yuv_src[1] += stride >> 1; /* Skip down one chroma line */ | ||
411 | yuv_src[2] += stride >> 1; | ||
412 | y += 2; | ||
413 | } | ||
414 | while (--height > 0); | ||
415 | } | ||
416 | else | ||
417 | { | ||
418 | do | ||
419 | { | ||
420 | lcd_window_blit(y, x, y+1, x+width-1); | ||
421 | |||
422 | lcd_write_cmd(R_WRITE_DATA_2_GRAM); | ||
423 | |||
424 | lcd_write_yuv420_lines(yuv_src, width, stride); | ||
425 | yuv_src[0] += stride << 1; /* Skip down two luma lines */ | ||
426 | yuv_src[1] += stride >> 1; /* Skip down one chroma line */ | ||
427 | yuv_src[2] += stride >> 1; | ||
428 | y += 2; | ||
429 | } | ||
430 | while (--height > 0); | ||
431 | } | ||
432 | } | ||
433 | |||
434 | #endif | ||
435 | |||
436 | |||
339 | /* Update the display. | 437 | /* Update the display. |
340 | This must be called after all other LCD functions that change the display. */ | 438 | This must be called after all other LCD functions that change the display. */ |
341 | void lcd_update(void) | 439 | void lcd_update(void) |