summaryrefslogtreecommitdiff
path: root/firmware/target/coldfire/iaudio/x5/lcd-x5.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/coldfire/iaudio/x5/lcd-x5.c')
-rw-r--r--firmware/target/coldfire/iaudio/x5/lcd-x5.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/firmware/target/coldfire/iaudio/x5/lcd-x5.c b/firmware/target/coldfire/iaudio/x5/lcd-x5.c
index a6a4fc0176..266a381c40 100644
--- a/firmware/target/coldfire/iaudio/x5/lcd-x5.c
+++ b/firmware/target/coldfire/iaudio/x5/lcd-x5.c
@@ -414,6 +414,69 @@ bool lcd_active(void)
414#endif 414#endif
415/*** update functions ***/ 415/*** update functions ***/
416 416
417/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420.
418 * y should have two lines of Y back to back, 2nd line first.
419 * c should contain the Cb and Cr data for the two lines of Y back to back.
420 * Needs EMAC set to saturated, signed integer mode.
421 */
422extern void lcd_write_yuv420_lines(const unsigned char *y,
423 const unsigned char *c, int width);
424
425/* Performance function to blit a YUV bitmap directly to the LCD
426 * src_x, src_y, width and height should be even and within the LCD's
427 * boundaries.
428 */
429void lcd_blit_yuv(unsigned char * const src[3],
430 int src_x, int src_y, int stride,
431 int x, int y, int width, int height)
432{
433 /* IRAM Y, Cb/bu, guv and Cb/rv buffers. */
434 unsigned char y_ibuf[LCD_WIDTH*2];
435 unsigned char c_ibuf[LCD_WIDTH];
436 const unsigned char *ysrc, *usrc, *vsrc;
437 const unsigned char *ysrc_max;
438
439 if (!display_on)
440 return;
441
442 width &= ~1; /* stay on the safe side */
443 height &= ~1;
444
445 lcd_write_reg(R_ENTRY_MODE, R_ENTRY_MODE_DIT_HORZ);
446 /* Set start position and window */
447 lcd_write_reg(R_VERT_RAM_ADDR_POS, (LCD_WIDTH-1) << 8);
448
449 ysrc = src[0] + src_y * stride + src_x;
450 usrc = src[1] + (src_y * stride >> 2) + (src_x >> 1);
451 vsrc = src[2] + (src_y * stride >> 2) + (src_x >> 1);
452 ysrc_max = ysrc + height * stride;
453
454 unsigned long macsr = coldfire_get_macsr();
455 coldfire_set_macsr(EMAC_SATURATE);
456
457 do
458 {
459 lcd_write_reg(R_HORIZ_RAM_ADDR_POS, ((y + y_offset + 1) << 8) | (y + y_offset));
460 lcd_write_reg(R_RAM_ADDR_SET, (x << 8) | (y + y_offset));
461 lcd_begin_write_gram();
462
463 memcpy(y_ibuf + width, ysrc, width);
464 memcpy(y_ibuf, ysrc + stride, width);
465 memcpy(c_ibuf, usrc, width >> 1);
466 memcpy(c_ibuf + (width >> 1), vsrc, width >> 1);
467 lcd_write_yuv420_lines(y_ibuf, c_ibuf, width >> 1);
468
469 y += 2;
470 ysrc += 2 * stride;
471 usrc += stride >> 1;
472 vsrc += stride >> 1;
473 }
474 while (ysrc < ysrc_max);
475
476 coldfire_set_macsr(macsr);
477} /* lcd_yuv_blit */
478
479
417/* Update the display. 480/* Update the display.
418 This must be called after all other LCD functions that change the 481 This must be called after all other LCD functions that change the
419 lcd frame buffer. */ 482 lcd frame buffer. */