diff options
Diffstat (limited to 'firmware/target/arm/ipod/video/lcd-video.c')
-rw-r--r-- | firmware/target/arm/ipod/video/lcd-video.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/firmware/target/arm/ipod/video/lcd-video.c b/firmware/target/arm/ipod/video/lcd-video.c index 494bec8429..27d889aafa 100644 --- a/firmware/target/arm/ipod/video/lcd-video.c +++ b/firmware/target/arm/ipod/video/lcd-video.c @@ -439,6 +439,53 @@ void lcd_update(void) lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); } +/* Line write helper function for lcd_yuv_blit. Writes two lines of yuv420. */ +extern void lcd_write_yuv420_lines(unsigned char const * const src[3], + unsigned bcmaddr, + int width, + int stride); + +/* 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) +{ + unsigned bcmaddr; + off_t z; + unsigned char const * yuv_src[3]; + +#ifdef HAVE_LCD_SLEEP + if (!lcd_state.display_on) + return; +#endif + + /* Sorry, but width and height must be >= 2 or else */ + width &= ~1; + + z = stride * src_y; + yuv_src[0] = src[0] + z + src_x; + yuv_src[1] = src[1] + (z >> 2) + (src_x >> 1); + yuv_src[2] = src[2] + (yuv_src[1] - src[1]); + + /* Prevent the tick from triggering BCM updates while we're writing. */ + lcd_block_tick(); + + bcmaddr = BCMA_CMDPARAM + (LCD_WIDTH*2) * y + (x << 1); + height >>= 1; + + do + { + lcd_write_yuv420_lines(yuv_src, bcmaddr, width, stride); + bcmaddr += (LCD_WIDTH*4); /* Skip up two lines */ + yuv_src[0] += stride << 1; + yuv_src[1] += stride >> 1; /* Skip down one chroma line */ + yuv_src[2] += stride >> 1; + } + while (--height > 0); + + lcd_unblock_and_update(); +} + #ifdef HAVE_LCD_SLEEP /* Executes a BCM command immediately and waits for it to complete. Other BCM commands (eg. LCD updates or lcd_tick) must not interfere. |