/*************************************************************** ** (c)2009-2010 Broadcom Corporation ** ** This program is the proprietary software of Broadcom Corporation and/or its licensors, ** and may only be used, duplicated, modified or distributed pursuant to the terms and ** conditions of a separate, written license agreement executed between you and Broadcom ** (an "Authorized License"). Except as set forth in an Authorized License, Broadcom grants ** no license (express or implied), right to use, or waiver of any kind with respect to the ** Software, and Broadcom expressly reserves all rights in and to the Software and all ** intellectual property rights therein. IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU ** HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY ** NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE. ** ** Except as expressly set forth in the Authorized License, ** ** 1. This program, including its structure, sequence and organization, constitutes the valuable trade ** secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof, ** and to use this information only in connection with your use of Broadcom integrated circuit products. ** ** 2. TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" ** AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR ** WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO ** THE SOFTWARE. BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES ** OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, ** LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION ** OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF ** USE OR PERFORMANCE OF THE SOFTWARE. ** ** 3. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS ** LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR ** EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR ** USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF ** THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT ** ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE ** LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF ** ANY LIMITED REMEDY. ** ** Created: 8/22/2002 by Jeffrey P. Fisher ** ** $brcm_Workfile: bgfx.c $ ** $brcm_Revision: Refsw_7550/10 $ ** $brcm_Date: 4/14/10 3:29p $ ** ** Revision History: ** ** $brcm_Log: /nexus/lib/softgfx/src/bgfx.c $ ** ** Refsw_7550/10 4/14/10 3:29p gautamk ** SW7550-369:[7550] Fixing compilation warning ** ** Refsw_7550/9 4/8/10 6:38p gautamk ** SW7550-369:[7550] Merging Scaling feature of softgfx to mainline. ** ** Refsw_7550/SWARTEMIS-10/4 3/26/10 6:57p gezhang ** SW7550-208: Require stretch-BLIT function on soft-gfx lib ** ** Refsw_7550/8 2/18/10 11:09a kagrawal ** SW7550-265: Added CSC from ARGB8888 to AYCbCr8888 ** ** Refsw_7550/8 2/18/10 10:51a kagrawal ** SW7550-265: Added CSC from ARGB8888 to AYCbCr8888 ** ** Refsw_7550/6 11/26/09 11:27a kagrawal ** SW7550-77: Fixed compile time warning ** ** Refsw_7550/5 11/5/09 9:41a kagrawal ** SW7550-59: Added special cases when as=0 and at=0 for further ** optimizing alpha-blending ** ** Refsw_7550/4 11/4/09 3:57p kagrawal ** SW7550-59: Fix incorrect bt extraction (which was over-writing at) in ** bgfx_blit_pixel_ARGB8888_optimized() ** ** Refsw_7550/3 11/4/09 11:10a kagrawal ** SW7550-59: Performance optimazation ** - Alpha-blend for operation 0x33 ** - Fill, BLT are using memcpy() ** - Alpha-blended Fill is comparing previous pixels ** ** Refsw_7550/2 9/25/09 12:54p kagrawal ** SW7550-50: Performance optimized gfx from 7003 latest ** ** Refsw_7550/1 9/7/09 5:04p kagrawal ** SW7550-3: Initial check-in for Soft Graphics ** ****************************************************************/ /** include files **/ //#define BDISPATCH_BYPASS #include "bgfx.h" #include #include #undef BDISPATCH_BYPASS #if !defined LINUX && !defined B_OS_UCOS_II #include "bdispatch.h" #endif #if SOFT_GFX_AS_IN_7003 #include "bpxl.h" #endif BDBG_MODULE(bgfx); #define GRAPHICS_FMT_P4 NEXUS_PixelFormat_ePalette4 #define GRAPHICS_FMT_P8 NEXUS_PixelFormat_ePalette8 #define GRAPHICS_FMT_ARGB_888 NEXUS_PixelFormat_eA8_R8_G8_B8 #define GRAPHICS_FMT_RGBA_888 NEXUS_PixelFormat_eR8_G8_B8_A8 #define GRAPHICS_FMT_AYCbCr_888 NEXUS_PixelFormat_eA8_Y8_Cb8_Cr8 #define GRAPHICS_FMT_RGB_565 NEXUS_PixelFormat_eR5_G6_B5 #define GRAPHICS_FMT_WRGB_1555 NEXUS_PixelFormat_eA1_R5_G5_B5 #define GRAPHICS_FMT_RGBW_5551 NEXUS_PixelFormat_eR5_G5_B5_A1 #define GRAPHICS_FMT_ARGB_4444 NEXUS_PixelFormat_eA4_R4_G4_B4 #define GRAPHICS_FMT_RGBA_4444 NEXUS_PixelFormat_eR4_G4_B4_A4 #define ZORDER_TUNNEL 3 #define ZORDER_FX 2 #define ZORDER_TOP 1 #define ZORDER_BOTTOM 0 #define SURF_WIDTH 720 #define BGFX_MIN(x,y) ((x < y) ? x : y) #define bgfx_valid_flags(x) ((x & BGFX_SURF_RGB) ? (x & BGFX_SURF_PRIMARY) : 1) #define bgfx_clut8_to_rgb(clut,c) (uint32_t)(clut[c]) #if SOFT_GFX_AS_IN_7003 #define CONFIG_BGFX_SURF_RGB #define SIMPLE_BLENDING_FORMULA #define COMPARE_PREVIOUS_PIXEL #endif #define _BGFX_CALC_OFFSET 10 /******************************************************************************* Color Space Conversion Equations: o RGB -> YCrCb RGB [0..255] Y [16..235] Cb/Cr [16..240] o ITU-R BT.601: Y = (0.257 * R) + (0.504 * G) + (0.098 * B) + 16 Cb = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128 Cr = (0.439 * R) - (0.368 * G) - (0.071 * B) + 128 For fixed point software this becomes Y = 66*R/256 + 129*G/256 + 25*B/256 + 16 Cb = -38*R/256 - 74*G/256 + 112*B/256 + 128 Cr = 112*R/256 - 94*G/256 - 18*B/256 + 128 o ITU-R BT.709: Y = (0.183 * R) + (0.614 * G) + (0.062 * B) + 16 Cb = -(0.101 * R) - (0.339 * G) + (0.439 * B) + 128 Cr = (0.439 * R) - (0.339 * G) - (0.040 * B) + 128 For fixed point software this becomes Y = 47*R/256 + 157*G/256 + 16*B/256 + 16 Cb = -26*R/256 - 87*G/256 + 112*B/256 + 128 Cr = 112*R/256 - 87*G/256 - 10*B/256 + 128 *******************************************************************************/ #define bgfx_csc_BT_601_RGB_2_YCbCr_macro(Y, Cb, Cr, R, G, B) \ { \ Y = ((66*R + 129*G + 25*B) >> 8) + 16; \ Cb = ((-38*R - 74*G + 112*B) >> 8) + 128; \ Cr = ((112*R - 94*G - 18*B) >> 8) + 128; \ } #define bgfx_csc_BT_709_RGB_2_YCbCr_macro(Y, Cb, Cr, R, G, B) \ { \ Y = ((47*R + 157*G + 16*B) >> 8) + 16; \ Cb = ((-26*R - 87*G + 112*B) >> 8) + 128; \ Cr = ((112*R - 87*G - 10*B) >> 8) + 128; \ } #define bgfx_csc_RGB_2_YCbCr_macro_org(At, Y, Cb, Cr, As, R, G, B) \ { \ Y = ((m0*R + m1*G + m2*B + m3*As + m4) >> shift); \ Cb = ((m5*R + m6*G + m7*B + m8*As + m9) >> shift); \ Cr = ((m10*R + m11*G + m12*B + m13*As + m14) >> shift); \ At = ((m15*R + m16*G + m17*B + m18*As + m19) >> shift); \ } #define bgfx_csc_RGB_2_YCbCr_macro(At, Y, Cb, Cr, As, R, G, B) \ { \ Y = ((m0*R + m1*G + m2*B + m4) >> shift); \ Cb = ((m5*R + m6*G + m7*B + m9) >> shift); \ Cr = ((m10*R + m11*G + m12*B + m14) >> shift); \ } /* SW_ANTI_FLUTTER_FILTER_HORIZONTAL */ /* blit row a1 to clut 8 destination */ static inline void bgfx_render_a1_to_clut4( uint8_t *src, uint8_t *dst, int width, uint8_t c, int odd_pixel ) { int i; SGL_TRACE(("%p,%p,%d,0x%02x ",src,dst,width,c)); for (i = 0; i < width; i++) { if (src[i>>3] & (1<<(7-(i%8)))) { if (odd_pixel & 1) { *dst &= 0xF0; *dst |= (c & 0xF); } else { *dst &= 0xF; *dst |= (c & 0xF) << 4; } SGL_TRACE(("%d,",i)); } if (odd_pixel) { odd_pixel = 0; dst++; } else odd_pixel = 1; } SGL_TRACE(("\n")); } /* blit row a8 to clut 8 destination */ static inline void bgfx_render_a8_to_clut4( uint8_t *src, uint8_t *dst, int width, uint8_t c ) { int i; for (i = 0; i < width; i++) { if (*src > 0x80) { if (i & 1) { *dst &= 0xF0; *dst |= (c & 0xF); } else { *dst &= 0xF; *dst |= (c & 0xF) << 4; } } SGL_TRACE(("0x%02x(0x%02x)",*src,*dst)); if (i & 1) dst++; src++; } SGL_TRACE(("\n")); } /* blit row a1 to clut 8 destination */ static inline void bgfx_render_a1_to_clut8( uint8_t *src, uint8_t *dst, int width, uint8_t c ) { int i; SGL_TRACE(("%p,%p,%d,0x%02x ",src,dst,width,c)); for (i = 0; i < width; i++) { if (src[i>>3] & (1<<(7-(i%8)))) { *dst = c; SGL_TRACE(("%d,",i)); } dst++; } SGL_TRACE(("\n")); } /* blit row a8 to clut 8 destination */ static inline void bgfx_render_a8_to_clut8( uint8_t *src, uint8_t *dst, int width, uint8_t c ) { int i; for (i = 0; i < width; i++) { if (*src > 0x80) { *dst = c; } SGL_TRACE(("0x%02x(0x%02x)",*src,*dst)); dst++; src++; } SGL_TRACE(("\n")); } #ifdef CONFIG_BGFX_SURF_RGB #if SOFT_GFX_AS_IN_7003 /* Raymond, GFX convert ARGB input to other graphic format, 20090304 */ static BPXL_Format bgfx_colorformat_mapping(NEXUS_PixelFormat format) { switch(format) { case GRAPHICS_FMT_P4: return BPXL_eP4; case GRAPHICS_FMT_P8: return BPXL_eP8; case GRAPHICS_FMT_ARGB_888: return BPXL_eA8_R8_G8_B8; case GRAPHICS_FMT_RGBA_888: return BPXL_eR8_G8_B8_A8; case GRAPHICS_FMT_RGB_565: return BPXL_eR5_G6_B5; case GRAPHICS_FMT_WRGB_1555: return BPXL_eW1_R5_G5_B5; case GRAPHICS_FMT_RGBW_5551: return BPXL_eR5_G5_B5_W1; case GRAPHICS_FMT_ARGB_4444: return BPXL_eA4_R4_G4_B4; case GRAPHICS_FMT_RGBA_4444: return BPXL_eR4_G4_B4_A4; default: return BPXL_eR5_G6_B5; } } #endif /* blit row a1 to 8888 ARGB destination */ static inline void bgfx_render_a1_to_rgb( uint8_t *src, uint8_t *dst, int width, uint32_t c ) { int i; SGL_TRACE(("%p,%p,%d,0x%02lx ",src,dst,width,c)); for (i = 0; i < width; i++) { if (src[i>>3] & (1<<(7-(i%8)))) { *((uint32_t*)dst) = c; SGL_TRACE(("%d,",i)); } dst += 4; } SGL_TRACE(("\n")); } /* blit row a8 to 8888 ARGB destination */ /* #define SGL_BLEND(a,rs,rd) (((rs * a)/0xFF) + (rd - ((a * rd)/0xFF)) & 0xFF) */ #define SGL_BLEND(a,rs,rd) ((a * (rs-rd) >> 8) + rd) static inline void bgfx_render_a8_to_rgb( uint8_t *src, uint8_t *dst, int width, uint32_t c) { register int i; register uint32_t a,r,g,b; register uint32_t a_src; register uint32_t r_src = (c >> 16) & 0xFF; register uint32_t g_src = (c >> 8) & 0xFF; register uint32_t b_src = (c >> 0) & 0xFF; for (i = 0; i < width; i++) { a_src = *src; a = dst[3]; r = dst[2]; g = dst[1]; b = dst[0]; *((uint32_t*)dst) = (a << 24) | (SGL_BLEND(a_src,r_src,r) << 16) | (SGL_BLEND(a_src,g_src,g) << 8) | SGL_BLEND(a_src,b_src,b); SGL_TRACE(("0x%02x(0x%08x)",*src,*((uint32_t*)dst))); dst += 4; src++; } SGL_TRACE(("\n")); } #endif /****************************************************************} * INPUTS: io and protection function structures * OUTPUTS: none * RETURNS: non-zero on failure * FUNCTION: initialize sgl, primarily for handling freetype * ****************************************************************/ int bgfx_init(bgfx_io_t *io_p,bgfx_prot_t *prot_p) { bgfx_config(io_p,prot_p); return bgfx_font_init(); } /****************************************************************} * INPUTS: none * OUTPUTS: none * RETURNS: non-zero on failure * FUNCTION: release sgl global resources, primarily for handling freetype * ****************************************************************/ void bgfx_done(void) { bgfx_font_done(); } /****************************************************************} * bgfx_create * * INPUTS: node_name - name of the node to create surface in * p - surface structure to initialize * OUTPUTS: none * RETURNS: non-zero on failure * FUNCTION: initialize and create the surface. * ****************************************************************/ #if SOFT_GFX_AS_IN_7003 int bgfx_create(bgfx_surf_p p,uint16_t width,uint16_t height, uint16_t x_pos, uint16_t y_pos, uint8_t *ptr, uint16_t pitch, bgfx_palette_t *palette, uint32_t flags) { /* keep current format */ int format = p->format; BDBG_MSG(("bgfx_create - format = %d ", format)); BDBG_MSG(("bgfx_create - flags = 0x%lx ", flags)); SGL_MEMSET(p,0,sizeof(bgfx_surf_t)); if (!ptr && (flags & BGFX_SURF_PRIMARY)) { SGL_DEBUG(("bgfx_create SGL_SURF_FULLSCREEN requires valid memory ptr. ")); } p->format = format; switch (format) { case GRAPHICS_FMT_ARGB_888: case GRAPHICS_FMT_RGBA_888: case GRAPHICS_FMT_AYCbCr_888: p->bpp = 32; break; case GRAPHICS_FMT_RGB_565: case GRAPHICS_FMT_WRGB_1555: case GRAPHICS_FMT_RGBW_5551: case GRAPHICS_FMT_ARGB_4444: case GRAPHICS_FMT_RGBA_4444: p->bpp = 16; break; case GRAPHICS_FMT_P4: p->bpp = 4; break; case GRAPHICS_FMT_P8: p->bpp = 8; break; default: SGL_DEBUG(("%s: unsupported format %d", __func__, format)); p->bpp = 4; break; } //p->bpp = 4; /* = 8bpp TODO support 4bpp */ p->flags = flags; if (ptr) { p->surface.pitch = pitch; p->surface.buf = ptr; p->surface.width = width; p->surface.height = height; p->surface.x = 0; p->surface.y = 0; } else { p->surface.pitch = width * (p->bpp >> 3); if (p->surface.pitch & 0x1) p->surface.pitch += 1; p->surface.width = width; p->surface.height = height; p->surface.buf = SGL_MALLOC(p->surface.pitch * p->surface.height); p->flags |= BGFX_SURF_ALLOC; p->surface.x = x_pos; p->surface.y = y_pos; } if (palette) { if(p->format == GRAPHICS_FMT_P4) SGL_MEMCPY(&p->palette,palette, sizeof(uint32_t) << 4); else if(p->format == GRAPHICS_FMT_P8) SGL_MEMCPY(&p->palette,palette, sizeof(uint32_t) << 8); //SGL_MEMCPY(&p->palette,palette,sizeof(bgfx_palette_t)); } return 0; } #else int bgfx_create(bgfx_surf_p p,uint16_t width,uint16_t height, uint8_t *ptr, uint16_t pitch, bgfx_palette_t *palette, uint32_t flags) { SGL_MEMSET(p,0,sizeof(bgfx_surf_t)); if (!ptr && (flags & BGFX_SURF_PRIMARY)) { SGL_DEBUG(("bgfx_create SGL_SURF_FULLSCREEN requires valid memory ptr. ")); } p->bpp = 4; /* = 8bpp TODO support 4bpp */ p->flags = flags; if (ptr) { p->surface.pitch = pitch; p->surface.buf = ptr; p->surface.width = width; p->surface.height = height; } else { p->surface.pitch = width * p->bpp / 8; if (p->surface.pitch & 0x1) p->surface.pitch += 1; p->surface.width = width; p->surface.height = height; p->surface.buf = SGL_MALLOC(p->surface.pitch * p->surface.height); p->flags |= BGFX_SURF_ALLOC; } if (palette) { SGL_MEMCPY(&p->palette,palette,sizeof(bgfx_palette_t)); } return 0; } #endif /**************************************************************** * bgfx_destroy * * INPUTS: p - surface structure * OUTPUTS: none * RETURNS: none * FUNCTION: free up surface resources * ****************************************************************/ void bgfx_destroy(bgfx_surf_p p) { if (p->flags & BGFX_SURF_ALLOC) { SGL_FREE(p->surface.buf); p->surface.buf = NULL; return; } } /**************************************************************** * bgfx_get_info * * INPUTS: p - surface structure * OUTPUTS: w,h,flags - surface width,height and flags * RETURNS: none * FUNCTION: Return surface information (width,height, and flags) * ****************************************************************/ void bgfx_get_info(bgfx_surf_p p,uint16_t *w,uint16_t *h,uint16_t *pitch, uint32_t *flags) { *w = p->surface.width; *h = p->surface.height; *pitch = p->surface.pitch; *flags = p->flags; } /**************************************************************** * bgfx_get_palette * * INPUTS: p - surface structure * OUTPUTS: palette_p - return current palette * RETURNS: none * FUNCTION: get the current palett * ****************************************************************/ #if SOFT_GFX_AS_IN_7003 void bgfx_get_palette(bgfx_surf_p p,bgfx_palette_t *palette_p) { if(p->format == GRAPHICS_FMT_P4) SGL_MEMCPY(palette_p,&p->palette, sizeof(uint32_t) << 4); else if(p->format == GRAPHICS_FMT_P8) SGL_MEMCPY(palette_p,&p->palette, sizeof(uint32_t) << 8); // SGL_MEMCPY(palette_p,&p->palette,sizeof(bgfx_palette_t)); } #else void bgfx_get_palette(bgfx_surf_p p,bgfx_palette_t *palette_p) { SGL_MEMCPY(palette_p,&p->palette,sizeof(bgfx_palette_t)); } #endif /**************************************************************** * bgfx_set_palette * * INPUTS: p - surface structure * palette_p - the palette * OUTPUTS: none * RETURNS: none * FUNCTION: set the global system palette * ****************************************************************/ #if SOFT_GFX_AS_IN_7003 void bgfx_set_palette(bgfx_surf_p p, bgfx_palette_t *palette_p) { if(p->format == GRAPHICS_FMT_P4) SGL_MEMCPY(&p->palette,palette_p, sizeof(uint32_t) << 4); else if(p->format == GRAPHICS_FMT_P8) SGL_MEMCPY(&p->palette,palette_p, sizeof(uint32_t) << 8); // SGL_MEMCPY(&p->palette,palette_p,sizeof(bgfx_palette_t)); } #else void bgfx_set_palette(bgfx_surf_p p, bgfx_palette_t *palette_p) { SGL_MEMCPY(&p->palette,palette_p,sizeof(bgfx_palette_t)); } #endif /**************************************************************** * bgfx_set_pixel * * INPUTS: p - surface structure * x,y - coordinates * c - pixel value * OUTPUTS: none * RETURNS: none * FUNCTION: set the pixel at x,y * ****************************************************************/ #if SOFT_GFX_AS_IN_7003 void bgfx_set_pixel(bgfx_surf_p p,uint16_t x,uint16_t y,bgfx_pixel c) { uint8_t *dst; #ifdef CONFIG_SGL_DEBUG if ((x >= p->surface.width) || (y >= p->surface.height)) { SGL_DEBUG(("bgfx_set_pixel param error (%p,%d,%d) ",p,x,y)); return; } #endif dst = (uint8_t*)p->surface.buf; dst += y * p->surface.pitch + x * (p->bpp >> 3); #ifdef CONFIG_BGFX_SURF_RGB if (p->flags & BGFX_SURF_RGB) { /* if RGB palette palette */ if (p->bpp <= 8) { /* make sure size of palette match if CLUT 8 is used */ *((uint32_t*)dst) = bgfx_clut8_to_rgb(p->palette.clut,c); bgfx_cacheflush(dst,4); } else if (32 == p->bpp){ *((uint32_t*)dst) = c; bgfx_cacheflush(dst, (p->bpp >> 3)); } else { /* For 16bit color format, Raymond, 20090304 */ uint16_t c16; c = BPXL_MAKE_PIXEL(bgfx_colorformat_mapping(p->format), c>>24, (c>>16)&0xff, (c>>8)&0xff, c&0xff); c16 = (c & 0xffff); *((uint16_t*)dst) = c16; bgfx_cacheflush(dst, (p->bpp >> 3)); return; } } else #endif { /* AYUV P4 */ if(p->format == GRAPHICS_FMT_P4) { if (x & 1) { *dst &= 0xF0; *dst |= (c & 0xF); } else { *dst &= 0xF; *dst |= (c & 0xF) << 4; } } else if(p->format == GRAPHICS_FMT_P8) { *dst &= 0x00; *dst |= (c & 0xFF); } bgfx_cacheflush(dst,1); } } void bgfx_set_pixel_direct(bgfx_surf_p p,uint16_t x,uint16_t y,bgfx_pixel c) { uint8_t *dst; #ifdef CONFIG_SGL_DEBUG if ((x >= p->surface.width) || (y >= p->surface.height)) { SGL_DEBUG(("bgfx_set_pixel param error (%p,%d,%d) ",p,x,y)); return; } #endif dst = (uint8_t*)p->surface.buf; dst += y * p->surface.pitch + x * (p->bpp >> 3); #ifdef CONFIG_BGFX_SURF_RGB if (p->flags & BGFX_SURF_RGB) { /* if RGB palette palette */ if (p->bpp <= 8) { /* make sure size of palette match if CLUT 8 is used */ *((uint32_t*)dst) = bgfx_clut8_to_rgb(p->palette.clut,c); bgfx_cacheflush(dst,4); } else if (32 == p->bpp){ *((uint32_t*)dst) = c; bgfx_cacheflush(dst, (p->bpp >> 3)); } else { /* For 16bit color format, Raymond, 20090304 */ uint16_t c16; c16 = (c & 0xffff); *((uint16_t*)dst) = c16; bgfx_cacheflush(dst, (p->bpp >> 3)); return; } } else #endif { /* AYUV P4 */ if(p->format == GRAPHICS_FMT_P4) { if (x & 1) { *dst &= 0xF0; *dst |= (c & 0xF); } else { *dst &= 0xF; *dst |= (c & 0xF) << 4; } } else if(p->format == GRAPHICS_FMT_P8) { *dst &= 0x00; *dst |= (c & 0xFF); } bgfx_cacheflush(dst,1); } } #else void bgfx_set_pixel(bgfx_surf_p p,uint16_t x,uint16_t y,bgfx_pixel c) { uint8_t *dst; if ((x >= p->surface.width) || (y >= p->surface.height)) { SGL_DEBUG(("bgfx_set_pixel param error (%p,%d,%d) ",p,x,y)); return; } dst = (uint8_t*)p->surface.buf; dst += y * p->surface.pitch + (x * p->bpp)/8; #ifdef CONFIG_BGFX_SURF_RGB if (p->flags & BGFX_SURF_RGB) { *((uint32_t*)dst) = bgfx_clut8_to_rgb(p->palette.clut,c); bgfx_cacheflush(dst,4); } else #endif { if (x & 1) { *dst &= 0xF0; *dst |= (c & 0xF); } else { *dst &= 0xF; *dst |= (c & 0xF) << 4; } bgfx_cacheflush(dst,1); } } #endif /**************************************************************** * bgfx_get_pixel * * INPUTS: p - surface structure * x,y - coordinates * c - pixel value * OUTPUTS: none * RETURNS: none * FUNCTION: get the pixel value at x,y. The bgfx_color will be the * actual pixel value. * * NOTE: Not supported for RGB surfaces. To get a pixel for RGB access buf * directly. * ****************************************************************/ #if SOFT_GFX_AS_IN_7003 bgfx_pixel bgfx_get_pixel(bgfx_surf_p p,uint16_t x,uint16_t y) { uint8_t *dst; #ifdef CONFIG_SGL_DEBUG if ((x >= p->surface.width) || (y >= p->surface.height)) { SGL_DEBUG(("bgfx_get_pixel param error (%p,%d,%d) ",p,x,y)); return 0; } #endif dst = (uint8_t*)p->surface.buf; dst += y * p->surface.pitch + x * (p->bpp >> 3); #ifdef CONFIG_BGFX_SURF_RGB /* let application to check 16 or 32 bits? */ if (p->flags & BGFX_SURF_RGB) return *((uint32_t*)dst); #endif if (x & 1) { return (*dst & 0xF0); } return (*dst >> 4); } bgfx_pixel bgfx_get_pixel_from_buffer(uint8_t format, uint16_t src_w, uint16_t src_h, uint32_t des_x, uint32_t des_y, void *pbuffer) { uint16_t pitch; uint8_t bpp; BSTD_UNUSED(src_h); switch(format) { case GRAPHICS_FMT_ARGB_888: case GRAPHICS_FMT_RGBA_888: bpp = 32; pitch = src_w * (bpp >> 3); return (bgfx_pixel)(*(uint32_t *)((uint8_t *)pbuffer + des_y * pitch + des_x * (bpp >> 3))); case GRAPHICS_FMT_RGB_565: case GRAPHICS_FMT_WRGB_1555: case GRAPHICS_FMT_RGBW_5551: case GRAPHICS_FMT_ARGB_4444: case GRAPHICS_FMT_RGBA_4444: bpp = 16; pitch = src_w * (bpp >> 3); return (bgfx_pixel)(*(uint16_t *)((uint8_t *)pbuffer + des_y * pitch + des_x * (bpp >> 3))); case GRAPHICS_FMT_P4: case GRAPHICS_FMT_P8: default: SGL_DEBUG(("Unsupported format. ")); break; } return -1; } #else bgfx_pixel bgfx_get_pixel(bgfx_surf_p p,uint16_t x,uint16_t y) { uint8_t *dst; if ((x >= p->surface.width) || (y >= p->surface.height)) { SGL_DEBUG(("bgfx_get_pixel param error (%p,%d,%d) ",p,x,y)); return 0; } dst = (uint8_t*)p->surface.buf; dst += y * p->surface.pitch + (x * p->bpp)/8; #ifdef CONFIG_BGFX_SURF_RGB if (p->flags & BGFX_SURF_RGB) return *((uint32_t*)dst); #endif if (x & 1) { return (*dst & 0xF0); } return (*dst >> 4); } #endif /**************************************************************** * bgfx_h_draw_line * * INPUTS: p - surface structure * x1,x2,y - coordinates * c - pixel value * OUTPUTS: none * RETURNS: none * FUNCTION: Draw a horizontal line make of pixels defined by the value c. * * JPF - these need to be optimized * ****************************************************************/ void bgfx_h_draw_line(bgfx_surf_p p,uint16_t x1,uint16_t x2,uint16_t y, bgfx_pixel c) { #if 1 int w = x2 - x1; if (w < 0) { w = -w; bgfx_fill_rect(p,x2,y,(uint16_t)w,1, c); } else { bgfx_fill_rect(p,x1,y,(uint16_t)w,1, c); } #else uint8_t *dst; uint16_t w = x2 - x1; uint16_t off; if ((x2 <= x1) || (y >= p->surface.height)) { SGL_DEBUG(("bgfx_h_draw_line param error (%p,%d,%d,%d,0x%02lx) ",p,x1,x2,y,c)); return; } if (w > p->surface.width - x1) w = p->surface.width - x1; dst = (uint8_t*)p->surface.buf; dst += (y * p->surface.pitch) + (x1 * p->bpp)/8; #ifdef CONFIG_BGFX_SURF_RGB if (p->flags & BGFX_SURF_RGB) { uint32_t c32 = bgfx_clut8_to_rgb(p->palette.clut,c); while (w--) { *((uint32_t*)dst) = c32; dst += p->bpp/8; } } else #endif { while (w--) { off = (w * p->bpp)/8; if (w & 1) { dst[off] &= 0xF0; dst[off] |= (c & 0xF); } else { dst[off] &= 0xF; dst[off] |= (c & 0xF) << 4; } } } bgfx_cacheflush(p->surface.buf,p->surface.pitch * p->surface.height); #endif } /**************************************************************** * bgfx_v_draw_line * * INPUTS: p - surface structure * x,y1,y2 - coordinates * c - pixel value * OUTPUTS: none * RETURNS: none * FUNCTION: Draw a vertical line make of pixels defined by the value c. * * JPF - these need to be optimized * ****************************************************************/ #if SOFT_GFX_AS_IN_7003 void bgfx_v_draw_line(bgfx_surf_p p,uint16_t x,uint16_t y1,uint16_t y2, bgfx_pixel c) { uint8_t *dst; uint16_t h = y2 - y1; if ((y2 <= y1) || (x >= p->surface.width)) { SGL_DEBUG(("bgfx_v_draw_line param error (%p,%d,%d,%d,0x%02lx) ",p,x,y1,y2,c)); return; } if (h > p->surface.height - y1) h = p->surface.height - y1; dst = (uint8_t*)p->surface.buf; dst += y1 * p->surface.pitch + x * (p->bpp >> 3); #ifdef CONFIG_BGFX_SURF_RGB if (p->flags & BGFX_SURF_RGB) { uint32_t c32; /* Raymond, GFX convert ARGB input to other graphic format, 20090304 */ if (p->bpp <= 8) c32 = bgfx_clut8_to_rgb(p->palette.clut,c); else if (32 == p->bpp) c32 = (uint32_t)c; else { /* For 16bit color format, Raymond, 20090304 */ uint16_t c16; c = BPXL_MAKE_PIXEL(bgfx_colorformat_mapping(p->format), c>>24, (c>>16)&0xff, (c>>8)&0xff, c&0xff); c16 = (c & 0xffff); while (h--) { *((uint16_t*)dst) = c16; dst += p->surface.pitch; } bgfx_cacheflush(p->surface.buf,p->surface.pitch * p->surface.height); return; } while (h--) { *((uint32_t*)dst) = c32; dst += p->surface.pitch; } } else #endif { while (h--) { /* AYUV P4 */ if(p->format == GRAPHICS_FMT_P4) { if (x & 1) { *dst &= 0xF0; *dst |= (c & 0xF); } else { *dst &= 0xF; *dst |= (c & 0xF) << 4; } } else if(p->format == GRAPHICS_FMT_P8) { *dst &= 0x00; *dst |= (c & 0xFF); } dst += p->surface.pitch; } } bgfx_cacheflush(p->surface.buf,p->surface.pitch * p->surface.height); } #else void bgfx_v_draw_line(bgfx_surf_p p,uint16_t x,uint16_t y1,uint16_t y2, bgfx_pixel c) { uint8_t *dst; uint16_t h = y2 - y1; if ((y2 <= y1) || (x >= p->surface.width)) { SGL_DEBUG(("bgfx_v_draw_line param error (%p,%d,%d,%d,0x%02lx) ",p,x,y1,y2,c)); return; } if (h > p->surface.height - y1) h = p->surface.height - y1; dst = (uint8_t*)p->surface.buf; dst += y1 * p->surface.pitch + x * p->bpp/8; #ifdef CONFIG_BGFX_SURF_RGB if (p->flags & BGFX_SURF_RGB) { uint32_t c32 = bgfx_clut8_to_rgb(p->palette.clut,c); while (h--) { *((uint32_t*)dst) = c32; dst += p->surface.pitch; } } else #endif { while (h--) { if (x & 1) { *dst &= 0xF0; *dst |= (c & 0xF); } else { *dst &= 0xF; *dst |= (c & 0xF) << 4; } dst += p->surface.pitch; } } bgfx_cacheflush(p->surface.buf,p->surface.pitch * p->surface.height); } #endif /**************************************************************** * bgfx_fill_rect * * INPUTS: p - surface structure * x1,x2,y1,y2 - coordinates * c - pixel value * OUTPUTS: none * RETURNS: none * FUNCTION: Fill the rectangle with pixels defined by the value c. * * JPF - these need to be optimized * ****************************************************************/ /* TODO create optimized version of memset */ #if 0 static inline void *bgfx_memset(void *dest,int c,size_t count) { uint8_t *d = dest; for(;count>0;count--) { *d++ = c; } return dest; } #else #define bgfx_memset memset #endif #if SOFT_GFX_AS_IN_7003 void bgfx_fill_rect(bgfx_surf_p p,uint16_t x,uint16_t y,uint16_t w,uint16_t h, bgfx_pixel c) { #if 0 bgfx_fill_rect(p->fd,p->psurface[p->surf_idx],x,y,w,h,bgfx_clut8_to_rgb(p->palette.clut,c)); #else #ifdef CONFIG_BGFX_SURF_RGB uint8_t *tdst; uint16_t i; #endif uint8_t *dst; uint16_t j; /* printf("-----surface buffer addr: %lx, X: %d, Y:%d, Width:%d, Height:%d----- ", p->surface.buf, x, y, w, h); */ if (y + h > p->surface.height) h = p->surface.height - y; if (w + x > p->surface.width) w = p->surface.width - x; dst = (uint8_t*)p->surface.buf; dst += y * p->surface.pitch + x * (p->bpp >> 3); #ifdef CONFIG_BGFX_SURF_RGB if (p->flags & BGFX_SURF_RGB) { uint32_t c32; if (p->bpp <= 8) c32 = bgfx_clut8_to_rgb(p->palette.clut,c); else if (32 == p->bpp) c32 = (uint32_t)c; else { /* Raymond, GFX convert ARGB input to other graphic format, 20090304 */ uint16_t c16; c = BPXL_MAKE_PIXEL(bgfx_colorformat_mapping(p->format), c>>24, (c>>16)&0xff, (c>>8)&0xff, c&0xff); c16 = (c & 0xffff); for (j = 0; j < h; ++j) { tdst = dst; for (i = 0; i < w; ++i) { *((uint16_t*)tdst) = c16; tdst += 2; } dst += p->surface.pitch; } bgfx_cacheflush(p->surface.buf,p->surface.pitch * p->surface.height); return; } #if NON_OPTIMIZED for (j = 0; j < h; ++j) { tdst = dst; for (i = 0; i < w; ++i) { *((uint32_t*)tdst) = c32; tdst += (p->bpp >> 3); } dst += p->surface.pitch; } #else tdst = dst; uint8_t *tmp_line = dst; for (i = 0; i < w; ++i) { *((uint32_t*)tdst) = c32; tdst += 4; } dst += p->surface.pitch; for (j = 1; j < h; ++j) { tdst = dst; memcpy((void *)tdst, (const void*)tmp_line, w*4); dst += p->surface.pitch; } #endif bgfx_cacheflush(p->surface.buf,p->surface.pitch * p->surface.height); } else #endif { unsigned char two_pixel = 0; if(p->format == GRAPHICS_FMT_P4) two_pixel = (c << 4) | c; else if(p->format == GRAPHICS_FMT_P8) two_pixel = (c & 0xFF); for (j = 0; j < h; ++j) { unsigned int num_bytes = w * (p->bpp >> 3); //printf("\n****two_pixel=%x,num_bytes=%d, j=%d****\n",two_pixel,num_bytes,j); if(p->format == GRAPHICS_FMT_P4) { if (x & 1) { *dst &= 0xF0; *dst |= (c & 0xF); if (w & 1) { bgfx_memset(&dst[1],two_pixel,num_bytes); } else { bgfx_memset(&dst[1],two_pixel,num_bytes - 1); dst[num_bytes] &= 0x0F; dst[num_bytes] |= (c & 0xF) << 4; } } else { if (w & 1) { bgfx_memset(dst,two_pixel,num_bytes); dst[num_bytes] &= 0x0F; dst[num_bytes] |= (c & 0xF) << 4; } else bgfx_memset(dst,two_pixel,num_bytes); } } else if(p->format == GRAPHICS_FMT_P8) { bgfx_memset(dst,two_pixel,num_bytes); } dst += p->surface.pitch; } } bgfx_cacheflush(p->surface.buf,p->surface.pitch * p->surface.height); #endif } #else void bgfx_fill_rect(bgfx_surf_p p,uint16_t x,uint16_t y,uint16_t w,uint16_t h, bgfx_pixel c) { #if 0 bgfx_fill_rect(p->fd,p->psurface[p->surf_idx],x,y,w,h,bgfx_clut8_to_rgb(p->palette.clut,c)); #else #ifdef CONFIG_BGFX_SURF_RGB uint8_t *tdst; uint16_t i; #endif uint8_t *dst; uint16_t j; if (y + h > p->surface.height) h = p->surface.height - y; if (w + x > p->surface.width) w = p->surface.width - x; dst = (uint8_t*)p->surface.buf; dst += y * p->surface.pitch + x * p->bpp/8; #ifdef CONFIG_BGFX_SURF_RGB if (p->flags & BGFX_SURF_RGB) { uint32_t c32 = bgfx_clut8_to_rgb(p->palette.clut,c); for (j = 0; j < h; ++j) { tdst = dst; for (i = 0; i < w; ++i) { *((uint32_t*)tdst) = c32; tdst += p->bpp/8; } dst += p->surface.pitch; } } else #endif { unsigned char two_pixel = (c << 4) | c; for (j = 0; j < h; ++j) { unsigned int num_bytes = (w * p->bpp)/8; if (x & 1) { *dst &= 0xF0; *dst |= (c & 0xF); if (w & 1) { bgfx_memset(&dst[1],two_pixel,num_bytes); } else { bgfx_memset(&dst[1],two_pixel,num_bytes - 1); dst[num_bytes] &= 0x0F; dst[num_bytes] |= (c & 0xF) << 4; } } else { if (w & 1) { bgfx_memset(dst,two_pixel,num_bytes); dst[num_bytes] &= 0x0F; dst[num_bytes] |= (c & 0xF) << 4; } else bgfx_memset(dst,two_pixel,num_bytes); } dst += p->surface.pitch; } } bgfx_cacheflush(p->surface.buf,p->surface.pitch * p->surface.height); #endif } #endif /**************************************************************** * bgfx_render_glyph * * INPUTS: p - surface structure * x,y - coordinates * a_char - character to render * font_p - font definition * c - color * OUTPUTS: none * RETURNS: character advance * FUNCTION: Fill the rectangle with pixels defined by the value c. * ****************************************************************/ #define IT_OFFSET 3 #if SOFT_GFX_AS_IN_7003 static inline int bgfx_render_glyph(bgfx_surf_p p,uint16_t x,uint16_t y, const unsigned long a_char, bgfx_font_t *font_p,bgfx_pixel c, bgfx_glyph_t * p_bgfx_glyph,bgfx_text_style style) { int max_width,ybase; uint16_t row; uint8_t *src,*dst; bgfx_glyph_t * bgfx_glyph = p_bgfx_glyph; unsigned char glyph_width; /* width of the rendered character bitmap in pixels */ unsigned char glyph_height; /* height of the rendered character bitmap in pixels */ ybase = y; if (x > p->surface.width) { SGL_TRACE(("bgfx_render_glyph x > width (%d,%d) ",x,p->surface.width)); return 0; } /* if using glyph cache use the get glyph rather than render directly to surface buffer */ if (!bgfx_glyph && (font_p->cache_size > 0)) { bgfx_glyph = bgfx_get_glyph(font_p,a_char); } if (!bgfx_glyph) { SGL_DEBUG(("bgfx_render_glyph could not load glyph 0x%08lx ",a_char)); return 0; } SGL_TRACE(("bgfx_render_glyph glyph (%p,%d,%d) ",bgfx_glyph->buf,bgfx_glyph->height,bgfx_glyph->width)); glyph_width = bgfx_glyph->width; glyph_height = bgfx_glyph->height; if (bgfx_glyph->left + x > 0) x += bgfx_glyph->left; if (y-bgfx_glyph->top > 0) y -= bgfx_glyph->top; else y = 0; if (glyph_height + y > p->surface.height) glyph_height = p->surface.height - y; if (glyph_width + x > p->surface.width) glyph_width = p->surface.width - x; src = (uint8_t*)bgfx_glyph->buf; dst = (uint8_t*)p->surface.buf; SGL_TRACE(("bgfx_render_glyph suface (%p(y = %d,x = %d,pitch = %d,bpp = %d) ",dst,y,x,p->surface.pitch, p->bpp)); dst += y * p->surface.pitch + x * p->bpp/8; if (style & eBGFX_ITALIC) max_width = BGFX_MIN(glyph_width + IT_OFFSET, p->surface.width - x); else max_width = BGFX_MIN(glyph_width, p->surface.width - x); if (max_width <= 0) { if (glyph_width != 0) { SGL_TRACE(("bgfx_render_glyph glyph_width = %d ", glyph_width)); } return bgfx_glyph->advance; } /* Render mono glyph */ if (font_p->format & SGL_MONO) { SGL_TRACE(("bgfx_render_glyph Alpha 1 font ")); #ifdef CONFIG_BGFX_SURF_RGB if (p->flags & BGFX_SURF_RGB) { uint32_t c32; uint16_t c16 = (c & 0xffff); if (p->bpp <= 8) c32 = bgfx_clut8_to_rgb(p->palette.clut,c); else { if (32 == p->bpp) c32 = c; //else // c16 = (c & 0xffff); } if (p->bpp <= 8) { for (row = 0; row < glyph_height; row++) { bgfx_render_a1_to_rgb( src, dst, max_width,c32 ); src += bgfx_glyph->pitch; dst += p->surface.pitch; } } else if (32 == p->bpp) { for (row = 0; row < glyph_height; row++) { *(uint32_t *)dst = c32; src += bgfx_glyph->pitch; dst += p->surface.pitch; } } else { for (row = 0; row < glyph_height; row++) { *(uint16_t *)dst = c16; src += bgfx_glyph->pitch; dst += p->surface.pitch; } } } else #endif { uint16_t adjx = x; for (row = 0; row < glyph_height; row++) { if (style & eBGFX_ITALIC) { adjx = x + IT_OFFSET - ((row * IT_OFFSET)/glyph_height); dst = (uint8_t*)p->surface.buf; dst += (y + row) * p->surface.pitch + adjx * (p->bpp >> 3); } bgfx_render_a1_to_clut4( src, dst, max_width,c, adjx & 0x1 ); src += bgfx_glyph->pitch; dst += p->surface.pitch; } } } else /* Render 8 bit grayscale glyph */ { SGL_TRACE(("bgfx_render_glyph Alpha 8 font ")); #ifdef CONFIG_BGFX_SURF_RGB if (p->flags & BGFX_SURF_RGB) { uint32_t c32; uint16_t c16 = (c & 0xffff); if (p->bpp <= 8) c32 = bgfx_clut8_to_rgb(p->palette.clut,c); else { if (32 == p->bpp) c32 = c; //else // c16 = (c & 0xffff); } if (p->bpp <= 8) { for (row = 0; row < glyph_height; row++) { bgfx_render_a8_to_rgb( src, dst, glyph_width,c32); src += bgfx_glyph->pitch; dst += p->surface.pitch; } } else if (32 == p->bpp) { for (row = 0; row < glyph_height; row++) { *(uint32_t *)dst = c32; src += bgfx_glyph->pitch; dst += p->surface.pitch; } } else { for (row = 0; row < glyph_height; row++) { *(uint16_t *)dst = c16; src += bgfx_glyph->pitch; dst += p->surface.pitch; } } } else #endif { for (row = 0; row < glyph_height; row++) { bgfx_render_a8_to_clut4( src, dst, glyph_width,c ); src += bgfx_glyph->pitch; dst += p->surface.pitch; } } } if (style & eBGFX_UNDERLINE) bgfx_h_draw_line(p,x,x + bgfx_glyph->advance,ybase,c); return bgfx_glyph->advance; } #else static inline int bgfx_render_glyph(bgfx_surf_p p,uint16_t x,uint16_t y, const unsigned long a_char, bgfx_font_t *font_p,bgfx_pixel c, bgfx_glyph_t * p_bgfx_glyph,bgfx_text_style style) { int max_width,ybase; uint16_t row; uint8_t *src,*dst; bgfx_glyph_t * bgfx_glyph = p_bgfx_glyph; unsigned char glyph_width; /* width of the rendered character bitmap in pixels */ unsigned char glyph_height; /* height of the rendered character bitmap in pixels */ ybase = y; if (x > p->surface.width) { SGL_TRACE(("bgfx_render_glyph x > width (%d,%d) ",x,p->surface.width)); return 0; } /* if using glyph cache use the get glyph rather than render directly to surface buffer */ if (!bgfx_glyph && (font_p->cache_size > 0)) { bgfx_glyph = bgfx_get_glyph(font_p,a_char); } if (!bgfx_glyph) { SGL_DEBUG(("bgfx_render_glyph could not load glyph 0x%08lx ",a_char)); return 0; } SGL_TRACE(("bgfx_render_glyph glyph (%p,%d,%d) ",bgfx_glyph->buf,bgfx_glyph->height,bgfx_glyph->width)); glyph_width = bgfx_glyph->width; glyph_height = bgfx_glyph->height; if (bgfx_glyph->left + x > 0) x += bgfx_glyph->left; if (y-bgfx_glyph->top > 0) y -= bgfx_glyph->top; else y = 0; if (glyph_height + y > p->surface.height) glyph_height = p->surface.height - y; if (glyph_width + x > p->surface.width) glyph_width = p->surface.width - x; src = (uint8_t*)bgfx_glyph->buf; dst = (uint8_t*)p->surface.buf; SGL_TRACE(("bgfx_render_glyph suface (%p(y = %d,x = %d,pitch = %d,bpp = %d) ",dst,y,x,p->surface.pitch, p->bpp)); dst += y * p->surface.pitch + x * p->bpp/8; if (style & eBGFX_ITALIC) max_width = BGFX_MIN(glyph_width + IT_OFFSET, p->surface.width - x); else max_width = BGFX_MIN(glyph_width, p->surface.width - x); if (max_width <= 0) { if (glyph_width != 0) { SGL_TRACE(("bgfx_render_glyph glyph_width = %d ", glyph_width)); } return bgfx_glyph->advance; } /* Render mono glyph */ if (font_p->format & SGL_MONO) { SGL_TRACE(("bgfx_render_glyph Alpha 1 font ")); #ifdef CONFIG_BGFX_SURF_RGB if (p->flags & BGFX_SURF_RGB) { uint32_t c32 = bgfx_clut8_to_rgb(p->palette.clut,c); for (row = 0; row < glyph_height; row++) { bgfx_render_a1_to_rgb( src, dst, max_width,c32 ); src += bgfx_glyph->pitch; dst += p->surface.pitch; } } else #endif { uint16_t adjx = x; for (row = 0; row < glyph_height; row++) { if (style & eBGFX_ITALIC) { adjx = x + IT_OFFSET - ((row * IT_OFFSET)/glyph_height); dst = (uint8_t*)p->surface.buf; dst += (y + row) * p->surface.pitch + adjx * p->bpp/8; } bgfx_render_a1_to_clut4( src, dst, max_width,c, adjx & 0x1 ); src += bgfx_glyph->pitch; dst += p->surface.pitch; } } } else /* Render 8 bit grayscale glyph */ { SGL_TRACE(("bgfx_render_glyph Alpha 8 font ")); #ifdef CONFIG_BGFX_SURF_RGB if (p->flags & BGFX_SURF_RGB) { uint32_t c32 = bgfx_clut8_to_rgb(p->palette.clut,c); for (row = 0; row < glyph_height; row++) { bgfx_render_a8_to_rgb( src, dst, glyph_width,c32); src += bgfx_glyph->pitch; dst += p->surface.pitch; } } else #endif { for (row = 0; row < glyph_height; row++) { bgfx_render_a8_to_clut4( src, dst, glyph_width,c ); src += bgfx_glyph->pitch; dst += p->surface.pitch; } } } if (style & eBGFX_UNDERLINE) bgfx_h_draw_line(p,x,x + bgfx_glyph->advance,ybase,c); return bgfx_glyph->advance; } #endif /**************************************************************** * bgfx_draw_text * * INPUTS: p - surface structure * x,y - coordinates * str_p - array of 32-bit unicode characters str_len - number of 32-bit characters in array * font_p - font definition * c - color * OUTPUTS: none * RETURNS: none * FUNCTION: Fill the rectangle with pixels defined by the value c. * ****************************************************************/ void bgfx_draw_text(bgfx_surf_p p,uint16_t x,uint16_t y, const unsigned long *str_p, int str_len, bgfx_font_t *font_p,bgfx_pixel c, bgfx_text_style style) { int offset; SGL_TRACE(("bgfx_draw_text %ld characters. ",str_len)); for (offset = 0; offset < str_len; offset++) { x += bgfx_render_glyph(p,x,y, str_p[offset], font_p,c,NULL,style); } bgfx_cacheflush(p->surface.buf,p->surface.pitch * p->surface.height); } /**************************************************************** * bgfx_draw_text_box * * INPUTS: p - surface structure * x,y - coordinates * width,height - width and hegith of the text box to draw * str_p - array of 32-bit unicode characters str_len - number of 32-bit characters in array * font_p - font definition * c - color line_spacing - line space * OUTPUTS: none * RETURNS: none * FUNCTION: Fill the rectangle with pixels defined by the value c. * ****************************************************************/ #define MAX_TEXT_BOX_CHARS 512 #define MAX_LINES 16 static unsigned long s_test_char = 0x00000057UL; /* TODO: Might want to improve macro to check for chars other than spaces */ #define SGL_IS_BREAK(x) ((x == 0x00000020) ? 1 : 0) //#define SGL_VARIABL_LINE_HEIGHT void bgfx_draw_text_box(bgfx_surf_p p,uint16_t x,uint16_t y, uint16_t width, uint16_t height, const unsigned long *str_p, int str_len, bgfx_font_t *font_p,bgfx_pixel c, uint16_t line_spacing) { int offset,bw_off,line_idx; static bgfx_glyph_t * p_bgfx_glyph[MAX_TEXT_BOX_CHARS]; /* Not thread safe */ static uint8_t brk_loc[MAX_TEXT_BOX_CHARS]; uint16_t max_h[MAX_LINES],ch_w,test_max_h,bot; bgfx_glyph_t *p_test_glyph; SGL_TRACE(("bgfx_draw_text_box(%d,%d,%d,%d,%d) %ld characters. ",x,y,width,height,line_spacing,str_len)); if (str_len > MAX_TEXT_BOX_CHARS) { SGL_DEBUG(("bgfx_draw_text %d > %d maximum characters. ",str_len,MAX_TEXT_BOX_CHARS)); str_len = MAX_TEXT_BOX_CHARS; } bot = y + height; p_test_glyph = bgfx_get_glyph(font_p,s_test_char); if (p_test_glyph) test_max_h = p_test_glyph->height; else test_max_h = 0; for (line_idx = 0; line_idx < MAX_LINES; ++line_idx) max_h[line_idx] = test_max_h; ch_w = 0; line_idx = 0; for (offset = 0; offset < str_len; offset++) { brk_loc[offset] = 0; p_bgfx_glyph[offset] = bgfx_get_glyph(font_p,str_p[offset]); if (p_bgfx_glyph[offset] == NULL) { SGL_DEBUG(("%s:%d str[%d] = 0x%08x ",__FUNCTION__,__LINE__,offset,str_p[offset])); /* if not a printable charactor, then use space instead */ p_bgfx_glyph[offset] = bgfx_get_glyph(font_p,0x00000020); continue; } ch_w += p_bgfx_glyph[offset]->advance; if (p_bgfx_glyph[offset]->height > max_h[line_idx]) max_h[line_idx] = p_bgfx_glyph[offset]->height; if (ch_w >= width) { line_idx++; for (bw_off = offset - 1; bw_off >= 0; --bw_off) { if (brk_loc[bw_off]) { bw_off = -1; break; } if (SGL_IS_BREAK(str_p[bw_off])) { brk_loc[bw_off] = 1; break; } } /* last resort, break on preceding character */ if (bw_off < 0) { brk_loc[offset - 1] = 1; ch_w = p_bgfx_glyph[offset]->advance; } else { offset = bw_off; ch_w = 0; } } } /* offset y so text is inside box */ line_idx = 0; #ifdef SGL_VARIABL_LINE_HEIGHT y += max_h[line_idx]; #else y += test_max_h; #endif ch_w = 0; for (offset = 0; (offset < str_len) && (line_idx < MAX_LINES); offset++) { if (brk_loc[offset]) { line_idx++; ch_w = 0; #ifdef SGL_VARIABL_LINE_HEIGHT y += line_spacing + max_h[line_idx]; if ((y - max_h[line_idx]) > bot) break; #else y += line_spacing + test_max_h; if ((y - test_max_h) > bot) break; #endif continue; } ch_w += bgfx_render_glyph(p,x + ch_w,y, str_p[offset], font_p,c,p_bgfx_glyph[offset],eBGFX_NORMAL); } bgfx_cacheflush(p->surface.buf,p->surface.pitch * p->surface.height); } /**************************************************************** * bgfx_render_file * * INPUTS: p - surface structure * x,y - coordinates * file_p - file to get image from * set_palette - use the palette in the file to set the * global palette. * OUTPUTS: none * RETURNS: non-zero on error * FUNCTION: Render the image in the file to the x,y location * ****************************************************************/ #if (SOFT_GFX_AS_IN_7003 == 0) int bgfx_render_file(bgfx_surf_p p,uint16_t x,uint16_t y, void *file_p,int set_palette) { bcm_raw_8_t header; int result = -1; static uint8_t tbuf[SURF_WIDTH]; uint16_t row,rows,rowbytes; uint8_t *dst_ptr; int palette_bytes; #ifdef CONFIG_BGFX_SURF_RGB uint16_t i; uint8_t *r_ptr,*tdst; #endif if (bgfx_read(&header,1,sizeof(header),file_p) == sizeof(header)) { if (header.type != RAW_TYPE || header.version != RAW_VERSION) { SGL_DEBUG(("bgfx_render_file failed version,type invalid(0x%08lx,0x%08lx) ",header.type,header.version)); return -1; } SGL_TRACE(("header.version = 0x%08lx ",header.version)); SGL_TRACE(("header.type = 0x%08lx ",header.type)); SGL_TRACE(("header.clut_size = %d ",header.clut_size)); SGL_TRACE(("header.color_key = 0x%02x ",header.color_key)); SGL_TRACE(("header.pitch = %ld ",header.pitch)); SGL_TRACE(("header.width = 0x%08x ",header.width)); SGL_TRACE(("header.height = 0x%08x ",header.height)); palette_bytes = (sizeof(unsigned long) * header.clut_size); if (bgfx_read(&p->palette,1,palette_bytes,file_p) == palette_bytes) { if (set_palette && (header.clut_size == PALETTE_SIZE)) bgfx_set_palette(p,&p->palette); } if ((header.width == p->surface.width) && (header.height == p->surface.height) && (p->surface.pitch == header.pitch) && (x == 0) && (y == 0) && !(p->flags & BGFX_SURF_RGB)) { SGL_TRACE(("Fast Render ")); bgfx_read(p->surface.buf,1,header.pitch*header.height,file_p); } else if ((p->palette.clut[header.color_key] & 0xFF000000) != 0) { SGL_TRACE(("Render - no color key ")); rowbytes = BGFX_MIN(header.width,p->surface.width - x) * p->bpp/8; rows = BGFX_MIN(header.height, p->surface.height - y); dst_ptr = (uint8_t*)p->surface.buf; dst_ptr += y * p->surface.pitch + x * p->bpp/8; #ifdef CONFIG_BGFX_SURF_RGB if (p->flags & BGFX_SURF_RGB) { for (row = 0; row < rows; row++) { bgfx_read(tbuf ,1,rowbytes,file_p); r_ptr = dst_ptr; for (i = 0; i < rowbytes; ++i) { uint32_t sr,sg,sb,sa,dr,dg,db,da,src_c; src_c = bgfx_clut8_to_rgb(p->palette.clut,tbuf[i]); sa = (src_c >> 24) & 0xFF; if (sa == 0xFF) { *((uint32_t*)r_ptr) = src_c; } else { sr = (src_c >> 16) & 0xFF; sg = (src_c >> 8) & 0xFF; sb = (src_c >> 0) & 0xFF; da = (*((uint32_t*)r_ptr) >> 24) & 0xFF; dr = (*((uint32_t*)r_ptr) >> 16) & 0xFF; dg = (*((uint32_t*)r_ptr) >> 8) & 0xFF; db = (*((uint32_t*)r_ptr) >> 0) & 0xFF; dr = (((sr * sa)/0xFF) & 0xFF) + ((((0xFF - sa) * dr)/0xFF) & 0xFF); dg = (((sg * sa)/0xFF) & 0xFF) + ((((0xFF - sa) * dg)/0xFF) & 0xFF); db = (((sb * sa)/0xFF) & 0xFF) + ((((0xFF - sa) * db)/0xFF) & 0xFF); *((uint32_t*)r_ptr) = (da << 24) | (dr << 16) | (dg << 8) | db; } r_ptr += p->bpp/8; } if (header.pitch > rowbytes) { bgfx_read(tbuf ,1,header.pitch - rowbytes,file_p); } dst_ptr += p->surface.pitch; } } else #endif { for (row = 0; row < rows; row++) { bgfx_read(dst_ptr ,1,rowbytes,file_p); if (header.pitch > rowbytes) { bgfx_read(tbuf ,1,header.pitch - rowbytes,file_p); } dst_ptr += p->surface.pitch; } } } else { SGL_TRACE(("Render - color key ")); rowbytes = BGFX_MIN(header.width,(p->surface.width - x)) * p->bpp/8; rows = BGFX_MIN(header.height, (p->surface.height - y)); dst_ptr = (uint8_t*)p->surface.buf; dst_ptr += y * p->surface.pitch + x * p->bpp/8; #ifdef CONFIG_BGFX_SURF_RGB if (p->flags & BGFX_SURF_RGB) { for (row = 0; row < rows; row++) { bgfx_read(tbuf ,1,rowbytes,file_p); r_ptr = dst_ptr; for (i = 0; i < rowbytes; ++i) { if (tbuf[i] != header.color_key) { uint32_t sr,sg,sb,sa,dr,dg,db,da,src_c; src_c = bgfx_clut8_to_rgb(p->palette.clut,tbuf[i]); sa = (src_c >> 24) & 0xFF; if (sa == 0xFF) { *((uint32_t*)r_ptr) = src_c; } else { sr = (src_c >> 16) & 0xFF; sg = (src_c >> 8) & 0xFF; sb = (src_c >> 0) & 0xFF; da = (*((uint32_t*)r_ptr) >> 24) & 0xFF; dr = (*((uint32_t*)r_ptr) >> 16) & 0xFF; dg = (*((uint32_t*)r_ptr) >> 8) & 0xFF; db = (*((uint32_t*)r_ptr) >> 0) & 0xFF; dr = (((sr * sa)/0xFF) & 0xFF) + ((((0xFF - sa) * dr)/0xFF) & 0xFF); dg = (((sg * sa)/0xFF) & 0xFF) + ((((0xFF - sa) * dg)/0xFF) & 0xFF); db = (((sb * sa)/0xFF) & 0xFF) + ((((0xFF - sa) * db)/0xFF) & 0xFF); *((uint32_t*)r_ptr) = (da << 24) | (dr << 16) | (dg << 8) | db; } } r_ptr += p->bpp/8; } if (header.pitch > rowbytes) { bgfx_read(tbuf ,1,header.pitch - rowbytes,file_p); } dst_ptr += p->surface.pitch; } } else #endif { for (row = 0; row < rows; row++) { bgfx_read(dst_ptr ,1,rowbytes,file_p); if (header.pitch > rowbytes) { bgfx_read(tbuf ,1,header.pitch - rowbytes,file_p); } dst_ptr += p->surface.pitch; } } } } SGL_TRACE(("Render - done ")); bgfx_cacheflush(p->surface.buf,p->surface.pitch * p->surface.height); result = 0; return result; } #else /* Raymond, BGFX support rendering RGB 24bit bitmap, 20090305 */ static uint32_t read_24(void *fin) { int b1, b2, b3; bgfx_read(&b1,1,1,fin); bgfx_read(&b2,1,1,fin); bgfx_read(&b3,1,1,fin); return (uint32_t) ( (b1&0xFF) | ((b2&0xFF)<<8) | ((b3&0xFF)<<16) ); } int bgfx_render_file(bgfx_surf_p p, uint16_t src_w, uint16_t src_h, int16_t des_x, int16_t des_y, void *file_p) { int16_t x, y; for(y=des_y + src_h- 1;y>=des_y;y--) { for(x=des_x;x> 7) & 0xf8; c24_g = (c16 >> 2) & 0xf8; c24_b = (c16 << 3) & 0xf8; c24 = (c24_r << 16) | (c24_g << 8) | (c24_b); if(c16 & 0x8000) /* alpha */ c24 = c24 | (0xff << 24); break; case GRAPHICS_FMT_ARGB_888: /* ARGB8888 */ b1 = *p8++; b2 = *p8++; b3 = *p8++; b4 = *p8++; c24 = (uint32_t) ( (b1&0xFF) | ((b2&0xFF)<<8) | ((b3&0xFF)<<16) | (b4%0xff)<<24); break; case GRAPHICS_FMT_RGBW_5551: /* TODO */ case GRAPHICS_FMT_ARGB_4444: /* TODO */ case GRAPHICS_FMT_RGBA_4444: /* TODO */ case GRAPHICS_FMT_P4: /* TODO */ case GRAPHICS_FMT_P8: /* TODO */ case GRAPHICS_FMT_RGBA_888: /* TODO */ case GRAPHICS_FMT_RGB_565: /* TODO */ default: SGL_DEBUG(("Unsupported format. ")); break; } bgfx_set_pixel(p, x, y, c24); } } return 0; } #endif /**************************************************************** * bgfx_blit * * INPUTS: p_src,p_dst - surface structure * x,y - destination coordinates * OUTPUTS: none * RETURNS: non-zero on error * FUNCTION: Blit between the two surfaces, only the destination can be RGB * ****************************************************************/ #if SOFT_GFX_AS_IN_7003 int bgfx_blit(bgfx_surf_p p_src, bgfx_surf_p p_dst, uint16_t x,uint16_t y) { uint8_t *dst,*src; uint16_t j,w,h,rowbytes; #ifdef CONFIG_BGFX_SURF_RGB uint16_t i; uint8_t *tdst; #endif SGL_TRACE(("bgfx_blit x,y (%d,%d) ",x,y)); if ((x > p_dst->surface.width) || (y > p_dst->surface.height)) { SGL_DEBUG(("bgfx_blit x,y (%d,%d) outside destination (%d,%d) ",x,y, p_dst->surface.width,p_dst->surface.height)); return -1; } w = p_src->surface.width; if (w > p_dst->surface.width - x) w = p_dst->surface.width - x; h = p_src->surface.height; if (h > p_dst->surface.height - y) h = p_dst->surface.height - y; src = (uint8_t*)p_src->surface.buf; dst = (uint8_t*)p_dst->surface.buf; dst += y * p_dst->surface.pitch + x * (p_dst->bpp >> 3); #ifdef CONFIG_BGFX_SURF_RGB if (p_dst->flags & BGFX_SURF_RGB) { for (j = 0; j < h; ++j) { tdst = dst; /* assume that destination and source format should be same */ if (p_dst->bpp <= 8) { for (i = 0; i < w; ++i) { if (src[i] != 0xFF) *((uint32_t*)tdst) = bgfx_clut8_to_rgb(p_src->palette.clut,src[i]); tdst += (p_dst->bpp >> 3); } } else if (32 == p_dst->bpp) { for (i = 0; i < (w << 2); i += 4, tdst += 4) { *((uint32_t*)tdst) = *(uint32_t *)&src[i]; } } else { for (i = 0; i < (w << 1); i += 2, tdst += 2) { *((uint16_t*)tdst) = *(uint16_t *)&src[i]; } } dst += p_dst->surface.pitch; src += p_src->surface.pitch; } } else #endif { rowbytes = BGFX_MIN(p_src->surface.width,p_dst->surface.width - x) * (p_dst->bpp >> 3); for (j = 0; j < h; ++j) { memcpy(dst,src,rowbytes); dst += p_dst->surface.pitch; src += p_src->surface.pitch; } } bgfx_cacheflush(p_dst->surface.buf,p_dst->surface.pitch * p_dst->surface.height); return 0; } #else int bgfx_blit(bgfx_surf_p p_src, bgfx_surf_p p_dst, uint16_t x,uint16_t y) { uint8_t *dst,*src; uint16_t j,w,h,rowbytes; #ifdef CONFIG_BGFX_SURF_RGB uint16_t i; uint8_t *tdst; #endif SGL_TRACE(("bgfx_blit x,y (%d,%d) ",x,y)); if ((x > p_dst->surface.width) || (y > p_dst->surface.height)) { SGL_DEBUG(("bgfx_blit x,y (%d,%d) outside destination (%d,%d) ",x,y, p_dst->surface.width,p_dst->surface.height)); return -1; } w = p_src->surface.width; if (w > p_dst->surface.width - x) w = p_dst->surface.width - x; h = p_src->surface.height; if (h > p_dst->surface.height - y) h = p_dst->surface.height - y; src = (uint8_t*)p_src->surface.buf; dst = (uint8_t*)p_dst->surface.buf; dst += y * p_dst->surface.pitch + x * p_dst->bpp/8; #ifdef CONFIG_BGFX_SURF_RGB if (p_dst->flags & BGFX_SURF_RGB) { for (j = 0; j < h; ++j) { tdst = dst; for (i = 0; i < w; ++i) { if (src[i] != 0xFF) *((uint32_t*)tdst) = bgfx_clut8_to_rgb(p_src->palette.clut,src[i]); tdst += p_dst->bpp/8; } dst += p_dst->surface.pitch; src += p_src->surface.pitch; } } else #endif { rowbytes = BGFX_MIN(p_src->surface.width,p_dst->surface.width - x) * p_dst->bpp/8; for (j = 0; j < h; ++j) { memcpy(dst,src,rowbytes); dst += p_dst->surface.pitch; src += p_src->surface.pitch; } } bgfx_cacheflush(p_dst->surface.buf,p_dst->surface.pitch * p_dst->surface.height); return 0; } #endif /**************************************************************** * INPUTS: p_src,p_dst - source and destination buffer pointers * sx * dx * w - width * OUTPUTS: none * RETURNS: non-zero on error * FUNCTION: Blit a region of one surface to another (for 4 bpp ) * ****************************************************************/ static inline void bgfx_row_copy(unsigned char *src, unsigned char *dst, uint16_t sx,uint16_t dx,uint16_t w) { unsigned int num_bytes = (w * 4)/8; int pix; if (sx & 1) { if (dx & 1) { *dst &= 0xF0; *dst |= (*src & 0xF); if (w & 1) { memcpy(&dst[1],&src[1],num_bytes); } else { memcpy(&dst[1],&src[1],num_bytes - 1); dst[num_bytes] &= 0x0F; dst[num_bytes] |= (src[num_bytes] & 0xF0); } } else { for (pix = 0; pix < w; ++pix) { if (pix & 1) { *dst &= 0xF0; *dst |= (*src & 0xF0) >> 4; dst++; } else { *dst &= 0x0F; *dst |= (*src & 0xF) << 4; src++; } } } } else { if (dx & 1) { for (pix = 0; pix < w; ++pix) { if (pix & 1) { *dst &= 0x0F; *dst |= (*src & 0xF) << 4; src++; } else { *dst &= 0xF0; *dst |= (*src & 0xF0) >> 4; dst++; } } } else { if (w & 1) { memcpy(dst,src,num_bytes); dst[num_bytes] &= 0x0F; dst[num_bytes] |= (src[num_bytes] & 0xF0); } else { memcpy(dst,src,num_bytes); } } } } /**************************************************************** * INPUTS: p_src,p_dst - source and destination surface structures * sx,sy - source coordinates * dx,dy - destination coordinates * sw,sh - width and height of region * OUTPUTS: none * RETURNS: non-zero on error * FUNCTION: Blit a region of one surface to another * ****************************************************************/ #if SOFT_GFX_AS_IN_7003 int bgfx_blit_rect(bgfx_surf_p p_src, bgfx_surf_p p_dst, uint16_t sx,uint16_t sy, uint16_t dx,uint16_t dy, uint16_t sw,uint16_t sh, bool b_csc, bgfx_color_matrix_p p_csc) { uint8_t *dst,*src; uint16_t j,w,h; #ifdef CONFIG_BGFX_SURF_RGB uint8_t *tdst; int i; #endif if ((dx >= p_dst->surface.width) || (dy >= p_dst->surface.height)) { SGL_DEBUG(("bgfx_blit_rect dst_x,dst_y (%d,%d) outside destination (%d,%d) ",dx,dy, p_dst->surface.width,p_dst->surface.height)); return -1; } if ((sx >= p_src->surface.width) || (sy >= p_src->surface.height)) { SGL_DEBUG(("bgfx_blit_rect src_x,src_y (%d,%d) outside source (%d,%d) ",sx,sy, p_src->surface.width,p_src->surface.height)); return -1; } if (p_dst->format == GRAPHICS_FMT_AYCbCr_888 && p_src->format != GRAPHICS_FMT_ARGB_888) { SGL_DEBUG(("bgfx_blit_rect dst_format=%d src_format=%d",p_dst->format, p_src->format)); SGL_DEBUG(("bgfx_blit_rect dst format YCbCr supported only if src format is ARGB8888")); return -1; } src = (uint8_t*)p_src->surface.buf; src += (sy * p_src->surface.pitch) + (sx * (p_src->bpp >> 3)); dst = (uint8_t*)p_dst->surface.buf; dst += (dy * p_dst->surface.pitch) + (dx * (p_dst->bpp >> 3)); w = sw; if (sw >= (p_src->surface.width - sx)) w= p_src->surface.width - sx; if (w >= p_dst->surface.width - dx) w = p_dst->surface.width - dx; h = sh; if (sh >= (p_src->surface.height - sy)) h= p_src->surface.height - sy; if (h >= p_dst->surface.height - dy) h = p_dst->surface.height - dy; #ifdef CONFIG_BGFX_SURF_RGB if (p_dst->flags & BGFX_SURF_RGB) { for (j = 0; j < h; ++j) { tdst = dst; if (p_dst->bpp <= 8) { for (i = 0; i < w; ++i) { if (src[i] != 0xFF) *((uint32_t*)tdst) = bgfx_clut8_to_rgb(p_src->palette.clut,src[i]); tdst += (p_dst->bpp >> 3); } } else if (32 == p_dst->bpp) { if(b_csc) { if (p_dst->format == GRAPHICS_FMT_AYCbCr_888) { uint32_t rgb, y, cb, cr, a, r, g, b, shift; #define A p_csc->coeffMatrix int32_t m0=A[0], m1=A[1], m2=A[2], m4=A[4]; int32_t m5=A[5], m6=A[6], m7=A[7], m9=A[9]; int32_t m10=A[10], m11=A[11], m12=A[12], m14=A[14]; #undef A shift = p_csc->shift; for (i = 0; i < (w << 2); i += 4, tdst += 4) { rgb = *(uint32_t *)&src[i]; #ifdef COMPARE_PREVIOUS_PIXEL if(i > 0 && rgb == *(uint32_t*)(&src[i-4])) { *((uint32_t*)tdst) = *((uint32_t*)(tdst-4)); } else #endif { a = ((rgb >> 24) & 0xff); r = ((rgb >> 16) & 0xff); g = (rgb >> 8) & 0xff; b = rgb & 0xff; #if 0 bgfx_csc_BT_601_RGB_2_YCbCr_macro(y, cb, cr, r, g, b); *((uint32_t*)tdst) = ((rgb & 0xFF000000) | (y<<16) | (cb<<8) | cr); #else #if 0 bgfx_csc_RGB_2_YCbCr_macro_org(at, y, cb, cr, a, r, g, b); *((uint32_t*)tdst) = ((at<<24) | (y<<16) | (cb<<8) | cr); #else bgfx_csc_RGB_2_YCbCr_macro(at, y, cb, cr, a, r, g, b); *((uint32_t*)tdst) = ((a<<24) | (y<<16) | (cb<<8) | cr); #endif #endif } } //SGL_DEBUG(("RGB (0x%x) -> YCbCr (0x%x)",rgb, ((at<<24) | (y<<16) | (cb<<8) | cr))); } } else { memcpy((void *)tdst, (void *)src, w*4); } } else { for (i = 0; i < (w << 1); i += 2, tdst += 2) { *((uint16_t*)tdst) = *(uint16_t *)&src[i]; } } dst += p_dst->surface.pitch; src += p_src->surface.pitch; } } else #endif { for (j = 0; j < h; ++j) { bgfx_row_copy(src,dst,sx,dx,w); dst += p_dst->surface.pitch; src += p_src->surface.pitch; } } bgfx_cacheflush(p_dst->surface.buf,p_dst->surface.pitch * p_dst->surface.height); return 0; } #else int bgfx_blit_rect(bgfx_surf_p p_src, bgfx_surf_p p_dst, uint16_t sx,uint16_t sy, uint16_t dx,uint16_t dy, uint16_t sw,uint16_t sh) { uint8_t *dst,*src; uint16_t j,w,h; #ifdef CONFIG_BGFX_SURF_RGB uint8_t *tdst; #endif if ((dx >= p_dst->surface.width) || (dy >= p_dst->surface.height)) { SGL_DEBUG(("bgfx_blit_rect dst_x,dst_y (%d,%d) outside destination (%d,%d) ",dx,dy, p_dst->surface.width,p_dst->surface.height)); return -1; } if ((sx >= p_src->surface.width) || (sy >= p_src->surface.height)) { SGL_DEBUG(("bgfx_blit_rect src_x,src_y (%d,%d) outside source (%d,%d) ",sx,sy, p_src->surface.width,p_src->surface.height)); return -1; } src = (uint8_t*)p_src->surface.buf; src += (sy * p_src->surface.pitch) + ((sx * p_src->bpp)/8); dst = (uint8_t*)p_dst->surface.buf; dst += (dy * p_dst->surface.pitch) + ((dx * p_dst->bpp)/8); w = sw; if (sw >= (p_src->surface.width - sx)) w= p_src->surface.width - sx; if (w >= p_dst->surface.width - dx) w = p_dst->surface.width - dx; h = sh; if (sh >= (p_src->surface.height - sy)) h= p_src->surface.height - sy; if (h >= p_dst->surface.height - dy) h = p_dst->surface.height - dy; #ifdef CONFIG_BGFX_SURF_RGB if (p_dst->flags & BGFX_SURF_RGB) { for (j = 0; j < h; ++j) { tdst = dst; for (i = 0; i < w; ++i) { if (src[i] != 0xFF) *((uint32_t*)tdst) = bgfx_clut8_to_rgb(p_src->palette.clut,src[i]); tdst += p_dst->bpp/8; } dst += p_dst->surface.pitch; src += p_src->surface.pitch; } } else #endif { for (j = 0; j < h; ++j) { bgfx_row_copy(src,dst,sx,dx,w); dst += p_dst->surface.pitch; src += p_src->surface.pitch; } } bgfx_cacheflush(p_dst->surface.buf,p_dst->surface.pitch * p_dst->surface.height); return 0; } #endif #if SOFT_GFX_AS_IN_7003 #if 0 /**************************************************************** * INPUTS: src1, src2 - source data pointer * bpp_src1, bpp_src2, bpp_dst - source and destination bits per pixel * fmt_src1, fmt_src2, fmt_dst - source and distination color format * operation - alpha blending mode * alpha1 - specified alpha value for calculating R,G,B blending * alpha2 - specified alpha value for calculating A blending, if it's a bi-alpha format, alpha2 must = 0xff * OUTPUTS: none * RETURNS: pixel value * FUNCTION: Blit a pixel of one surface to another * ****************************************************************/ static int bgfx_blit_pixel(void *src1, void *src2, int bpp_src1, int bpp_src2, int bpp_dst, int fmt_src1, int fmt_src2, int fmt_dst, unsigned int operation, uint8_t alpha1, uint8_t alpha2) { uint32_t rt, gt, bt, at, rs, gs, bs, as; uint32_t p1; uint32_t p2; if(bpp_src1 <= 8 || bpp_src2 <= 8 || bpp_dst <= 8) /* P4 or P8 */ { SGL_DEBUG(("multi surface alpha blending only support RGB surfaces.")); return -1; } if(bpp_src1 == 32) p1 = *(uint32_t *)src1; else /* bpp = 16 */ p1 = (uint32_t)(*(uint16_t *)src1); if(bpp_src2 == 32) p2 = *(uint32_t *)src2; else /* bpp = 16 */ p2 = (uint32_t)(*(uint16_t *)src2); BPXL_ConvertComponent(BPXL_eA8_R8_G8_B8, bgfx_colorformat_mapping(fmt_src1), p1, 2, &rs); BPXL_ConvertComponent(BPXL_eA8_R8_G8_B8, bgfx_colorformat_mapping(fmt_src2), p2, 2, &rt); BPXL_ConvertComponent(BPXL_eA8_R8_G8_B8, bgfx_colorformat_mapping(fmt_src1), p1, 1, &gs); BPXL_ConvertComponent(BPXL_eA8_R8_G8_B8, bgfx_colorformat_mapping(fmt_src2), p2, 1, >); BPXL_ConvertComponent(BPXL_eA8_R8_G8_B8, bgfx_colorformat_mapping(fmt_src1), p1, 0, &bs); BPXL_ConvertComponent(BPXL_eA8_R8_G8_B8, bgfx_colorformat_mapping(fmt_src2), p2, 0, &bt); if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1) { as = alpha1; at = alpha1; } else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC1_ALPHA) { BPXL_ConvertComponent(BPXL_eA8_R8_G8_B8, bgfx_colorformat_mapping(fmt_src1), p1, 3, &as); at = as; } else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC2_ALPHA) { BPXL_ConvertComponent(BPXL_eA8_R8_G8_B8, bgfx_colorformat_mapping(fmt_src2), p2, 3, &at); as = at; } else { BPXL_ConvertComponent(BPXL_eA8_R8_G8_B8, bgfx_colorformat_mapping(fmt_src1), p1, 3, &as); BPXL_ConvertComponent(BPXL_eA8_R8_G8_B8, bgfx_colorformat_mapping(fmt_src2), p2, 3, &at); } SGL_TRACE(("******************** ")); SGL_TRACE((" as=0x%x, rs=0x%x, gs=0x%x, bs=0x%x ", as, rs, gs, bs)); SGL_TRACE((" at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x ", at, rt, gt, bt)); SGL_TRACE(("******************** ")); /* Normal case formula * R = R1 * Alpha1 + R2 * Alpha2 * (1-Alpha1) * G = G1 * Alpha1 + G2 * Alpha2 * (1-Alpha1) * B = B1 * Alpha1 + B2 * Alpha2 * (1-Alpha1) * Alpha = 1 - (1 - Alpha1) * ( 1 - Alpha2) * R = R / Alpha * G = G / Alpha * B = B / Alpha * (0> 8); SGL_TRACE(("******************** ")); SGL_TRACE(("after blend, at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x ", at, rt, gt, bt)); SGL_TRACE(("******************** ")); return BPXL_MAKE_PIXEL(bgfx_colorformat_mapping(fmt_dst), at, rt, gt, bt); } #endif /* Blit rgb from two source pixel with same alpha Formula: dst = (alpha * src + (ALPHA_MAX - alpha) * dst )/ALPHA_MAX Simplified as: dst = (src - dst) * alpha >> (log2 ALPHA_MAX) + dst special for ARGB8888 dst = (alpha * src + (256 - alpha) * dst )/256 Simplified as: dst = (src - dst) * alpha >> 8 + dst */ #define bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, as) \ switch(as) \ { \ case 255: \ rt = rs; \ gt = gs; \ bt = bs; \ break; \ case 128: \ rt = ((rs - rt) >> 1) + rt; \ gt = ((gs - gt) >> 1) + gt; \ bt = ((bs - bt) >> 1) + bt; \ break; \ case 64: \ rt = ((rs - rt) >> 2) + rt; \ gt = ((gs - gt) >> 2) + gt; \ bt = ((bs - bt) >> 2) + bt; \ break; \ case 32: \ rt = ((rs - rt) >> 3) + rt; \ gt = ((gs - gt) >> 3) + gt; \ bt = ((bs - bt) >> 3) + bt; \ break; \ case 16: \ rt = ((rs - rt) >> 4) + rt; \ gt = ((gs - gt) >> 4) + gt; \ bt = ((bs - bt) >> 4) + bt; \ break; \ case 8: \ rt = ((rs - rt) >> 5) + rt; \ gt = ((gs - gt) >> 5) + gt; \ bt = ((bs - bt) >> 5) + bt; \ break; \ case 4: \ rt = ((rs - rt) >> 6) + rt; \ gt = ((gs - gt) >> 6) + gt; \ bt = ((bs - bt) >> 6) + bt; \ break; \ case 2: \ rt = ((rs - rt) >> 7) + rt; \ gt = ((gs - gt) >> 7) + gt; \ bt = ((bs - bt) >> 7) + bt; \ break; \ case 1: \ rt = ((rs - rt) >> 8) + rt; \ gt = ((gs - gt) >> 8) + gt; \ bt = ((bs - bt) >> 8) + bt; \ break; \ case 0: \ break; \ default: \ { \ uint32_t shift = (as >> 8); \ rt += (rs - rt)*shift;/* rt = rs * shift + rt - rt * shift; */ \ gt += (gs - gt)*shift; /* gt = gs * shift + gt - gt * shift; */ \ bt += (bs - bt)*shift;/* bt = bs * shift + bt - bt * shift; */ \ } \ } /* Blit rgb from two source pixel with different alpha * R = R1 * Alpha1 + R2 * Alpha2 * (1-Alpha1) * G = G1 * Alpha1 + G2 * Alpha2 * (1-Alpha1) * B = B1 * Alpha1 + B2 * Alpha2 * (1-Alpha1) * Alpha = 1 - (1 - Alpha1) * ( 1 - Alpha2) * R = R / Alpha * G = G / Alpha * B = B / Alpha * (0> 8); \ gt = (gt >> 8); \ bt = (bt >> 8); \ at = (at >> 8); \ } #else #define bgfx_blit_pixel_different_alphasrc_macro(rt, gt, bt, at, rs, gs, bs, as) \ { \ rt = ((rs * as) << 8) + (256 - as) * rt * at; \ gt = ((gs * as) << 8) + (256 - as) * gt * at; \ bt = ((bs * as) << 8) + (256 - as) * bt * at; \ at = (as << 8) + (at << 8) - as * at; \ rt = rt / at; \ gt = gt / at; \ bt = bt / at; \ at = (at >> 8); \ } #endif #if 0 static int bgfx_blit_pixel_RGB565(void *src1, void *src2, unsigned int operation, uint32_t alpha1, uint32_t alpha2) { uint32_t rt, gt, bt, at, rs, gs, bs, as; uint32_t p1; uint32_t p2; p1 = (uint32_t)(*(uint16_t *)src1); p2 = (uint32_t)(*(uint16_t *)src2); rs = (p1 >> 11) & 0x1f; gs = (p1 >> 5) & 0x3f; bs = p1 & 0x1f; rt = (p2 >> 11) & 0x1f; gt = (p2 >> 5) & 0x3f; bt = p2 & 0x1f; as = alpha1; at = alpha1; //#define SGL_TRACE(x) printf x SGL_TRACE(("******************** ")); SGL_TRACE((" as=0x%x, rs=0x%x, gs=0x%x, bs=0x%x ", as, rs, gs, bs)); SGL_TRACE((" at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x ", at, rt, gt, bt)); SGL_TRACE(("******************** ")); if(as == at) bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, as) else bgfx_blit_pixel_different_alphasrc_macro(rt, gt, bt, at, rs, gs, bs, as) SGL_TRACE(("******************** ")); SGL_TRACE(("after blend, rt=0x%x, gt=0x%x, bt=0x%x ", rt, gt, bt)); SGL_TRACE(("******************** ")); return (rt << 11) | (gt << 5) | bt; } #endif static int bgfx_blit_pixel_RGB565_ideal(void *src1, void *src2, uint32_t alpha1, uint32_t alpha2) { uint32_t rt, gt, bt, rs, gs, bs; uint32_t p1; uint32_t p2; BSTD_UNUSED(alpha2); p1 = *(uint16_t *)src1; p2 = *(uint16_t *)src2; rs = (p1 >> 11) & 0x1f; gs = (p1 >> 5) & 0x3f; bs = p1 & 0x1f; rt = (p2 >> 11) & 0x1f; gt = (p2 >> 5) & 0x3f; bt = p2 & 0x1f; bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, alpha1) return (rt << 11) | (gt << 5) | bt; } static int bgfx_blit_pixel_ARGB4444(void *src1, void *src2, unsigned int operation, uint32_t alpha1, uint32_t alpha2) { uint32_t rt, gt, bt, at, rs, gs, bs, as; uint32_t p1; uint32_t p2; p1 = (uint32_t)(*(uint16_t *)src1); p2 = (uint32_t)(*(uint16_t *)src2); rs = (p1 >> 8) & 0xf; gs = (p1 >> 4) & 0xf; bs = p1 & 0xf; rt = (p2 >> 8) & 0xf; gt = (p2 >> 4) & 0xf; bt = p2 & 0xf; if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1) { as = alpha1; at = alpha1; } else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC1_ALPHA) { as = ((p1 >> 12) & 0xf) << 4; at = as; } else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC2_ALPHA) { at = ((p2 >> 12) & 0xf) << 4; as = at; } else { as = ((p1 >> 12) & 0xf) << 4; at = ((p2 >> 12) & 0xf) << 4; } //#define SGL_TRACE(x) printf x SGL_TRACE(("******************** ")); SGL_TRACE((" as=0x%x, rs=0x%x, gs=0x%x, bs=0x%x ", as, rs, gs, bs)); SGL_TRACE((" at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x ", at, rt, gt, bt)); SGL_TRACE(("******************** ")); if(as == at) bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, as) else bgfx_blit_pixel_different_alphasrc_macro(rt, gt, bt, at, rs, gs, bs, as) if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2) at = alpha2; else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC1_ALPHA) at = p1 & 0xf000; else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC2_ALPHA) at = p2 & 0xf000; else at = (at >> 4) << 12; SGL_TRACE(("******************** ")); SGL_TRACE(("after blend, at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x ", at, rt, gt, bt)); SGL_TRACE(("******************** ")); return at | (rt << 8) | (gt << 4) | bt; } static int bgfx_blit_pixel_ARGB4444_ideal(void *src1, void *src2, uint32_t alpha1, uint32_t alpha2) { uint32_t rt, gt, bt, rs, gs, bs; uint32_t p1; uint32_t p2; p1 = *(uint16_t *)src1; p2 = *(uint16_t *)src2; rs = (p1 >> 8) & 0xf; gs = (p1 >> 4) & 0xf; bs = p1 & 0xf; rt = (p2 >> 8) & 0xf; gt = (p2 >> 4) & 0xf; bt = p2 & 0xf; bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, alpha1) return alpha2 | (rt << 8) | (gt << 4) | bt; } static int bgfx_blit_pixel_RGBA4444(void *src1, void *src2, unsigned int operation, uint32_t alpha1, uint32_t alpha2) { uint32_t rt, gt, bt, at, rs, gs, bs, as; uint32_t p1; uint32_t p2; p1 = (uint32_t)(*(uint16_t *)src1); p2 = (uint32_t)(*(uint16_t *)src2); rs = (p1 >> 12) & 0xf; gs = (p1 >> 8) & 0xf; bs = (p1 >> 4) & 0xf; rt = (p2 >> 12) & 0xf; gt = (p2 >> 8) & 0xf; bt = (p2 >> 4) & 0xf; if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1) { as = alpha1; at = alpha1; } else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC1_ALPHA) { as = (p1 & 0xf) << 4; at = as; } else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC2_ALPHA) { at = (p2 & 0xf) << 4; as = at; } else { as = (p1 & 0xf) << 4; at = (p2 & 0xf) << 4; } //#define SGL_TRACE(x) printf x SGL_TRACE(("******************** ")); SGL_TRACE((" as=0x%x, rs=0x%x, gs=0x%x, bs=0x%x ", as, rs, gs, bs)); SGL_TRACE((" at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x ", at, rt, gt, bt)); SGL_TRACE(("******************** ")); if(as == at) bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, as) else bgfx_blit_pixel_different_alphasrc_macro(rt, gt, bt, at, rs, gs, bs, as) if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2) at = alpha2; else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC1_ALPHA) at = p1 & 0xf; else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC2_ALPHA) at = p2 & 0xf; else at = (at >> 4); SGL_TRACE(("******************** ")); SGL_TRACE(("after blend, at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x ", at, rt, gt, bt)); SGL_TRACE(("******************** ")); return (rt << 12) | (gt << 8) | (bt << 4) | at; } static int bgfx_blit_pixel_RGBA4444_ideal(void *src1, void *src2, uint32_t alpha1, uint32_t alpha2) { uint32_t rt, gt, bt, rs, gs, bs; uint32_t p1; uint32_t p2; p1 = *(uint16_t *)src1; p2 = *(uint16_t *)src2; rs = (p1 >> 12) & 0xf; gs = (p1 >> 8) & 0xf; bs = (p1 >> 4) & 0xf; rt = (p2 >> 12) & 0xf; gt = (p2 >> 8) & 0xf; bt = (p2 >> 4) & 0xf; bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, alpha1) return (rt << 12) | (gt << 8) | (bt << 4) | alpha2; } static int bgfx_blit_pixel_WRGB1555(void *src1, void *src2, unsigned int operation, uint32_t alpha1, uint32_t alpha2) { uint32_t rt, gt, bt, at, rs, gs, bs, as; uint32_t p1; uint32_t p2; p1 = (uint32_t)(*(uint16_t *)src1); p2 = (uint32_t)(*(uint16_t *)src2); rs = (p1 >> 10) & 0x1f; gs = (p1 >> 5) & 0x1f; bs = p1 & 0x1f; rt = (p2 >> 10) & 0x1f; gt = (p2 >> 5) & 0x1f; bt = p2 & 0x1f; if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1) { as = alpha1; at = alpha1; } else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC1_ALPHA) { as = (p1 & 0x8000)? 0xff: 0; at = as; } else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC2_ALPHA) { at = (p2 & 0x8000)? 0xff: 0; as = at; } else { as = (p1 & 0x8000)? 0xff: 0; at = (p2 & 0x8000)? 0xff: 0; } //#define SGL_TRACE(x) printf x SGL_TRACE(("******************** ")); SGL_TRACE((" as=0x%x, rs=0x%x, gs=0x%x, bs=0x%x ", as, rs, gs, bs)); SGL_TRACE((" at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x ", at, rt, gt, bt)); SGL_TRACE(("******************** ")); if(as == at) bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, as) else bgfx_blit_pixel_different_alphasrc_macro(rt, gt, bt, at, rs, gs, bs, as) if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2) at = alpha2; else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC1_ALPHA) at = p1 & 0x8000; else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC2_ALPHA) at = p2 & 0x8000; else at = (at == 0xff)? 0x8000: 0; SGL_TRACE(("******************** ")); SGL_TRACE(("after blend, at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x ", at, rt, gt, bt)); SGL_TRACE(("******************** ")); return at | (rt << 10) | (gt << 5) | bt; } static int bgfx_blit_pixel_WRGB1555_ideal(void *src1, void *src2, uint32_t alpha1, uint32_t alpha2) { uint32_t rt, gt, bt, rs, gs, bs; uint32_t p1; uint32_t p2; p1 = *(uint16_t *)src1; p2 = *(uint16_t *)src2; rs = (p1 >> 10) & 0x1f; gs = (p1 >> 5) & 0x1f; bs = p1 & 0x1f; rt = (p2 >> 10) & 0x1f; gt = (p2 >> 5) & 0x1f; bt = p2 & 0x1f; bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, alpha1) return alpha2 | (rt << 10) | (gt << 5) | bt; } static int bgfx_blit_pixel_RGBW5551(void *src1, void *src2, unsigned int operation, uint32_t alpha1, uint32_t alpha2) { uint32_t rt, gt, bt, at, rs, gs, bs, as; uint32_t p1; uint32_t p2; p1 = (uint32_t)(*(uint16_t *)src1); p2 = (uint32_t)(*(uint16_t *)src2); rs = (p1 >> 11) & 0x1f; gs = (p1 >> 6) & 0x1f; bs = (p1 >> 1) & 0x1f; rt = (p2 >> 11) & 0x1f; gt = (p2 >> 6) & 0x1f; bt = (p2 >> 1) & 0x1f; if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1) { as = alpha1; at = alpha1; } else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC1_ALPHA) { as = (p1 & 0x1)? 0xff: 0; at = as; } else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC2_ALPHA) { at = (p2 & 0x1)? 0xff: 0; as = at; } else { as = (p1 & 0x1)? 0xff: 0; at = (p2 & 0x1)? 0xff: 0; } //#define SGL_TRACE(x) printf x SGL_TRACE(("******************** ")); SGL_TRACE((" as=0x%x, rs=0x%x, gs=0x%x, bs=0x%x ", as, rs, gs, bs)); SGL_TRACE((" at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x ", at, rt, gt, bt)); SGL_TRACE(("******************** ")); if(as == at) bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, as) else bgfx_blit_pixel_different_alphasrc_macro(rt, gt, bt, at, rs, gs, bs, as) if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2) at = alpha2; else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC1_ALPHA) at = p1 & 0x1; else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC2_ALPHA) at = p2 & 0x1; else at = (at == 0xff)? 1: 0; SGL_TRACE(("******************** ")); SGL_TRACE(("after blend, at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x ", at, rt, gt, bt)); SGL_TRACE(("******************** ")); return (rt << 11) | (gt << 6) | (bt << 1) | at; } static int bgfx_blit_pixel_RGBW5551_ideal(void *src1, void *src2, uint32_t alpha1, uint32_t alpha2) { uint32_t rt, gt, bt, rs, gs, bs; uint32_t p1; uint32_t p2; p1 = *(uint16_t *)src1; p2 = *(uint16_t *)src2; rs = (p1 >> 11) & 0x1f; gs = (p1 >> 6) & 0x1f; bs = (p1 >> 1) & 0x1f; rt = (p2 >> 11) & 0x1f; gt = (p2 >> 6) & 0x1f; bt = (p2 >> 1) & 0x1f; bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, alpha1) return (rt << 11) | (gt << 6) | (bt << 1) | alpha2; } static int bgfx_blit_pixel_ARGB8888(void *src1, void *src2, unsigned int operation, uint32_t alpha1, uint32_t alpha2) { uint32_t rt, gt, bt, at, rs, gs, bs, as; uint32_t p1; uint32_t p2; p1 = *(uint32_t *)src1; p2 = *(uint32_t *)src2; rs = (p1 >> 16) & 0xff; gs = (p1 >> 8) & 0xff; bs = p1 & 0xff; rt = (p2 >> 16) & 0xff; gt = (p2 >> 8) & 0xff; bt = p2 & 0xff; if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1) { as = alpha1; at = alpha1; } else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC1_ALPHA) { as = (p1 >> 24) & 0xff; at = as; } else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC2_ALPHA) { at = (p2 >> 24) & 0xff; as = at; } else { as = (p1 >> 24) & 0xff; at = (p2 >> 24) & 0xff; } //#define SGL_TRACE(x) printf x SGL_TRACE(("******************** ")); SGL_TRACE((" as=0x%x, rs=0x%x, gs=0x%x, bs=0x%x ", as, rs, gs, bs)); SGL_TRACE((" at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x ", at, rt, gt, bt)); SGL_TRACE(("******************** ")); if(as == at) bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, as) else bgfx_blit_pixel_different_alphasrc_macro(rt, gt, bt, at, rs, gs, bs, as) if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2) at = alpha2; else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC1_ALPHA) at = p1 & 0xff000000; else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC2_ALPHA) at = p2 & 0xff000000; else at = (at << 24); SGL_TRACE(("******************** ")); SGL_TRACE(("after blend, at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x ", at, rt, gt, bt)); SGL_TRACE(("******************** ")); return at | (rt << 16) | (gt << 8) | bt; } static int bgfx_blit_pixel_ARGB8888_ideal(void *src1, void *src2, uint32_t alpha1, uint32_t alpha2) { uint32_t rt, gt, bt, rs, gs, bs; uint32_t p1; uint32_t p2; p1 = *(uint32_t *)src1; p2 = *(uint32_t *)src2; rs = (p1 >> 16) & 0xff; gs = (p1 >> 8) & 0xff; bs = p1 & 0xff; rt = (p2 >> 16) & 0xff; gt = (p2 >> 8) & 0xff; bt = p2 & 0xff; bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, alpha1) return alpha2 | (rt << 16) | (gt << 8) | bt; } static int bgfx_blit_pixel_RGBA8888(void *src1, void *src2, unsigned int operation, uint32_t alpha1, uint32_t alpha2) { uint32_t rt, gt, bt, at, rs, gs, bs, as; uint32_t p1; uint32_t p2; p1 = *(uint32_t *)src1; p2 = *(uint32_t *)src2; rs = (p1 >> 24) & 0xff; gs = (p1 >> 16) & 0xff; bs = (p1 >> 8) & 0xff; rt = (p2 >> 24) & 0xff; gt = (p2 >> 16) & 0xff; bt = (p2 >> 8) & 0xff; if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1) { as = alpha1; at = alpha1; } else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC1_ALPHA) { as = p1 & 0xff; at = as; } else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC2_ALPHA) { at = p2 & 0xff; as = at; } else { as = p1 & 0xff; at = p2 & 0xff; } //#define SGL_TRACE(x) printf x SGL_TRACE(("******************** ")); SGL_TRACE((" as=0x%x, rs=0x%x, gs=0x%x, bs=0x%x ", as, rs, gs, bs)); SGL_TRACE((" at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x ", at, rt, gt, bt)); SGL_TRACE(("******************** ")); if(as == at) bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, as) else bgfx_blit_pixel_different_alphasrc_macro(rt, gt, bt, at, rs, gs, bs, as) if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2) at = alpha2; else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC1_ALPHA) at = p1 & 0xff; else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC2_ALPHA) at = p2 & 0xff; SGL_TRACE(("******************** ")); SGL_TRACE(("after blend, at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x ", at, rt, gt, bt)); SGL_TRACE(("******************** ")); return (rt << 24) | (gt << 16) | (bt << 8) | at; } static int bgfx_blit_pixel_RGBA8888_ideal(void *src1, void *src2, uint32_t alpha1, uint32_t alpha2) { uint32_t rt, gt, bt, rs, gs, bs; uint32_t p1; uint32_t p2; p1 = *(uint32_t *)src1; p2 = *(uint32_t *)src2; rs = (p1 >> 24) & 0xff; gs = (p1 >> 16) & 0xff; bs = (p1 >> 8) & 0xff; rt = (p2 >> 24) & 0xff; gt = (p2 >> 16) & 0xff; bt = (p2 >> 8) & 0xff; bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, alpha1) return (rt << 24) | (gt << 16) | (bt << 8) | alpha2; } static int bgfx_blit_pixel_ARGB8888_optimized(void *src1, void *src2) { // note operation, alpha1, alpha2 all unused. Hardcoded to operation 0x33 #if 0 /* Basic equation is: rt = (rs * as + (256 - as) * rt) >> 8; gt = (gs * as + (256 - as) * gt) >> 8; bt = (bs * as + (256 - as) * bt) >> 8; at = (((as + at) << 8) - as * at) >> 8; Most of the menu as values are 0xb2 (178 = 70%), 0xee (238 = 93%), 0xff (255 = 100%) you could approximate with: if (as=0) { use as=0 then the basic equation becomes: rt = rt; gt = gt; bt = bt; at = at; therefore, out pixel = src2 pixel; } else if (as >= 0xee) { use as=0xff so no need to extract rt/gt/bt and then compute by shifts Basic equation becomes: rt = (rs *as) >> 8; => rt = rs; gt = gs; bt = rs; at = ((256 + at) * 256 - 256 * at ) / 256 = 256 = as; therefore, out pixel = src1 pixel; } else if (as >= 0xb2) { use as = 75%, at = 25% and then compute by shifts Basic equation becomes: rt = (rs * as + (256 - as) * rt) >> 8; = (rs * 256*3/4 + (256 - 256*3/4) * rt) / 256 = (rs * 3/4 + rt/4) = (rs * 3 + rt) / 4 = (rs * 3 + rt) >> 2 => rt = (rs + rs + rs + rt) >> 2 gt = (gs + gs + gs + gt) >> 2 bt = (bs + bs + bs + bt) >> 2 at = (((256*3/4 + 256/4) * 256) - 256*3/4 * 256/4) / 256; = ((256*256) - 256*256*3/16)/256; = 256*13/16; => at = 208; } else { use basic equation } */ register uint32_t rt, gt, bt, at, rs, gs, bs, as; register uint32_t p1,p2; p2 = *(uint32_t *)src2; p1 = *(uint32_t *)src1; as = (p1 >> 24) & 0xff; if(as == 0) { /* out pixel = src2 pixel */ return p2; } else if (as >= 0xee) { /* out pixel = src1 pixel */ return p1; } else if (as >= 0xb2) { /* Use as = 75%, at = 25%, basic equation simplifies to: */ rs = (p1 >> 16) & 0xff; rt = (p2 >> 16) & 0xff; rt = (rs + rs + rs + rt) >> 2; gs = (p1 >> 8) & 0xff; gt = (p2 >> 8) & 0xff; gt = (gs + gs + gs + gt) >> 2; bs = p1 & 0xff; bt = p2 & 0xff; bt = (bs + bs + bs + bt) >> 2; at = 208; } else { /* Execute basic equation for all other cases */ //bgfx_blit_pixel_different_alphasrc_macro(rt, gt, bt, at, rs, gs, bs, as); rs = (p1 >> 16) & 0xff; rt = (p2 >> 16) & 0xff; rt = (rs * as + (256 - as) * rt) >> 8; gs = (p1 >> 8) & 0xff; gt = (p2 >> 8) & 0xff; gt = (gs * as + (256 - as) * gt) >> 8; bs = p1 & 0xff; bt = p2 & 0xff; bt = (bs * as + (256 - as) * bt) >> 8; at = (p2 >> 24) & 0xff; at = (((as + at) << 8) - as * at) >> 8; } #else register uint32_t rt, gt, bt, at, rs, gs, bs, as; register uint32_t p1,p2; uint32_t tmp_at, tmp_as; p2 = *(uint32_t *)src2; p1 = *(uint32_t *)src1; //bgfx_blit_pixel_different_alphasrc_macro(rt, gt, bt, at, rs, gs, bs, as); tmp_as = p1 & 0xff000000; if( tmp_as == 0 ) return p2; tmp_at = p2 & 0xff000000; if(tmp_at == 0) return p1; as = tmp_as >> 24; at = tmp_at >> 24; rs = (p1 >> 16) & 0xff; gs = (p1 >> 8) & 0xff; bs = p1 & 0xff; rt = (p2 >> 16) & 0xff; gt = (p2 >> 8) & 0xff; bt = p2 & 0xff; rt = (rs * as + (256 - as) * rt) >> 8; gt = (gs * as + (256 - as) * gt) >> 8; bt = (bs * as + (256 - as) * bt) >> 8; at = (((as + at) << 8) - as * at) >> 8; #endif #if (PRINT_ON ==1) printf("p1=%x, p2=%x \r\n", p1,p2); printf("rs=%x, gs=%x, bs=%x\r\n", rs,gs,bs); printf("rt=%x, gt=%x, bt=%x\r\n", rt,gt,bt); #endif #if 0 //bgfx_blit_pixel_different_alphasrc_macro(rt, gt, bt, at, rs, gs, bs, as); rt = (rs * as + (256 - as) * rt) >> 8; gt = (gs * as + (256 - as) * gt) >> 8; bt = (bs * as + (256 - as) * bt) >> 8; at = (((as + at) << 8) - as * at) >> 8; #endif #if (PRINT_ON ==1) printf("rt=%x, gt=%x, bt=%x, at=%x\r\n", rt,gt,bt, at); #endif return (at << 24) | (rt << 16) | (gt << 8) | bt; } /**************************************************************** * INPUTS: p_src1, p_src2, p_dst - source and destination surface structures * s1x,s1y,s2x,s2y - source coordinates * dx,dy - destination coordinates * sw,sh - width and height of region * operation - alpha blending settings * alpha1 - specified alpha value for calculating R,G,B blending * alpha2 - specified alpha value for calculating A blending * OUTPUTS: none * RETURNS: non-zero on error * FUNCTION: Blit a region of one surface to another * ****************************************************************/ int bgfx_blit_rect_multisuf_blending(bgfx_surf_p p_src1, bgfx_surf_p p_src2, bgfx_surf_p p_dst, uint16_t s1x,uint16_t s1y, uint16_t s2x,uint16_t s2y, uint16_t dx,uint16_t dy, uint16_t sw, uint16_t sh, unsigned int operation, uint32_t alpha1, uint32_t alpha2) { uint8_t *dst,*src1, *src2; uint16_t j,w,h; #ifdef CONFIG_BGFX_SURF_RGB uint8_t *tdst; uint32_t i; uint32_t dst_pitch; uint16_t dst_step; #endif if ((dx >= p_dst->surface.width) || (dy >= p_dst->surface.height)) { SGL_DEBUG(("bgfx_blit_rect dst_x,dst_y (%d,%d) outside destination (%d,%d) ",dx,dy, p_dst->surface.width,p_dst->surface.height)); return -1; } if ((s1x >= p_src1->surface.width) || (s1y >= p_src1->surface.height)) { SGL_DEBUG(("bgfx_blit_rect src_x,src_y (%d,%d) outside source (%d,%d) ",s1x,s1y, p_src1->surface.width,p_src1->surface.height)); return -1; } if ((s2x >= p_src2->surface.width) || (s2y >= p_src2->surface.height)) { SGL_DEBUG(("bgfx_blit_rect src_x,src_y (%d,%d) outside source (%d,%d) ",s2x,s2y, p_src2->surface.width,p_src2->surface.height)); return -1; } src1 = (uint8_t*)p_src1->surface.buf; src1 += (s1y * p_src1->surface.pitch) + (s1x * (p_src1->bpp >> 3)); src2 = (uint8_t*)p_src2->surface.buf; src2 += (s2y * p_src2->surface.pitch) + (s2x * (p_src2->bpp >> 3)); dst = (uint8_t*)p_dst->surface.buf; dst += (dy * p_dst->surface.pitch) + (dx * (p_dst->bpp >> 3)); w = sw; if (sw >= (p_src1->surface.width - s1x)) w= p_src1->surface.width - s1x; if (w >= (p_src2->surface.width - s2x)) w= p_src2->surface.width - s2x; if (w >= p_dst->surface.width - dx) w = p_dst->surface.width - dx; h = sh; if (sh >= (p_src1->surface.height - s1y)) h= p_src1->surface.height - s1y; if (sh >= (p_src2->surface.height - s2y)) h= p_src2->surface.height - s2y; if (h >= p_dst->surface.height - dy) h = p_dst->surface.height - dy; SGL_TRACE(("w=%d ", w)); SGL_TRACE(("h=%d ", h)); SGL_TRACE(("operation=%d ", operation)); dst_step = (p_dst->bpp >> 3); dst_pitch = dst_step * w; #ifdef CONFIG_BGFX_SURF_RGB if (p_dst->flags & BGFX_SURF_RGB) { switch(p_dst->format) { case GRAPHICS_FMT_ARGB_888: alpha2 = (alpha2 << 24); if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1 && (operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2) { for (j = 0; j < h; ++j) { tdst = dst; for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step) { #ifdef COMPARE_PREVIOUS_PIXEL if(i > 0 && *(uint32_t*)(&src1[i]) == *(uint32_t*)(&src1[i-dst_step]) && *(uint32_t*)(&src2[i]) == *(uint32_t*)(&src2[i-dst_step])) { // memcpy(tdst, tdst - dst_step, dst_step); *((uint32_t*)tdst) = *((uint32_t*)(tdst - dst_step)); } else { #endif *((uint32_t*)tdst) = bgfx_blit_pixel_ARGB8888_ideal(&src1[i], &src2[i], alpha1, alpha2); } } dst += p_dst->surface.pitch; src1 += p_src1->surface.pitch; src2 += p_src2->surface.pitch; } } else { uint32_t p1, p2, p3; p1 = p_dst->surface.pitch; p2 = p_src1->surface.pitch; p3 = p_src2->surface.pitch; if(operation == 0x33) { for (j = h; j--; ) { tdst = dst; for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step) { #ifdef COMPARE_PREVIOUS_PIXEL if(i != 0 && *(uint32_t*)(&src1[i]) == *(uint32_t*)(&src1[i-dst_step]) && *(uint32_t*)(&src2[i]) == *(uint32_t*)(&src2[i-dst_step])) { // memcpy(tdst, tdst - dst_step, dst_step); *((uint32_t*)tdst) = *((uint32_t*)(tdst - dst_step)); } else #endif { #if 0 *((uint32_t*)tdst) = bgfx_blit_pixel_ARGB8888(&src1[i], &src2[i], operation, alpha1, alpha2); #else *((uint32_t*)tdst) = bgfx_blit_pixel_ARGB8888_optimized(&src1[i], &src2[i]); #endif } }/* for i */ #if NON_OPTIMIZED dst += p_dst->surface.pitch; src1 += p_src1->surface.pitch; src2 += p_src2->surface.pitch; #else dst += p1; src1 += p2; src2 += p3; #endif }/* for j */ } else { /* operation != 0x33 */ for (j = h; j--; ) { tdst = dst; for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step) { #ifdef COMPARE_PREVIOUS_PIXEL if(i != 0 && *(uint32_t*)(&src1[i]) == *(uint32_t*)(&src1[i-dst_step]) && *(uint32_t*)(&src2[i]) == *(uint32_t*)(&src2[i-dst_step])) { // memcpy(tdst, tdst - dst_step, dst_step); *((uint32_t*)tdst) = *((uint32_t*)(tdst - dst_step)); } else #endif { #if 1 *((uint32_t*)tdst) = bgfx_blit_pixel_ARGB8888(&src1[i], &src2[i], operation, alpha1, alpha2); #else *((uint32_t*)tdst) = bgfx_blit_pixel_ARGB8888_optimized(&src1[i], &src2[i]); #endif } }/* for i */ #if NON_OPTIMIZED dst += p_dst->surface.pitch; src1 += p_src1->surface.pitch; src2 += p_src2->surface.pitch; #else dst += p1; src1 += p2; src2 += p3; #endif } /* for j */ }/* if - else operation == 0x33 */ } break; case GRAPHICS_FMT_RGBA_888: if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1 && (operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2) { for (j = 0; j < h; ++j) { tdst = dst; for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step) #ifdef COMPARE_PREVIOUS_PIXEL if(i > 0 && *(uint32_t*)(&src1[i]) == *(uint32_t*)(&src1[i-dst_step]) && *(uint32_t*)(&src2[i]) == *(uint32_t*)(&src2[i-dst_step])) // memcpy(tdst, tdst - dst_step, dst_step); *((uint32_t*)tdst) = *((uint32_t*)(tdst - dst_step)); else #endif *((uint32_t*)tdst) = bgfx_blit_pixel_RGBA8888_ideal(&src1[i], &src2[i], alpha1, alpha2); dst += p_dst->surface.pitch; src1 += p_src1->surface.pitch; src2 += p_src2->surface.pitch; } } else { for (j = 0; j < h; ++j) { tdst = dst; for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step) #ifdef COMPARE_PREVIOUS_PIXEL if(i > 0 && *(uint32_t*)(&src1[i]) == *(uint32_t*)(&src1[i-dst_step]) && *(uint32_t*)(&src2[i]) == *(uint32_t*)(&src2[i-dst_step])) // memcpy(tdst, tdst - dst_step, dst_step); *((uint32_t*)tdst) = *((uint32_t*)(tdst - dst_step)); else #endif *((uint32_t*)tdst) = bgfx_blit_pixel_RGBA8888(&src1[i], &src2[i], operation, alpha1, alpha2); dst += p_dst->surface.pitch; src1 += p_src1->surface.pitch; src2 += p_src2->surface.pitch; } } break; case GRAPHICS_FMT_WRGB_1555: if(alpha2 != 0xff && alpha2 != 0 && (operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2) { SGL_DEBUG(("GRAPHICS_FMT_WRGB_1555 format only support 0 or 255 alpha output! ")); return -1; } else alpha2 = (alpha2 == 0xff)? 0x8000: 0; if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1 && (operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2) { for (j = 0; j < h; ++j) { tdst = dst; for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step) #ifdef COMPARE_PREVIOUS_PIXEL if(i > 0 && *(uint16_t*)(&src1[i]) == *(uint16_t*)(&src1[i-dst_step]) && *(uint16_t*)(&src2[i]) == *(uint16_t*)(&src2[i-dst_step])) // memcpy(tdst, tdst - dst_step, dst_step); *((uint16_t*)tdst) = *((uint16_t*)(tdst - dst_step)); else #endif *((uint16_t*)tdst) = bgfx_blit_pixel_WRGB1555_ideal(&src1[i], &src2[i], alpha1, alpha2) & 0xffff; dst += p_dst->surface.pitch; src1 += p_src1->surface.pitch; src2 += p_src2->surface.pitch; } } else { for (j = 0; j < h; ++j) { tdst = dst; for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step) #ifdef COMPARE_PREVIOUS_PIXEL if(i > 0 && *(uint16_t*)(&src1[i]) == *(uint16_t*)(&src1[i-dst_step]) && *(uint16_t*)(&src2[i]) == *(uint16_t*)(&src2[i-dst_step])) // memcpy(tdst, tdst - dst_step, dst_step); *((uint16_t*)tdst) = *((uint16_t*)(tdst - dst_step)); else #endif *((uint16_t*)tdst) = bgfx_blit_pixel_WRGB1555(&src1[i], &src2[i], operation, alpha1, alpha2) & 0xffff; dst += p_dst->surface.pitch; src1 += p_src1->surface.pitch; src2 += p_src2->surface.pitch; } } break; case GRAPHICS_FMT_RGBW_5551: if(alpha2 != 0xff && alpha2 != 0 && (operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2) { SGL_DEBUG(("GRAPHICS_FMT_RGBW_5551 format only support 0 or 255 alpha output! ")); return -1; } else alpha2 = (alpha2 == 0xff)? 1: 0; if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1 && (operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2) { for (j = 0; j < h; ++j) { tdst = dst; for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step) #ifdef COMPARE_PREVIOUS_PIXEL if(i > 0 && *(uint16_t*)(&src1[i]) == *(uint16_t*)(&src1[i-dst_step]) && *(uint16_t*)(&src2[i]) == *(uint16_t*)(&src2[i-dst_step])) // memcpy(tdst, tdst - dst_step, dst_step); *((uint16_t*)tdst) = *((uint16_t*)(tdst - dst_step)); else #endif *((uint16_t*)tdst) = bgfx_blit_pixel_RGBW5551_ideal(&src1[i], &src2[i], alpha1, alpha2) & 0xffff; dst += p_dst->surface.pitch; src1 += p_src1->surface.pitch; src2 += p_src2->surface.pitch; } } else { for (j = 0; j < h; ++j) { tdst = dst; for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step) #ifdef COMPARE_PREVIOUS_PIXEL if(i > 0 && *(uint16_t*)(&src1[i]) == *(uint16_t*)(&src1[i-dst_step]) && *(uint16_t*)(&src2[i]) == *(uint16_t*)(&src2[i-dst_step])) // memcpy(tdst, tdst - dst_step, dst_step); *((uint16_t*)tdst) = *((uint16_t*)(tdst - dst_step)); else #endif *((uint16_t*)tdst) = bgfx_blit_pixel_RGBW5551(&src1[i], &src2[i], operation, alpha1, alpha2) & 0xffff; dst += p_dst->surface.pitch; src1 += p_src1->surface.pitch; src2 += p_src2->surface.pitch; } } break; case GRAPHICS_FMT_ARGB_4444: alpha2 = ((alpha2 >> 4) << 12); if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1 && (operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2) { for (j = 0; j < h; ++j) { tdst = dst; for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step) #ifdef COMPARE_PREVIOUS_PIXEL if(i > 0 && *(uint16_t*)(&src1[i]) == *(uint16_t*)(&src1[i-dst_step]) && *(uint16_t*)(&src2[i]) == *(uint16_t*)(&src2[i-dst_step])) // memcpy(tdst, tdst - dst_step, dst_step); *((uint16_t*)tdst) = *((uint16_t*)(tdst - dst_step)); else #endif *((uint16_t*)tdst) = bgfx_blit_pixel_ARGB4444_ideal(&src1[i], &src2[i], alpha1, alpha2) & 0xffff; dst += p_dst->surface.pitch; src1 += p_src1->surface.pitch; src2 += p_src2->surface.pitch; } } else { for (j = 0; j < h; ++j) { tdst = dst; for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step) #ifdef COMPARE_PREVIOUS_PIXEL if(i > 0 && *(uint16_t*)(&src1[i]) == *(uint16_t*)(&src1[i-dst_step]) && *(uint16_t*)(&src2[i]) == *(uint16_t*)(&src2[i-dst_step])) // memcpy(tdst, tdst - dst_step, dst_step); *((uint16_t*)tdst) = *((uint16_t*)(tdst - dst_step)); else #endif *((uint16_t*)tdst) = bgfx_blit_pixel_ARGB4444(&src1[i], &src2[i], operation, alpha1, alpha2) & 0xffff; dst += p_dst->surface.pitch; src1 += p_src1->surface.pitch; src2 += p_src2->surface.pitch; } } break; case GRAPHICS_FMT_RGBA_4444: alpha2 = (alpha2 >> 4); if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1 && (operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2) { for (j = 0; j < h; ++j) { tdst = dst; for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step) #ifdef COMPARE_PREVIOUS_PIXEL if(i > 0 && *(uint16_t*)(&src1[i]) == *(uint16_t*)(&src1[i-dst_step]) && *(uint16_t*)(&src2[i]) == *(uint16_t*)(&src2[i-dst_step])) // memcpy(tdst, tdst - dst_step, dst_step); *((uint16_t*)tdst) = *((uint16_t*)(tdst - dst_step)); else #endif *((uint16_t*)tdst) = bgfx_blit_pixel_RGBA4444_ideal(&src1[i], &src2[i], alpha1, alpha2) & 0xffff; dst += p_dst->surface.pitch; src1 += p_src1->surface.pitch; src2 += p_src2->surface.pitch; } } else { for (j = 0; j < h; ++j) { tdst = dst; for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step) #ifdef COMPARE_PREVIOUS_PIXEL if(i > 0 && *(uint16_t*)(&src1[i]) == *(uint16_t*)(&src1[i-dst_step]) && *(uint16_t*)(&src2[i]) == *(uint16_t*)(&src2[i-dst_step])) // memcpy(tdst, tdst - dst_step, dst_step); *((uint16_t*)tdst) = *((uint16_t*)(tdst - dst_step)); else #endif *((uint16_t*)tdst) = bgfx_blit_pixel_RGBA4444(&src1[i], &src2[i], operation, alpha1, alpha2) & 0xffff; dst += p_dst->surface.pitch; src1 += p_src1->surface.pitch; src2 += p_src2->surface.pitch; } } break; case GRAPHICS_FMT_RGB_565: if(alpha2 != 0xff || (operation & 0xf0) != SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2 || (operation & 0x0f) != SURFBLIT_BLEND_WITH_SPEC_ALPHA1) { SGL_DEBUG(("operation parameter incorrect: Must use SURFBLIT_BLEND_WITH_SPEC_ALPHA1 and SURFBLIT_BLEND_WITH_SPEC_ALPHA2 method and alpha2 should be 0xff for a non-alpha format! ")); return -1; } for (j = 0; j < h; ++j) { tdst = dst; for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step) #ifdef COMPARE_PREVIOUS_PIXEL if(i > 0 && *(uint16_t*)(&src1[i]) == *(uint16_t*)(&src1[i-dst_step]) && *(uint16_t*)(&src2[i]) == *(uint16_t*)(&src2[i-dst_step])) // memcpy(tdst, tdst - dst_step, dst_step); *((uint16_t*)tdst) = *((uint16_t*)(tdst - dst_step)); else #endif *((uint16_t*)tdst) = bgfx_blit_pixel_RGB565_ideal(&src1[i], &src2[i], alpha1, alpha2) & 0xffff; dst += p_dst->surface.pitch; src1 += p_src1->surface.pitch; src2 += p_src2->surface.pitch; } break; default: SGL_DEBUG(("Not supported formats for multi surface alpha blending.")); return -1; } } else #endif { SGL_DEBUG(("multi surface alpha blending only support RGB surfaces.")); return -1; } bgfx_cacheflush(p_dst->surface.buf,p_dst->surface.pitch * p_dst->surface.height); return 0; } /**************************************************************** * * INPUTS: p_src - source palette pointer * OUTPUTS: none * RETURNS: none * FUNCTION: Map palette from RGB to YUV * Raymond, 20090211 ****************************************************************/ void bgfx_mapping_palette(unsigned int *p_src, unsigned int size) { unsigned int i; unsigned int a, r, g, b, y, u, v; SGL_TRACE(("----------palette size =%d---------- ", size)); for(i=0; i> 24) & 0xFF; r = (*(p_src + i) >> 16) & 0xFF; g = (*(p_src + i) >> 8) & 0xFF; b = (*(p_src + i) >> 0) & 0xFF; #if 1 bgfx_csc_BT_601_RGB_2_YCbCr_macro(y,u,v,r,g,b); #else y = (0.257 * r) + (0.504 * g) + (0.098 * b) + 16; v = (0.439 * r) - (0.368 * g) - (0.071 * b) + 128; u = -(0.148 * r) - (0.291 * g) + (0.439 * b) + 128; *(p_src + i) = (a << 24) | (y << 16) | (u << 8) | v; #endif SGL_TRACE(("----------AYUV ui_comp.ui_palette[%d]=%x---------- ", i, *(p_src + i))); } } #endif /**************************************************************** * INPUTS: p_src,p_dst - source and destination surface structures * sx,sy - source coordinates * dx,dy - destination coordinates * sw,sh - width and height of region * OUTPUTS: none * RETURNS: non-zero on error * FUNCTION: anti-flutter filter a region of one surface to another * ****************************************************************/ inline void bgfx_AFF_ARGB_888(uint32_t * q,uint32_t * q1, uint32_t *q2, uint32_t * dst, uint8_t coef) { register uint32_t a,r,g,b; register uint32_t r1,g1,b1; register uint32_t r2,g2,b2; register uint32_t q_val, q1_val, q2_val; register uint32_t mask_3rd_byte = 0x00ff0000; BSTD_UNUSED(coef); q_val = *q; a = (q_val&0xff000000); r = (q_val&mask_3rd_byte); g = (q_val&0x0000ff00); b = (q_val&0x000000ff); q1_val = *q1; r1 = (q1_val&mask_3rd_byte); g1 = (q1_val&0x0000ff00); b1 = (q1_val&0x000000ff); q2_val = *q2; r2 = (q2_val&mask_3rd_byte); g2 = (q2_val&0x0000ff00); b2 = (q2_val&0x000000ff); *dst = a | (((r1 + (r<<1) + r2)>>2)&mask_3rd_byte) | (((g1 + (g<<1) + g2)>>2)&0x0000ff00) |(((b1 + (b<<1) + b2)>>2)&0x000000ff); } inline void bgfx_AFF_RGBA_888(uint32_t * q,uint32_t * q1, uint32_t *q2, uint32_t * dst, uint8_t coef) { register uint32_t a,r,g,b; register uint32_t r1,g1,b1; register uint32_t r2,g2,b2; register uint32_t q_val, q1_val, q2_val; register uint32_t mask_3rd_byte = 0x00ff0000; register uint32_t mask_4rd_byte = 0xff000000; BSTD_UNUSED(coef); q_val = *q; a = (q_val&0x000000ff); r = (q_val&mask_4rd_byte); g = (q_val&mask_3rd_byte); b = (q_val&0x0000ff00); q1_val = *q1; r1 = (q1_val&mask_4rd_byte); g1 = (q1_val&mask_3rd_byte); b1 = (q1_val&0x0000ff00); q2_val = *q2; r2 = (q2_val&mask_4rd_byte); g2 = (q2_val&mask_3rd_byte); b2 = (q2_val&0x0000ff00); *dst = (((r1 + (r<<1) + r2)>>2)&mask_4rd_byte) | (((g1 + (g<<1) + g2)>>2)&mask_3rd_byte) |(((b1 + (b<<1) + b2)>>2)&0x0000ff00) | a; } inline void bgfx_AFF_RGB_565(uint16_t *p, uint16_t * p1, uint16_t * p2, uint16_t * dst, uint8_t coef) { register uint32_t r,g,b; register uint32_t r1,g1,b1; register uint32_t r2,g2,b2; register uint32_t p_val, p1_val, p2_val; BSTD_UNUSED(coef); p_val = (uint32_t)*p; r = (p_val&0xf800); g = (p_val&0x07e0); b = (p_val&0x001f); p1_val = (uint32_t)*p1; r1 = (p1_val&0xf800); g1 = (p1_val&0x07e0); b1 = (p1_val&0x001f); p2_val = (uint32_t)*p2; r2 = (p2_val&0xf800); g2 = (p2_val&0x07e0); b2 = (p2_val&0x001f); *dst = (((r1 + (r<<1) + r2)>>2)&0xf800) | (((g1 + (g<<1) + g2)>>2)&0x07e0) | (((b1 + (b<<1) + b2)>>2)&0x001f); } inline void bgfx_AFF_WRGB_1555(uint16_t *p, uint16_t * p1, uint16_t * p2, uint16_t * dst, uint8_t coef) { register uint32_t a,r,g,b; register uint32_t r1,g1,b1; register uint32_t r2,g2,b2; register uint32_t p_val, p1_val, p2_val; BSTD_UNUSED(coef); p_val = (uint32_t)*p; a = (p_val&0x8000); r = (p_val&0x7c00); g = (p_val&0x03e0); b = (p_val&0x001f); p1_val = (uint32_t)*p1; r1 = (p1_val&0x7c00); g1 = (p1_val&0x03e0); b1 = (p1_val&0x001f); p2_val = (uint32_t)*p2; r2 = (p2_val&0x7c00); g2 = (p2_val&0x03e0); b2 = (p2_val&0x001f); *dst = a | (((r1 + (r<<1) + r2)>>2)&0x7c00) | (((g1 + (g<<1) + g2)>>2)&0x03e0) | (((b1 + (b<<1) + b2)>>2)&0x001f); } inline void bgfx_AFF_RGBW_5551(uint16_t *p, uint16_t * p1, uint16_t * p2, uint16_t * dst, uint8_t coef) { register uint32_t a,r,g,b; register uint32_t r1,g1,b1; register uint32_t r2,g2,b2; register uint32_t p_val, p1_val, p2_val; BSTD_UNUSED(coef); p_val = (uint32_t)*p; a = (p_val&0x0001); r = (p_val&0xf800); g = (p_val&0x07c0); b = (p_val&0x003e); p1_val = (uint32_t)*p1; r1 = (p1_val&0xf800); g1 = (p1_val&0x07c0); b1 = (p1_val&0x003e); p2_val = (uint32_t)*p2; r2 = (p2_val&0xf800); g2 = (p2_val&0x07c0); b2 = (p2_val&0x003e); *dst = (((r1 + (r<<1) + r2)>>2)&0xf800) | (((g1 + (g<<1) + g2)>>2)&0x07c0) | (((b1 + (b<<1) + b2)>>2)&0x003e) | a; } inline void bgfx_AFF_ARGB_4444(uint16_t *p, uint16_t * p1, uint16_t * p2, uint16_t * dst, uint8_t coef) { register uint32_t a,r,g,b; register uint32_t r1,g1,b1; register uint32_t r2,g2,b2; register uint32_t p_val, p1_val, p2_val; BSTD_UNUSED(coef); p_val = (uint32_t)*p; a = (p_val&0xf000); r = (p_val&0x0f00); g = (p_val&0x00f0); b = (p_val&0x000f); p1_val = (uint32_t)*p1; r1 = (p1_val&0x0f00); g1 = (p1_val&0x00f0); b1 = (p1_val&0x000f); p2_val = (uint32_t)*p2; r2 = ((p2_val&0x0f00) >> 8); g2 = ((p2_val&0x00f0) >> 4); b2 = (p2_val&0x000f); *dst = a | (((r1 + (r<<1) + r2)>>2)&0x0f00) | (((g1 + (g<<1) + g2)>>2)&0x00f0) | (((b1 + (b<<1) + b2)>>2)&0x000f); } inline void bgfx_AFF_RGBA_4444(uint16_t *p, uint16_t * p1, uint16_t * p2, uint16_t * dst, uint8_t coef) { register uint32_t a,r,g,b; register uint32_t r1,g1,b1; register uint32_t r2,g2,b2; register uint32_t p_val, p1_val, p2_val; BSTD_UNUSED(coef); p_val = (uint32_t)*p; a = (p_val&0x000f); r = (p_val&0xf000); g = (p_val&0x0f00); b = (p_val&0x00f0); p1_val = (uint32_t)*p1; r1 = (p1_val&0xf000); g1 = (p1_val&0x0f00); b1 = (p1_val&0x00f0); p2_val = (uint32_t)*p2; r2 = (p2_val&0xf000); g2 = (p2_val&0x0f00); b2 = (p2_val&0x00f0); *dst = (((r1 + (r<<1) + r2)>>2)&0xf000) | (((g1 + (g<<1) + g2)>>2)&0x0f00) | (((b1 + (b<<1) + b2)>>2)&0x00f0) | a; } void bgfx_soft_AFF_V(uint8_t * dst, uint8_t * src, uint16_t width, uint16_t height, uint16_t pitch, int format, uint8_t vcoef) { register int i,j,k; register uint16_t *p,*p1,*p2; register uint8_t Bpp; register uint32_t *q,*q1,*q2; register uint16_t *last16=NULL; register uint32_t *last32=NULL; uint16_t tmp16; uint32_t tmp32; //printf("\n%s: dst=%p,src=%p,(%d,%d),pitch=%d\n",__func__,dst,src,width,height,pitch); switch (format) { case GRAPHICS_FMT_ARGB_888: case GRAPHICS_FMT_RGBA_888: Bpp = 4; last32 = (uint32_t *)SGL_MALLOC(width*4); if(last32 == NULL) { printf("%s: SGL_MALLOC %d error\n",__func__,width*4); return; } break; case GRAPHICS_FMT_RGB_565: case GRAPHICS_FMT_WRGB_1555: case GRAPHICS_FMT_RGBW_5551: case GRAPHICS_FMT_ARGB_4444: case GRAPHICS_FMT_RGBA_4444: Bpp = 2; last16 = (uint16_t *)SGL_MALLOC(width*2); if(last16 == NULL) { printf("%s: SGL_MALLOC %d error\n",__func__,width*2); return; } break; default: SGL_DEBUG(("%s: unsupported foramt %d", __func__, format)); return; } /*no filtered on the first and last line, reserve the original value */ /*anti-flutter filter*/ switch (format) { case GRAPHICS_FMT_ARGB_888: /*compute the second line and save temporarily*/ if(height > 2) { k = pitch; for(j=0; j 2) { k = pitch; for(j=0; j 2) { k = pitch; for(j=0; j 2) { k = pitch; for(j=0; j 2) { k = pitch; for(j=0; j 2) { k = pitch; for(j=0; j 2) { k = pitch; for(j=0; j 2) { k = (height-2)*pitch; memcpy(dst+k, last32,width*4); } SGL_FREE(last32); } if(last16 != NULL) { if(height > 2) { k = (height-2)*pitch; memcpy(dst+k, last16,width*2); } SGL_FREE(last16); } } #ifdef SW_ANTI_FLUTTER_FILTER_HORIZONTAL static void bgfx_soft_AFF_H(uint8_t * dst, uint8_t * src, uint16_t width, uint16_t height, uint16_t pitch, int format, uint8_t hcoef) { int i,j,k,l; uint16_t *p,*p1,*p2; uint16_t last16=0; uint32_t *q, *q1, *q2; uint32_t last32=0; uint32_t tmp32; uint16_t tmp16; uint8_t Bpp; printf("\n%s: dst=%p,src=%p,(%d,%d),pitch=%d\n",__func__,dst,src,width,height,pitch); switch (format) { case GRAPHICS_FMT_ARGB_888: case GRAPHICS_FMT_RGBA_888: Bpp = 4; break; case GRAPHICS_FMT_RGB_565: case GRAPHICS_FMT_WRGB_1555: case GRAPHICS_FMT_RGBW_5551: case GRAPHICS_FMT_ARGB_4444: case GRAPHICS_FMT_RGBA_4444: Bpp = 2; break; default: SGL_DEBUG(("%s: unsupported foramt %d", __func__, format)); return; } /*no filtered on the first and last column, reserve the original value */ /*anti-flutter, filter*/ switch (format) { case GRAPHICS_FMT_ARGB_888: for(i=0; iformat) { case GRAPHICS_FMT_ARGB_888: case GRAPHICS_FMT_RGBA_888: case GRAPHICS_FMT_RGB_565: case GRAPHICS_FMT_WRGB_1555: case GRAPHICS_FMT_RGBW_5551: case GRAPHICS_FMT_ARGB_4444: case GRAPHICS_FMT_RGBA_4444: break; case GRAPHICS_FMT_P4: case GRAPHICS_FMT_P8: SGL_DEBUG(("%s: can not filter foramt %d", __func__, p_src->format)); return -1; default: SGL_DEBUG(("%s: unsupported foramt %d", __func__, p_src->format)); return -1; } if ((dx >= p_dst->surface.width) || (dy >= p_dst->surface.height)) { SGL_DEBUG(("%s dst_x,dst_y (%d,%d) outside destination (%d,%d) ",__func__,dx,dy, p_dst->surface.width,p_dst->surface.height)); return -1; } if ((sx >= p_src->surface.width) || (sy >= p_src->surface.height)) { SGL_DEBUG(("%s src_x,src_y (%d,%d) outside source (%d,%d) ",__func__,sx,sy, p_src->surface.width,p_src->surface.height)); return -1; } src = (uint8_t*)p_src->surface.buf; src += (sy * p_src->surface.pitch) + ((sx * p_src->bpp)/8); dst = (uint8_t*)p_dst->surface.buf; dst += (dy * p_dst->surface.pitch) + ((dx * p_dst->bpp)/8); w = sw; if (sw >= (p_src->surface.width - sx)) w= p_src->surface.width - sx; if (w >= p_dst->surface.width - dx) w = p_dst->surface.width - dx; h = sh; if (sh >= (p_src->surface.height - sy)) h= p_src->surface.height - sy; if (h >= p_dst->surface.height - dy) h = p_dst->surface.height - dy; bgfx_soft_AFF_V(dst,src,w,h,p_src->surface.pitch,p_src->format,0); #if defined SW_ANTI_FLUTTER_FILTER_HORIZONTAL bgfx_soft_AFF_H(dst,src,w,h,p_src->surface.pitch,p_src->format,0); #endif return 0; } /**************************************************************** * INPUTS: p - surface structure * x,y - coordinates * w,h - width and height of region * c - constant color in ARGB8888 format * OUTPUTS: none * RETURNS: non-zero on error * FUNCTION: Fills the region as per following rule: * const color c -> AcRcGcBc (src1) * surface p -> AiRiGiBi (src2) * blended outpout -> AiRoGoBo * where Ro = Ac * Rc + (1 - Ac) * Ri * Go = Ac * Gc + (1 - Ac) * Gi * Bo = Ac * Bc + (1 - Ac) * Bi ****************************************************************/ #if 0 int bgfx_blend_fill_rect(bgfx_surf_p p, uint16_t x,uint16_t y, uint16_t w, uint16_t h, bgfx_pixel c) { uint8_t *dst; uint16_t j; unsigned int operation; uint8_t alpha1, alpha2; #ifdef CONFIG_BGFX_SURF_RGB uint8_t *tdst; uint32_t i=0, dst_step, last_pixel=0; #endif if ((x >= p->surface.width) || (y >= p->surface.height)) { SGL_DEBUG(("bgfx_blend_fill_rect x,y (%d,%d) w,h (%d,%d)\n",x,y, p->surface.width,p->surface.height)); return -1; } dst = (uint8_t*)p->surface.buf; dst += (y * p->surface.pitch) + ((x * p->bpp)/8); if (w >= p->surface.width - x) w = p->surface.width - x; if (h >= p->surface.height - y) h = p->surface.height - y; /* Support available only for colorOp = eBlend and alphaOp = eIgnore */ operation = SURFBLIT_BLEND_WITH_AVG_ALPHA | SURFBLIT_SET_DEST_ALPHA_WITH_SRC2_ALPHA; alpha1 = BPXL_GET_COMPONENT(BPXL_eA8_B8_G8_R8, c, 3); alpha2 = 1; SGL_TRACE(("w=%d", w)); SGL_TRACE(("h=%d", h)); SGL_TRACE(("operation=0x%x alpha1=0x%x alpha2=0x%x", operation, alpha1, alpha2)); dst_step = p->bpp / 8; #ifdef CONFIG_BGFX_SURF_RGB if (p->flags & BGFX_SURF_RGB) { for (j = 0; j < h; ++j) { tdst = dst; for(i = 0; i < dst_step * w; i += dst_step, tdst += dst_step) { if(p->bpp == 32) { #ifdef COMPARE_PREVIOUS_PIXEL if(i > 0 && *(uint32_t*)(&dst[i]) == last_pixel) { *((uint32_t*)tdst) = *(uint32_t*)(tdst - dst_step); } else #endif { last_pixel = *(uint32_t*)(&dst[i]); *((uint32_t*)tdst) = bgfx_blit_pixel(&c, &dst[i], 32/*bpp of const color*/, p->bpp, p->bpp, GRAPHICS_FMT_ARGB_888, p->format, p->format, operation, alpha1, alpha2); } } else if(p->bpp == 16) { *((uint16_t*)tdst) = bgfx_blit_pixel(&c, &dst[i], 32/*bpp of const color*/, p->bpp, p->bpp, GRAPHICS_FMT_ARGB_888, p->format, p->format, operation, alpha1, alpha2) & 0xffff; } } dst += p->surface.pitch; } } else #endif { SGL_DEBUG(("multi surface alpha blending only support RGB surfaces.")); return -1; } bgfx_cacheflush(p->surface.buf, p->surface.pitch * p->surface.height); return 0; } #else int bgfx_blend_fill_rect(bgfx_surf_p p, uint16_t x,uint16_t y, uint16_t w, uint16_t h, bgfx_pixel c) { register uint8_t *dst; register uint32_t i, j; register uint32_t rt, gt, bt, rs, gs, bs, as; #ifdef CONFIG_BGFX_SURF_RGB register uint8_t *tdst; register uint32_t dst_step; register uint32_t dst_pitch; register uint32_t last_pixel=0; #endif if ((x >= p->surface.width) || (y >= p->surface.height)) { SGL_DEBUG(("bgfx_blend_fill_rect x,y (%d,%d) w,h (%d,%d)\n",x,y, p->surface.width,p->surface.height)); return -1; } dst = (uint8_t*)p->surface.buf; dst += (y * p->surface.pitch) + ((x * p->bpp)/8); if (w >= p->surface.width - x) w = p->surface.width - x; if (h >= p->surface.height - y) h = p->surface.height - y; /* Support available only for colorOp = eBlend and alphaOp = eIgnore */ SGL_TRACE(("w=%d", w)); SGL_TRACE(("h=%d", h)); dst_step = p->bpp / 8; dst_pitch = dst_step * w; #ifdef CONFIG_BGFX_SURF_RGB if (p->flags & BGFX_SURF_RGB) { if(p->bpp == 32) { as = (c >> 24) & 0xff; rs = (c >> 16) & 0xff; gs = (c >> 8) & 0xff; bs = c & 0xff; for (j = 0; j < h; ++j) { tdst = dst; for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step) { #ifdef COMPARE_PREVIOUS_PIXEL if(i > 0 && *(uint32_t*)(&dst[i]) == last_pixel) { *((uint32_t*)tdst) = *(uint32_t*)(tdst - dst_step); } else #endif { last_pixel = *(uint32_t*)(&dst[i]); { rt = (last_pixel >> 16) & 0xff; gt = (last_pixel >> 8) & 0xff; bt = last_pixel & 0xff; rt = (rs * as + (256 - as) * rt) >> 8; gt = (gs * as + (256 - as) * gt) >> 8; bt = (bs * as + (256 - as) * bt) >> 8; *(uint32_t*)(&dst[i]) = (last_pixel & 0xff000000) | (rt << 16) | (gt << 8) | bt ; } } } dst += p->surface.pitch; } } else if(p->bpp == 16) { as = (c >> 12) & 0xf; rs = (c >> 8) & 0xf; gs = (c >> 4) & 0xf; bs = c & 0xf; for (j = 0; j < h; ++j) { tdst = dst; for(i = 0; i < dst_step * w; i += dst_step, tdst += dst_step) { last_pixel = *(uint16_t*)(&dst[i]); { rt = (last_pixel >> 8) & 0xf; gt = (last_pixel >> 4) & 0xf; bt = last_pixel & 0xf; rt = (rs * as + (16 - as) * rt) >> 4; gt = (gs * as + (16 - as) * gt) >> 4; bt = (bs * as + (16 - as) * bt) >> 4; *(uint16_t*)(&dst[i]) = (last_pixel & 0xf000) | (rt << 8) | (gt << 4) | bt ; } } dst += p->surface.pitch; } } } else #endif { SGL_DEBUG(("multi surface alpha blending only support RGB surfaces.")); return -1; } bgfx_cacheflush(p->surface.buf, p->surface.pitch * p->surface.height); return 0; } #endif /**************************************************************** * Copy a rectangle area from one surface to the other with scaling. * Copy the source surface at (sx,sy) to the destination at (dx,dy) ****************************************************************/ int bgfx_blit_rect_scale(bgfx_surf_p p_src, /* pointer to initialized source surface structure */ bgfx_surf_p p_dst, /* pointer to initialized destination surface structure */ uint16_t sx, /* source horizontal location in pixels */ uint16_t sy, /* source vertical location in pixels */ uint16_t dx, /* destination horizontal location in pixels */ uint16_t dy, /* destination vertical location in pixels */ uint16_t sw, /* source width in pixel */ uint16_t sh,/* source height in pixel */ uint16_t dw,/* destination width in pixel*/ uint16_t dh) /* destination width in pixel*/ { uint8_t *dst,*src; #ifdef CONFIG_BGFX_SURF_RGB uint32_t h_int_step, v_int_step; register uint32_t src_i, src_j,cur_y,cur_x,i,j,*pdst,*psrc; #endif if( (NULL == p_src) || (NULL == p_dst)) { return BERR_TRACE(NEXUS_INVALID_PARAMETER); } if ((dx >= p_dst->surface.width) || (dy >= p_dst->surface.height)) { SGL_DEBUG(("bgfx_blit_rect_scale dst_x,dst_y (%d,%d) outside destination (%d,%d) ",dx,dy, p_dst->surface.width,p_dst->surface.height)); return -1; } if ((sx >= p_src->surface.width) || (sy >= p_src->surface.height)) { SGL_DEBUG(("bgfx_blit_rect_scale src_x,src_y (%d,%d) outside source (%d,%d) ",sx,sy, p_src->surface.width,p_src->surface.height)); return -1; } /* only same pixelformat scaling is supported now.*/ src = (uint8_t*)p_src->surface.buf; src += (sy * p_src->surface.pitch) + (sx * (p_src->bpp >> 3)); dst = (uint8_t*)p_dst->surface.buf; dst += (dy * p_dst->surface.pitch) + (dx * (p_dst->bpp >> 3)); /* adjust width and height */ if (sw >= (p_src->surface.width - sx)) sw= p_src->surface.width - sx; if (dw >= p_dst->surface.width - dx) dw = p_dst->surface.width - dx; if (sh >= (p_src->surface.height - sy)) sh= p_src->surface.height - sy; if (dh >= p_dst->surface.height - dy) dh = p_dst->surface.height - dy; h_int_step = ((sw << _BGFX_CALC_OFFSET) / dw); v_int_step = ((sh << _BGFX_CALC_OFFSET) / dh); #ifdef CONFIG_BGFX_SURF_RGB if (p_dst->flags & BGFX_SURF_RGB) { cur_y = 0; for( i = 0; i < dh; i++ ) { cur_y += v_int_step; src_i = (cur_y - v_int_step) >> _BGFX_CALC_OFFSET; psrc = (uint32_t*)(src + p_src->surface.pitch * src_i); pdst = (uint32_t*)(dst + p_dst->surface.pitch * i); cur_x = 0; for (j = 0; j < dw;j++) { cur_x += h_int_step; src_j = (cur_x - h_int_step) >> _BGFX_CALC_OFFSET; pdst[j] = psrc[src_j]; } } } #endif bgfx_cacheflush(p_dst->surface.buf,p_dst->surface.pitch * p_dst->surface.height); return 0; } /**************************************************************** * Copy a rectangle area from one surface to the other with scaling. * Copy the source surface at (sx,sy) to the destination at (dx,dy) ****************************************************************/ int bgfx_blit_rect_scale_v_up_h_up(bgfx_surf_p p_src, /* pointer to initialized source surface structure */ bgfx_surf_p p_dst, /* pointer to initialized destination surface structure */ uint16_t sx, /* source horizontal location in pixels */ uint16_t sy, /* source vertical location in pixels */ uint16_t dx, /* destination horizontal location in pixels */ uint16_t dy, /* destination vertical location in pixels */ uint16_t sw, /* source width in pixel */ uint16_t sh,/* source height in pixel */ uint16_t dw,/* destination width in pixel*/ uint16_t dh) /* destination width in pixel*/ { uint8_t *line_p_src, *line_p_dst; uint8_t *pxl_p_src, *pxl_p_dst; register uint32_t i, j, k, cur_y, cur_x, dst_x, dst_y, next_x, next_y; uint32_t h_scl_step, v_scl_step; uint32_t pixel_bytes, vs_line_shift; int as, rs, gs, bs; int at, rt, gt, bt; /* May be negative */ uint32_t pxl_t; /* printf("\n!!! bgfx_blit_rect_scale_v_up_h_up: (%d, %d, %d, %d)=> (%d, %d, %d, %d)\n", sx, sy, sw, sh, dx, dy, dw, dh); */ pixel_bytes = p_src->bpp >> 3; h_scl_step = ((dw << _BGFX_CALC_OFFSET) / sw); v_scl_step = ((dh << _BGFX_CALC_OFFSET) / sh); /* Horizontal scaling */ cur_y = 0; /* dst_y = 0; */ line_p_src = (uint8_t*)p_src->surface.buf; line_p_src += p_src->surface.pitch * sy; line_p_dst = (uint8_t*)p_dst->surface.buf; line_p_dst += p_dst->surface.pitch * dy; for (i = 0; i < sh; i++) { pxl_p_src = line_p_src + pixel_bytes * sx; pxl_p_dst = line_p_dst + pixel_bytes * dx; dst_x = 0; cur_x = 0; for(j = 0; j < (uint32_t)(sw - 1); j++) { cur_x += h_scl_step; next_x = cur_x >> _BGFX_CALC_OFFSET; pxl_t = *(uint32_t*)pxl_p_src; as = ((pxl_t >> 24) & 0xff) << _BGFX_CALC_OFFSET; rs = ((pxl_t >> 16) & 0xff) << _BGFX_CALC_OFFSET; gs = ((pxl_t >> 8) & 0xff) << _BGFX_CALC_OFFSET; bs = (pxl_t & 0xff) << _BGFX_CALC_OFFSET; pxl_t = *((uint32_t*)(pxl_p_src + pixel_bytes)); at = ((pxl_t >> 24) & 0xff) << _BGFX_CALC_OFFSET; rt = ((pxl_t >> 16) & 0xff) << _BGFX_CALC_OFFSET; gt = ((pxl_t >> 8) & 0xff) << _BGFX_CALC_OFFSET; bt = (pxl_t & 0xff) << _BGFX_CALC_OFFSET; at = (at - as) / (int)(next_x - dst_x); rt = (rt - rs) / (int)(next_x - dst_x); gt = (gt - gs) / (int)(next_x - dst_x); bt = (bt - bs) / (int)(next_x - dst_x); /* printf("!!! (%d, %d, %d), 0x%08x, (%d, %d, %d)\n", rs, gs, bs, pxl_t, rt, gt, bt); */ for(k = dst_x; k < next_x; k++) { /* printf("!!! I read src %d and write to dst %d\n", j, k); */ *((uint32_t*)pxl_p_dst) = ((as >>_BGFX_CALC_OFFSET) << 24) | ((rs >>_BGFX_CALC_OFFSET) << 16) | ((gs >>_BGFX_CALC_OFFSET) << 8) | (bs >>_BGFX_CALC_OFFSET) ; pxl_p_dst += pixel_bytes; as += at; rs += rt; gs += gt; bs += bt; } pxl_p_src += pixel_bytes; dst_x = next_x; } /* margin pixels*/ while (dst_x < dw) { *((uint32_t*)pxl_p_dst) = *((uint32_t*)pxl_p_src); dst_x++; pxl_p_dst += pixel_bytes; } line_p_src += p_src->surface.pitch; cur_y += v_scl_step; next_y = cur_y >> _BGFX_CALC_OFFSET; #if 1 line_p_dst = p_dst->surface.buf; line_p_dst += (p_dst->surface.pitch * (dy +next_y)); #else line_p_dst += (p_dst->surface.pitch); #endif } #if 1 /* Vertical scaling "source" are actually lines in dest surface*/ dst_y = 0; cur_y = 0; line_p_dst = (uint8_t*)p_dst->surface.buf; line_p_dst += p_dst->surface.pitch * dy; for (i = 0; i < (uint32_t)(sh - 1); i++) { pxl_p_dst = line_p_dst + pixel_bytes * dx; pxl_p_src = line_p_dst + pixel_bytes * dx; cur_y += v_scl_step; next_y = cur_y >> _BGFX_CALC_OFFSET; vs_line_shift = (p_dst->surface.pitch * (next_y - dst_y)); for(j = 0; j < dw; j++) { pxl_t = *(uint32_t*)pxl_p_src; as = ((pxl_t >> 24) & 0xff) << _BGFX_CALC_OFFSET; rs = ((pxl_t >> 16) & 0xff) << _BGFX_CALC_OFFSET; gs = ((pxl_t >> 8) & 0xff) << _BGFX_CALC_OFFSET; bs = (pxl_t & 0xff) << _BGFX_CALC_OFFSET; pxl_t = *((uint32_t*)(pxl_p_src + vs_line_shift)); at = ((pxl_t >> 24) & 0xff) << _BGFX_CALC_OFFSET; rt = ((pxl_t >> 16) & 0xff) << _BGFX_CALC_OFFSET; gt = ((pxl_t >> 8) & 0xff) << _BGFX_CALC_OFFSET; bt = (pxl_t & 0xff) << _BGFX_CALC_OFFSET; at = (at - as) / (int)(next_y - dst_y); rt = (rt - rs) / (int)(next_y - dst_y); gt = (gt - gs) / (int)(next_y - dst_y); bt = (bt -bs) / (int)(next_y - dst_y); /* printf("!!! (%d, %d, %d), 0x%08x, (%d, %d, %d)\n", rs, gs, bs, pxl_t, rt, gt, bt); */ for(k = dst_y; k < next_y; k++) { *((uint32_t*)pxl_p_dst) = ((as >>_BGFX_CALC_OFFSET) << 24) | ((rs >>_BGFX_CALC_OFFSET) << 16) | ((gs >>_BGFX_CALC_OFFSET) << 8) | (bs >>_BGFX_CALC_OFFSET) ; pxl_p_dst += p_dst->surface.pitch; as += at; rs += rt; gs += gt; bs += bt; } pxl_p_src += pixel_bytes; pxl_p_dst = pxl_p_src; } line_p_dst += vs_line_shift; dst_y = next_y; } /* margin pixels*/ dst_y++; line_p_dst = p_dst->surface.buf; line_p_dst += p_dst->surface.pitch * dst_y + pixel_bytes * dx; /* line pointer shift */ while ( dst_y <= dh ) { memcpy(line_p_dst, (line_p_dst - p_dst->surface.pitch), pixel_bytes * dw); dst_y++; line_p_dst += p_dst->surface.pitch; } #endif return 0; } /**************************************************************** * Copy a rectangle area from one surface to the other with scaling. * Copy the source surface at (sx,sy) to the destination at (dx,dy) ****************************************************************/ int bgfx_blit_rect_scale_v_down_h_down(bgfx_surf_p p_src, /* pointer to initialized source surface structure */ bgfx_surf_p p_dst, /* pointer to initialized destination surface structure */ uint16_t sx, /* source horizontal location in pixels */ uint16_t sy, /* source vertical location in pixels */ uint16_t dx, /* destination horizontal location in pixels */ uint16_t dy, /* destination vertical location in pixels */ uint16_t sw, /* source width in pixel */ uint16_t sh,/* source height in pixel */ uint16_t dw,/* destination width in pixel*/ uint16_t dh) /* destination width in pixel*/ { uint8_t *line_p_dst; uint8_t *pxl_p_src, *pxl_p_dst; register uint32_t i, j, ii, jj, cur_y, cur_x, src_x, src_y, next_x, next_y; uint32_t h_scl_step, v_scl_step; uint32_t pixel_bytes, vs_pxl_cnt; uint8_t as, rs, gs, bs; int at, rt, gt, bt; /* May be negative */ uint32_t pxl_t; /* printf("\n!!! bgfx_blit_rect_scale_v_down_h_down: (%d, %d, %d, %d)=> (%d, %d, %d, %d)\n", sx, sy, sw, sh, dx, dy, dw, dh); */ pixel_bytes = p_src->bpp >> 3; h_scl_step = ((sw << _BGFX_CALC_OFFSET) /dw); v_scl_step = ((sh << _BGFX_CALC_OFFSET) / dh); /* Horizontal scaling */ src_y = 0; cur_y = 0; line_p_dst = p_dst->surface.buf; line_p_dst += p_dst->surface.pitch * dy; for (i = 0; i < dh; i++) { pxl_p_dst = line_p_dst + pixel_bytes * dx; cur_y += v_scl_step; next_y = cur_y >> _BGFX_CALC_OFFSET; src_x = 0; cur_x = 0; for(j = 0; j < dw; j++) { cur_x += h_scl_step; next_x = cur_x >> _BGFX_CALC_OFFSET; vs_pxl_cnt = (next_x - src_x) * (next_y - src_y); at = rt = gt = bt = 0; /* Accumulation */ for (ii = src_y; ii < next_y; ii++) { pxl_p_src = (uint8_t*)p_src->surface.buf; pxl_p_src += p_src->surface.pitch * sy + pixel_bytes * sx; pxl_p_src += (p_src->surface.pitch * ii + pixel_bytes * src_x); for (jj = src_x; jj < next_x; jj++) { pxl_t = *(uint32_t*)pxl_p_src; as = (pxl_t >> 24) & 0xff; rs = (pxl_t >> 16) & 0xff; gs = (pxl_t >> 8) & 0xff; bs = pxl_t & 0xff; at += as; rt += rs; gt += gs; bt += bs; pxl_p_src += pixel_bytes; } } as = ((at << 4) / vs_pxl_cnt + 8) >> 4; rs = ((rt << 4) / vs_pxl_cnt + 8) >> 4; gs = ((gt << 4) / vs_pxl_cnt + 8) >> 4; bs = ((bt << 4) / vs_pxl_cnt + 8) >> 4; *((uint32_t*)pxl_p_dst) = (as << 24) |(rs << 16) | (gs << 8) | bs ; pxl_p_dst += pixel_bytes; src_x = next_x; } line_p_dst += (p_dst->surface.pitch); src_y = next_y; } return 0; }