From 0250be1d6799db7b5ddc99cb33f31bf9cff01ed2 Mon Sep 17 00:00:00 2001 From: Thomas Martitz Date: Sun, 15 Jun 2014 18:26:44 +0200 Subject: lcd-16bit: Split out some functions to lcd-color-common.c An upcoming lcd-24bit.c driver will re-use a lot of code from the 16bit drivers, so prepare for that. Change-Id: I7bc7f6b992e5e3f4e0a0aa54dc08103ebb05315f --- firmware/drivers/lcd-16bit-common.c | 574 ------------------------------------ 1 file changed, 574 deletions(-) (limited to 'firmware/drivers/lcd-16bit-common.c') diff --git a/firmware/drivers/lcd-16bit-common.c b/firmware/drivers/lcd-16bit-common.c index 93e7c2e012..d006b3900a 100644 --- a/firmware/drivers/lcd-16bit-common.c +++ b/firmware/drivers/lcd-16bit-common.c @@ -28,44 +28,6 @@ #error ROW_INC or COL_INC not defined #endif -enum fill_opt { - OPT_NONE = 0, - OPT_SET, - OPT_COPY -}; - -/*** globals ***/ -fb_data lcd_static_framebuffer[LCD_FBHEIGHT][LCD_FBWIDTH] - IRAM_LCDFRAMEBUFFER CACHEALIGN_AT_LEAST_ATTR(16); -fb_data *lcd_framebuffer = &lcd_static_framebuffer[0][0]; - -static fb_data* lcd_backdrop = NULL; -static long lcd_backdrop_offset IDATA_ATTR = 0; - -static struct viewport default_vp = -{ - .x = 0, - .y = 0, - .width = LCD_WIDTH, - .height = LCD_HEIGHT, - .font = FONT_SYSFIXED, - .drawmode = DRMODE_SOLID, - .fg_pattern = LCD_DEFAULT_FG, - .bg_pattern = LCD_DEFAULT_BG, -}; - -static struct viewport* current_vp IDATA_ATTR = &default_vp; - -/* LCD init */ -void lcd_init(void) -{ - lcd_clear_display(); - - /* Call device specific init */ - lcd_init_device(); - scroll_init(); -} - /* Clear the current viewport */ void lcd_clear_viewport(void) { @@ -146,70 +108,6 @@ void lcd_clear_viewport(void) lcd_scroll_stop_viewport(current_vp); } -/*** parameter handling ***/ - -void lcd_set_drawmode(int mode) -{ - current_vp->drawmode = mode & (DRMODE_SOLID|DRMODE_INVERSEVID); -} - -int lcd_get_drawmode(void) -{ - return current_vp->drawmode; -} - -void lcd_set_foreground(unsigned color) -{ - current_vp->fg_pattern = color; -} - -unsigned lcd_get_foreground(void) -{ - return current_vp->fg_pattern; -} - -void lcd_set_background(unsigned color) -{ - current_vp->bg_pattern = color; -} - -unsigned lcd_get_background(void) -{ - return current_vp->bg_pattern; -} - -void lcd_set_drawinfo(int mode, unsigned fg_color, unsigned bg_color) -{ - lcd_set_drawmode(mode); - current_vp->fg_pattern = fg_color; - current_vp->bg_pattern = bg_color; -} - -int lcd_getwidth(void) -{ - return current_vp->width; -} - -int lcd_getheight(void) -{ - return current_vp->height; -} - -void lcd_setfont(int newfont) -{ - current_vp->font = newfont; -} - -int lcd_getfont(void) -{ - return current_vp->font; -} - -int lcd_getstringsize(const unsigned char *str, int *w, int *h) -{ - return font_getstringsize(str, w, h, current_vp->font); -} - /*** low-level drawing functions ***/ static void ICODE_ATTR setpixel(fb_data *address) @@ -249,155 +147,6 @@ lcd_fastpixelfunc_type* const lcd_fastpixelfuncs_backdrop[8] = { lcd_fastpixelfunc_type* const * lcd_fastpixelfuncs = lcd_fastpixelfuncs_bgcolor; -void lcd_set_backdrop(fb_data* backdrop) -{ - lcd_backdrop = backdrop; - if (backdrop) - { - lcd_backdrop_offset = (long)backdrop - (long)lcd_framebuffer; - lcd_fastpixelfuncs = lcd_fastpixelfuncs_backdrop; - } - else - { - lcd_backdrop_offset = 0; - lcd_fastpixelfuncs = lcd_fastpixelfuncs_bgcolor; - } -} - -fb_data* lcd_get_backdrop(void) -{ - return lcd_backdrop; -} - -/* Clear the whole display */ -void lcd_clear_display(void) -{ - struct viewport* old_vp = current_vp; - - current_vp = &default_vp; - - lcd_clear_viewport(); - - current_vp = old_vp; -} - -/* Set a single pixel */ -void lcd_drawpixel(int x, int y) -{ - if ( ((unsigned)x < (unsigned)current_vp->width) - && ((unsigned)y < (unsigned)current_vp->height) -#if defined(HAVE_VIEWPORT_CLIP) - && ((unsigned)x < (unsigned)LCD_WIDTH) - && ((unsigned)y < (unsigned)LCD_HEIGHT) -#endif - ) - lcd_fastpixelfuncs[current_vp->drawmode](FBADDR(current_vp->x+x, current_vp->y+y)); -} - -/* Draw a line */ -void lcd_drawline(int x1, int y1, int x2, int y2) -{ - int numpixels; - int i; - int deltax, deltay; - int d, dinc1, dinc2; - int x, xinc1, xinc2; - int y, yinc1, yinc2; - lcd_fastpixelfunc_type *pfunc = lcd_fastpixelfuncs[current_vp->drawmode]; - - deltay = abs(y2 - y1); - if (deltay == 0) - { - /* DEBUGF("lcd_drawline() called for horizontal line - optimisation.\n"); */ - lcd_hline(x1, x2, y1); - return; - } - deltax = abs(x2 - x1); - if (deltax == 0) - { - /* DEBUGF("lcd_drawline() called for vertical line - optimisation.\n"); */ - lcd_vline(x1, y1, y2); - return; - } - xinc2 = 1; - yinc2 = 1; - - if (deltax >= deltay) - { - numpixels = deltax; - d = 2 * deltay - deltax; - dinc1 = deltay * 2; - dinc2 = (deltay - deltax) * 2; - xinc1 = 1; - yinc1 = 0; - } - else - { - numpixels = deltay; - d = 2 * deltax - deltay; - dinc1 = deltax * 2; - dinc2 = (deltax - deltay) * 2; - xinc1 = 0; - yinc1 = 1; - } - numpixels++; /* include endpoints */ - - if (x1 > x2) - { - xinc1 = -xinc1; - xinc2 = -xinc2; - } - - if (y1 > y2) - { - yinc1 = -yinc1; - yinc2 = -yinc2; - } - - x = x1; - y = y1; - - for (i = 0; i < numpixels; i++) - { - if ( ((unsigned)x < (unsigned)current_vp->width) - && ((unsigned)y < (unsigned)current_vp->height) -#if defined(HAVE_VIEWPORT_CLIP) - && ((unsigned)x < (unsigned)LCD_WIDTH) - && ((unsigned)y < (unsigned)LCD_HEIGHT) -#endif - ) - pfunc(FBADDR(x + current_vp->x, y + current_vp->y)); - - if (d < 0) - { - d += dinc1; - x += xinc1; - y += yinc1; - } - else - { - d += dinc2; - x += xinc2; - y += yinc2; - } - } -} - -/* Draw a rectangular box */ -void lcd_drawrect(int x, int y, int width, int height) -{ - if ((width <= 0) || (height <= 0)) - return; - - int x2 = x + width - 1; - int y2 = y + height - 1; - - lcd_vline(x, y, y2); - lcd_vline(x2, y, y2); - lcd_hline(x, x2, y); - lcd_hline(x, x2, y2); -} - /* Fill a rectangular area */ void lcd_fillrect(int x, int y, int width, int height) { @@ -1087,326 +836,3 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, BLEND_FINISH; } - -/* Draw a full native bitmap */ -void lcd_bitmap(const fb_data *src, int x, int y, int width, int height) -{ - lcd_bitmap_part(src, 0, 0, STRIDE(SCREEN_MAIN, width, height), x, y, width, height); -} - -/* Draw a full native bitmap with a transparent color */ -void lcd_bitmap_transparent(const fb_data *src, int x, int y, - int width, int height) -{ - lcd_bitmap_transparent_part(src, 0, 0, - STRIDE(SCREEN_MAIN, width, height), x, y, width, height); -} - -/* draw alpha bitmap for anti-alias font */ -void ICODE_ATTR lcd_alpha_bitmap_part(const unsigned char *src, int src_x, - int src_y, int stride, int x, int y, - int width, int height) -{ - lcd_alpha_bitmap_part_mix(NULL, src, src_x, src_y, x, y, width, height, 0, stride); -} - -/* Draw a partial bitmap (mono or native) including alpha channel */ -void ICODE_ATTR lcd_bmp_part(const struct bitmap* bm, int src_x, int src_y, - int x, int y, int width, int height) -{ - int bitmap_stride = STRIDE_MAIN(bm->width, bm->height); - if (bm->format == FORMAT_MONO) - lcd_mono_bitmap_part(bm->data, src_x, src_y, bitmap_stride, x, y, width, height); - else if (bm->alpha_offset > 0) - lcd_alpha_bitmap_part_mix((fb_data*)bm->data, bm->data+bm->alpha_offset, - src_x, src_y, x, y, width, height, - bitmap_stride, ALIGN_UP(bm->width, 2)); - else - lcd_bitmap_transparent_part((fb_data*)bm->data, - src_x, src_y, bitmap_stride, x, y, width, height); -} - -/* Draw a native bitmap with alpha channel */ -void ICODE_ATTR lcd_bmp(const struct bitmap *bmp, int x, int y) -{ - lcd_bmp_part(bmp, 0, 0, x, y, bmp->width, bmp->height); -} - -/** - * |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 - */ -#define YFAC (74) -#define RVFAC (101) -#define GUFAC (-24) -#define GVFAC (-51) -#define BUFAC (128) - -static inline int clamp(int val, int min, int max) -{ - if (val < min) - val = min; - else if (val > max) - val = max; - return val; -} - -#ifndef _WIN32 -/* - * weak attribute doesn't work for win32 as of gcc 4.6.2 and binutils 2.21.52 - * When building win32 simulators, we won't be using an optimized version of - * lcd_blit_yuv(), so just don't use the weak attribute. - */ -__attribute__((weak)) -#endif -void lcd_yuv_set_options(unsigned options) -{ - (void)options; -} - -/* Draw a partial YUV colour bitmap */ -#ifndef _WIN32 -__attribute__((weak)) -#endif -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) -{ - const unsigned char *ysrc, *usrc, *vsrc; - int linecounter; - fb_data *dst, *row_end; - long z; - - /* width and height must be >= 2 and an even number */ - width &= ~1; - linecounter = height >> 1; - -#if LCD_WIDTH >= LCD_HEIGHT - dst = FBADDR(x, y); - row_end = dst + width; -#else - dst = FBADDR(LCD_WIDTH - y - 1, x); - row_end = dst + LCD_WIDTH * width; -#endif - - z = stride * src_y; - ysrc = src[0] + z + src_x; - usrc = src[1] + (z >> 2) + (src_x >> 1); - vsrc = src[2] + (usrc - src[1]); - - /* stride => amount to jump from end of last row to start of next */ - stride -= width; - - /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */ - - do - { - do - { - int y, cb, cr, rv, guv, bu, r, g, b; - - y = YFAC*(*ysrc++ - 16); - cb = *usrc++ - 128; - cr = *vsrc++ - 128; - - rv = RVFAC*cr; - guv = GUFAC*cb + GVFAC*cr; - bu = BUFAC*cb; - - r = y + rv; - g = y + guv; - b = y + bu; - - if ((unsigned)(r | g | b) > 64*256-1) - { - r = clamp(r, 0, 64*256-1); - g = clamp(g, 0, 64*256-1); - b = clamp(b, 0, 64*256-1); - } - - *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); - -#if LCD_WIDTH >= LCD_HEIGHT - dst++; -#else - dst += LCD_WIDTH; -#endif - - y = YFAC*(*ysrc++ - 16); - r = y + rv; - g = y + guv; - b = y + bu; - - if ((unsigned)(r | g | b) > 64*256-1) - { - r = clamp(r, 0, 64*256-1); - g = clamp(g, 0, 64*256-1); - b = clamp(b, 0, 64*256-1); - } - - *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); - -#if LCD_WIDTH >= LCD_HEIGHT - dst++; -#else - dst += LCD_WIDTH; -#endif - } - while (dst < row_end); - - ysrc += stride; - usrc -= width >> 1; - vsrc -= width >> 1; - -#if LCD_WIDTH >= LCD_HEIGHT - row_end += LCD_WIDTH; - dst += LCD_WIDTH - width; -#else - row_end -= 1; - dst -= LCD_WIDTH*width + 1; -#endif - - do - { - int y, cb, cr, rv, guv, bu, r, g, b; - - y = YFAC*(*ysrc++ - 16); - cb = *usrc++ - 128; - cr = *vsrc++ - 128; - - rv = RVFAC*cr; - guv = GUFAC*cb + GVFAC*cr; - bu = BUFAC*cb; - - r = y + rv; - g = y + guv; - b = y + bu; - - if ((unsigned)(r | g | b) > 64*256-1) - { - r = clamp(r, 0, 64*256-1); - g = clamp(g, 0, 64*256-1); - b = clamp(b, 0, 64*256-1); - } - - *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); - -#if LCD_WIDTH >= LCD_HEIGHT - dst++; -#else - dst += LCD_WIDTH; -#endif - - y = YFAC*(*ysrc++ - 16); - r = y + rv; - g = y + guv; - b = y + bu; - - if ((unsigned)(r | g | b) > 64*256-1) - { - r = clamp(r, 0, 64*256-1); - g = clamp(g, 0, 64*256-1); - b = clamp(b, 0, 64*256-1); - } - - *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9); - -#if LCD_WIDTH >= LCD_HEIGHT - dst++; -#else - dst += LCD_WIDTH; -#endif - } - while (dst < row_end); - - ysrc += stride; - usrc += stride >> 1; - vsrc += stride >> 1; - -#if LCD_WIDTH >= LCD_HEIGHT - row_end += LCD_WIDTH; - dst += LCD_WIDTH - width; -#else - row_end -= 1; - dst -= LCD_WIDTH*width + 1; -#endif - } - while (--linecounter > 0); - -#if LCD_WIDTH >= LCD_HEIGHT - lcd_update_rect(x, y, width, height); -#else - lcd_update_rect(LCD_WIDTH - y - height, x, height, width); -#endif -} - -/* Fill a rectangle with a gradient. This function draws only the partial - * gradient. It assumes the original gradient is src_height high and skips - * the first few rows. This is useful for drawing only the bottom half of - * a full gradient. - * - * height == src_height and row_skip == 0 will draw the full gradient - * - * x, y, width, height - dimensions describing the rectangle - * start_rgb - beginning color of the gradient - * end_rgb - end color of the gradient - * src_height - assumed original height (only height rows will be drawn) - * row_skip - how many rows of the original gradient to skip - */ -void lcd_gradient_fillrect_part(int x, int y, int width, int height, - unsigned start_rgb, unsigned end_rgb, int src_height, int row_skip) -{ - int old_pattern = current_vp->fg_pattern; - int step_mul, i; - int x1, x2; - x1 = x; - x2 = x + width; - - if (height == 0) return; - - step_mul = (1 << 16) / src_height; - int h_r = RGB_UNPACK_RED(start_rgb); - int h_g = RGB_UNPACK_GREEN(start_rgb); - int h_b = RGB_UNPACK_BLUE(start_rgb); - int rstep = (h_r - RGB_UNPACK_RED(end_rgb)) * step_mul; - int gstep = (h_g - RGB_UNPACK_GREEN(end_rgb)) * step_mul; - int bstep = (h_b - RGB_UNPACK_BLUE(end_rgb)) * step_mul; - h_r = (h_r << 16) + (1 << 15); - h_g = (h_g << 16) + (1 << 15); - h_b = (h_b << 16) + (1 << 15); - - if (row_skip > 0) - { - h_r -= rstep * row_skip; - h_g -= gstep * row_skip; - h_b -= bstep * row_skip; - } - - for(i = y; i < y + height; i++) { - current_vp->fg_pattern = LCD_RGBPACK(h_r >> 16, h_g >> 16, h_b >> 16); - lcd_hline(x1, x2, i); - h_r -= rstep; - h_g -= gstep; - h_b -= bstep; - } - - current_vp->fg_pattern = old_pattern; -} - -/* Fill a rectangle with a gradient. The gradient's color will fade from - * start_rgb to end_rgb over the height of the rectangle - * - * x, y, width, height - dimensions describing the rectangle - * start_rgb - beginning color of the gradient - * end_rgb - end color of the gradient - */ -void lcd_gradient_fillrect(int x, int y, int width, int height, - unsigned start_rgb, unsigned end_rgb) -{ - lcd_gradient_fillrect_part(x, y, width, height, start_rgb, end_rgb, height, 0); -} -- cgit v1.2.3