source: svn/trunk/newcon3bcm2_21bu/nexus/lib/softgfx/src/bgfx.c @ 2

Last change on this file since 2 was 2, checked in by phkim, 11 years ago

1.phkim

  1. revision copy newcon3sk r27
  • Property svn:executable set to *
File size: 146.9 KB
Line 
1/***************************************************************
2**     (c)2009-2010 Broadcom Corporation
3** 
4**  This program is the proprietary software of Broadcom Corporation and/or its licensors,
5**  and may only be used, duplicated, modified or distributed pursuant to the terms and
6**  conditions of a separate, written license agreement executed between you and Broadcom
7**  (an "Authorized License").  Except as set forth in an Authorized License, Broadcom grants
8**  no license (express or implied), right to use, or waiver of any kind with respect to the
9**  Software, and Broadcom expressly reserves all rights in and to the Software and all
10**  intellectual property rights therein.  IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU
11**  HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY
12**  NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE. 
13**   
14**  Except as expressly set forth in the Authorized License,
15**   
16**  1.     This program, including its structure, sequence and organization, constitutes the valuable trade
17**  secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof,
18**  and to use this information only in connection with your use of Broadcom integrated circuit products.
19**   
20**  2.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
21**  AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
22**  WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
23**  THE SOFTWARE.  BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES
24**  OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE,
25**  LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION
26**  OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF
27**  USE OR PERFORMANCE OF THE SOFTWARE.
28** 
29**  3.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS
30**  LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR
31**  EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR
32**  USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF
33**  THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT
34**  ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
35**  LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF
36**  ANY LIMITED REMEDY.
37**
38** Created: 8/22/2002 by Jeffrey P. Fisher
39**
40** $brcm_Workfile: bgfx.c $
41** $brcm_Revision: Refsw_7550/10 $
42** $brcm_Date: 4/14/10 3:29p $
43**
44** Revision History:
45**
46** $brcm_Log: /nexus/lib/softgfx/src/bgfx.c $
47**
48** Refsw_7550/10   4/14/10 3:29p gautamk
49** SW7550-369:[7550] Fixing compilation warning
50**
51** Refsw_7550/9   4/8/10 6:38p gautamk
52** SW7550-369:[7550] Merging Scaling feature of softgfx to mainline.
53**
54** Refsw_7550/SWARTEMIS-10/4   3/26/10 6:57p gezhang
55** SW7550-208: Require stretch-BLIT function on soft-gfx lib
56**
57** Refsw_7550/8   2/18/10 11:09a kagrawal
58** SW7550-265: Added CSC from ARGB8888 to AYCbCr8888
59**
60** Refsw_7550/8   2/18/10 10:51a kagrawal
61** SW7550-265: Added CSC from ARGB8888 to AYCbCr8888
62**
63** Refsw_7550/6   11/26/09 11:27a kagrawal
64** SW7550-77: Fixed compile time warning
65**
66** Refsw_7550/5   11/5/09 9:41a kagrawal
67** SW7550-59: Added special cases when as=0 and at=0 for further
68**  optimizing alpha-blending
69**
70** Refsw_7550/4   11/4/09 3:57p kagrawal
71** SW7550-59: Fix incorrect bt extraction (which was over-writing at) in
72**  bgfx_blit_pixel_ARGB8888_optimized()
73**
74** Refsw_7550/3   11/4/09 11:10a kagrawal
75** SW7550-59: Performance optimazation
76** - Alpha-blend for operation 0x33
77** - Fill, BLT are using memcpy()
78** - Alpha-blended Fill is comparing previous pixels
79**
80** Refsw_7550/2   9/25/09 12:54p kagrawal
81** SW7550-50: Performance optimized gfx from 7003 latest
82**
83** Refsw_7550/1   9/7/09 5:04p kagrawal
84** SW7550-3: Initial check-in for Soft Graphics
85**
86****************************************************************/
87
88/** include files **/
89//#define BDISPATCH_BYPASS
90#include "bgfx.h"
91#include <string.h>
92#include <stdlib.h>
93
94#undef BDISPATCH_BYPASS
95#if !defined LINUX && !defined B_OS_UCOS_II
96#include "bdispatch.h"
97#endif
98#if SOFT_GFX_AS_IN_7003
99#include "bpxl.h"
100#endif
101
102BDBG_MODULE(bgfx);
103
104#define GRAPHICS_FMT_P4 NEXUS_PixelFormat_ePalette4
105#define GRAPHICS_FMT_P8 NEXUS_PixelFormat_ePalette8
106#define GRAPHICS_FMT_ARGB_888 NEXUS_PixelFormat_eA8_R8_G8_B8
107#define GRAPHICS_FMT_RGBA_888 NEXUS_PixelFormat_eR8_G8_B8_A8
108#define GRAPHICS_FMT_AYCbCr_888 NEXUS_PixelFormat_eA8_Y8_Cb8_Cr8
109#define GRAPHICS_FMT_RGB_565  NEXUS_PixelFormat_eR5_G6_B5
110#define GRAPHICS_FMT_WRGB_1555 NEXUS_PixelFormat_eA1_R5_G5_B5
111#define GRAPHICS_FMT_RGBW_5551 NEXUS_PixelFormat_eR5_G5_B5_A1
112#define GRAPHICS_FMT_ARGB_4444 NEXUS_PixelFormat_eA4_R4_G4_B4
113#define GRAPHICS_FMT_RGBA_4444 NEXUS_PixelFormat_eR4_G4_B4_A4
114
115#define ZORDER_TUNNEL   3
116#define ZORDER_FX       2
117#define ZORDER_TOP      1
118#define ZORDER_BOTTOM   0
119
120
121#define SURF_WIDTH 720
122
123#define BGFX_MIN(x,y)   ((x < y) ? x : y)
124#define bgfx_valid_flags(x) ((x & BGFX_SURF_RGB) ? (x & BGFX_SURF_PRIMARY) : 1)
125#define bgfx_clut8_to_rgb(clut,c) (uint32_t)(clut[c])
126
127#if SOFT_GFX_AS_IN_7003
128#define CONFIG_BGFX_SURF_RGB
129#define SIMPLE_BLENDING_FORMULA
130#define COMPARE_PREVIOUS_PIXEL
131#endif
132
133#define _BGFX_CALC_OFFSET 10   
134
135
136/*******************************************************************************
137Color Space Conversion Equations:
138o       RGB -> YCrCb
139        RGB    [0..255]
140        Y        [16..235]
141        Cb/Cr [16..240]
142
143o       ITU-R BT.601:
144        Y  =  (0.257 * R) + (0.504 * G) + (0.098 * B) + 16
145        Cb = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128
146        Cr =  (0.439 * R) - (0.368 * G) - (0.071 * B) + 128
147
148        For fixed point software this becomes
149        Y  =   66*R/256   +  129*G/256   +  25*B/256 + 16
150        Cb =  -38*R/256   -   74*G/256   + 112*B/256 + 128
151        Cr =  112*R/256   -   94*G/256   -  18*B/256 + 128
152
153o       ITU-R BT.709:
154        Y  =  (0.183 * R) + (0.614 * G) + (0.062 * B) + 16
155        Cb = -(0.101 * R) - (0.339 * G) + (0.439 * B) + 128
156        Cr =  (0.439 * R) - (0.339 * G) - (0.040 * B) + 128
157
158        For fixed point software this becomes
159        Y  =   47*R/256   +  157*G/256   +  16*B/256 + 16
160        Cb =  -26*R/256   -   87*G/256   + 112*B/256 + 128
161        Cr =  112*R/256   -   87*G/256   -  10*B/256 + 128
162*******************************************************************************/
163#define bgfx_csc_BT_601_RGB_2_YCbCr_macro(Y, Cb, Cr, R, G, B)   \
164        {                                                           \
165        Y  =  ((66*R + 129*G + 25*B) >> 8) + 16;                \
166        Cb =  ((-38*R - 74*G + 112*B) >> 8) + 128;              \
167        Cr =  ((112*R - 94*G - 18*B) >> 8) + 128;               \
168        }
169
170#define bgfx_csc_BT_709_RGB_2_YCbCr_macro(Y, Cb, Cr, R, G, B)   \
171        {                                                           \
172        Y  =  ((47*R + 157*G + 16*B) >> 8) + 16;                \
173        Cb =  ((-26*R - 87*G + 112*B) >> 8) + 128;              \
174        Cr =  ((112*R - 87*G - 10*B) >> 8) + 128;               \
175        }
176
177#define bgfx_csc_RGB_2_YCbCr_macro_org(At, Y, Cb, Cr, As, R, G, B)      \
178        {                                                           \
179        Y  = ((m0*R + m1*G + m2*B + m3*As + m4) >> shift);      \
180        Cb = ((m5*R + m6*G + m7*B + m8*As + m9) >> shift);      \
181        Cr = ((m10*R + m11*G + m12*B + m13*As + m14) >> shift); \
182        At = ((m15*R + m16*G + m17*B + m18*As + m19) >> shift); \
183        }
184
185#define bgfx_csc_RGB_2_YCbCr_macro(At, Y, Cb, Cr, As, R, G, B)  \
186        {                                                           \
187        Y  = ((m0*R + m1*G + m2*B + m4) >> shift);      \
188        Cb = ((m5*R + m6*G + m7*B + m9) >> shift);      \
189        Cr = ((m10*R + m11*G + m12*B + m14) >> shift);  \
190        }
191
192
193/*
194   SW_ANTI_FLUTTER_FILTER_HORIZONTAL
195 */
196
197/* blit row a1 to clut 8 destination */
198static inline void bgfx_render_a1_to_clut4( uint8_t *src, uint8_t *dst, 
199                                                                                        int width, uint8_t c, int odd_pixel )
200{
201        int i;
202
203        SGL_TRACE(("%p,%p,%d,0x%02x ",src,dst,width,c));
204        for (i = 0; i < width; i++)
205        {
206                if (src[i>>3] & (1<<(7-(i%8))))
207                {
208                        if (odd_pixel & 1)
209                        {
210                                *dst &= 0xF0;
211                                *dst |= (c & 0xF);
212                        }
213                        else
214                        {
215                                *dst &= 0xF;
216                                *dst |= (c & 0xF) << 4;
217                        }
218                        SGL_TRACE(("%d,",i));
219                }
220                if (odd_pixel)
221                {
222                        odd_pixel = 0;
223                        dst++;
224                }
225                else
226                        odd_pixel = 1;
227
228        }
229        SGL_TRACE(("\n"));
230}
231
232/* blit row a8 to clut 8 destination */
233static inline void bgfx_render_a8_to_clut4( uint8_t *src, uint8_t *dst, int width, uint8_t c )
234{
235        int i;
236        for (i = 0; i < width; i++)
237        {
238                if (*src > 0x80)
239                {
240                        if (i & 1)
241                        {
242                                *dst &= 0xF0;
243                                *dst |= (c & 0xF);
244                        }
245                        else
246                        {
247                                *dst &= 0xF;
248                                *dst |= (c & 0xF) << 4;
249                        }
250                }
251                SGL_TRACE(("0x%02x(0x%02x)",*src,*dst));
252                if (i & 1)
253                        dst++;
254                src++;
255        }
256        SGL_TRACE(("\n"));
257}
258
259
260/* blit row a1 to clut 8 destination */
261static inline void bgfx_render_a1_to_clut8( uint8_t *src, uint8_t *dst, int width, uint8_t c )
262{
263        int i;
264
265        SGL_TRACE(("%p,%p,%d,0x%02x ",src,dst,width,c));
266        for (i = 0; i < width; i++)
267        {
268                if (src[i>>3] & (1<<(7-(i%8))))
269                {
270                        *dst = c;
271                        SGL_TRACE(("%d,",i));
272                }
273                dst++;
274        }
275        SGL_TRACE(("\n"));
276}
277/* blit row a8 to clut 8 destination */
278static inline void bgfx_render_a8_to_clut8( uint8_t *src, uint8_t *dst, int width, uint8_t c )
279{
280        int i;
281        for (i = 0; i < width; i++)
282        {
283                if (*src > 0x80)
284                {
285                        *dst = c;
286                }
287                SGL_TRACE(("0x%02x(0x%02x)",*src,*dst));
288                dst++;
289                src++;
290        }
291        SGL_TRACE(("\n"));
292}
293
294#ifdef CONFIG_BGFX_SURF_RGB
295
296#if SOFT_GFX_AS_IN_7003
297/* Raymond, GFX convert ARGB input to other graphic format, 20090304 */
298static BPXL_Format bgfx_colorformat_mapping(NEXUS_PixelFormat format)
299{
300        switch(format)
301        {
302                case GRAPHICS_FMT_P4:
303                        return BPXL_eP4;
304                case GRAPHICS_FMT_P8:
305                        return BPXL_eP8;
306                case GRAPHICS_FMT_ARGB_888:
307                        return BPXL_eA8_R8_G8_B8;
308                case GRAPHICS_FMT_RGBA_888:
309                        return BPXL_eR8_G8_B8_A8;
310                case GRAPHICS_FMT_RGB_565:
311                        return BPXL_eR5_G6_B5;
312                case GRAPHICS_FMT_WRGB_1555:
313                        return BPXL_eW1_R5_G5_B5;
314                case GRAPHICS_FMT_RGBW_5551:
315                        return BPXL_eR5_G5_B5_W1;
316                case GRAPHICS_FMT_ARGB_4444:
317                        return BPXL_eA4_R4_G4_B4;
318                case GRAPHICS_FMT_RGBA_4444:
319                        return BPXL_eR4_G4_B4_A4;
320                default:
321                        return BPXL_eR5_G6_B5;
322        }
323}
324#endif
325
326/* blit row a1 to 8888 ARGB destination */
327static inline void bgfx_render_a1_to_rgb( uint8_t *src, uint8_t *dst, int width, uint32_t c )
328{
329        int i;
330
331        SGL_TRACE(("%p,%p,%d,0x%02lx ",src,dst,width,c));
332        for (i = 0; i < width; i++)
333        {
334                if (src[i>>3] & (1<<(7-(i%8))))
335                {
336                        *((uint32_t*)dst) = c;
337                        SGL_TRACE(("%d,",i));
338                }
339                dst += 4;
340        }
341        SGL_TRACE(("\n"));
342}
343
344/* blit row a8 to 8888 ARGB destination */
345/*
346        #define SGL_BLEND(a,rs,rd)      (((rs * a)/0xFF) + (rd - ((a * rd)/0xFF)) & 0xFF)
347*/
348#define SGL_BLEND(a,rs,rd)      ((a * (rs-rd) >> 8) + rd)
349static inline void bgfx_render_a8_to_rgb( uint8_t *src, uint8_t *dst, int width, uint32_t c)
350{
351        register int i;
352        register uint32_t a,r,g,b;
353        register uint32_t a_src;
354        register uint32_t r_src =  (c >> 16) & 0xFF;
355        register uint32_t g_src =  (c >> 8) & 0xFF;
356        register uint32_t b_src =  (c >> 0) & 0xFF;
357        for (i = 0; i < width; i++)
358        {
359                a_src = *src;
360                a = dst[3]; r =  dst[2]; g =  dst[1]; b =  dst[0];
361                *((uint32_t*)dst) = (a << 24) |
362                                                        (SGL_BLEND(a_src,r_src,r) << 16) |
363                                                        (SGL_BLEND(a_src,g_src,g) << 8) |
364                                                        SGL_BLEND(a_src,b_src,b);
365                SGL_TRACE(("0x%02x(0x%08x)",*src,*((uint32_t*)dst)));
366                dst += 4;
367                src++;
368        }
369        SGL_TRACE(("\n"));
370}
371#endif
372
373/****************************************************************}
374* INPUTS:       io and protection function structures
375* OUTPUTS:      none
376* RETURNS:      non-zero on failure
377* FUNCTION: initialize sgl, primarily for handling freetype
378*
379****************************************************************/
380int bgfx_init(bgfx_io_t *io_p,bgfx_prot_t *prot_p)
381{
382        bgfx_config(io_p,prot_p);
383        return bgfx_font_init();
384}
385/****************************************************************}
386* INPUTS:       none
387* OUTPUTS:      none
388* RETURNS:      non-zero on failure
389* FUNCTION: release sgl global resources, primarily for handling freetype
390*
391****************************************************************/
392void bgfx_done(void)
393{
394        bgfx_font_done();
395}
396
397/****************************************************************}
398* bgfx_create
399*
400* INPUTS:       node_name - name of the node to create surface in
401*           p - surface structure to initialize
402* OUTPUTS:      none
403* RETURNS:      non-zero on failure
404* FUNCTION: initialize and create the surface.
405*
406****************************************************************/
407#if SOFT_GFX_AS_IN_7003
408int bgfx_create(bgfx_surf_p p,uint16_t width,uint16_t height, uint16_t x_pos, uint16_t y_pos,
409                           uint8_t      *ptr, uint16_t pitch,
410                           bgfx_palette_t *palette,
411                           uint32_t flags)
412{
413        /* keep current format */
414        int format = p->format;
415
416        BDBG_MSG(("bgfx_create - format = %d ", format));
417        BDBG_MSG(("bgfx_create - flags = 0x%lx ", flags));
418
419        SGL_MEMSET(p,0,sizeof(bgfx_surf_t));
420
421        if (!ptr && (flags & BGFX_SURF_PRIMARY))
422        {
423                SGL_DEBUG(("bgfx_create SGL_SURF_FULLSCREEN requires valid memory ptr. "));
424        }
425
426        p->format = format;
427        switch (format)
428        {
429                case GRAPHICS_FMT_ARGB_888:
430                case GRAPHICS_FMT_RGBA_888:
431                case GRAPHICS_FMT_AYCbCr_888:
432                        p->bpp = 32;
433                        break;
434
435                case GRAPHICS_FMT_RGB_565:
436                case GRAPHICS_FMT_WRGB_1555:
437                case GRAPHICS_FMT_RGBW_5551:
438                case GRAPHICS_FMT_ARGB_4444:
439                case GRAPHICS_FMT_RGBA_4444:
440                        p->bpp = 16;
441                        break;
442
443                case GRAPHICS_FMT_P4:
444                        p->bpp = 4;
445                        break;
446                case GRAPHICS_FMT_P8:
447                        p->bpp = 8;
448                        break;
449
450                default:
451                        SGL_DEBUG(("%s: unsupported format %d", __func__, format));
452                        p->bpp = 4;
453                        break;
454        }
455
456        //p->bpp = 4; /* = 8bpp TODO support 4bpp */
457        p->flags = flags;
458        if (ptr)
459        {
460                p->surface.pitch = pitch;
461                p->surface.buf = ptr;
462                p->surface.width = width;
463                p->surface.height = height;
464                p->surface.x = 0;
465                p->surface.y = 0;
466        }
467        else
468        {
469                p->surface.pitch = width * (p->bpp >> 3);
470                if (p->surface.pitch & 0x1)
471                        p->surface.pitch += 1;
472
473                p->surface.width = width;
474                p->surface.height = height;
475                p->surface.buf = SGL_MALLOC(p->surface.pitch * p->surface.height);
476                p->flags |= BGFX_SURF_ALLOC;
477                p->surface.x = x_pos;
478                p->surface.y = y_pos;
479        }
480
481        if (palette)
482        {
483                if(p->format == GRAPHICS_FMT_P4)
484                        SGL_MEMCPY(&p->palette,palette, sizeof(uint32_t) << 4);
485                else if(p->format == GRAPHICS_FMT_P8)
486                        SGL_MEMCPY(&p->palette,palette, sizeof(uint32_t) << 8);
487                //SGL_MEMCPY(&p->palette,palette,sizeof(bgfx_palette_t));
488        }
489        return 0;
490}
491#else
492int bgfx_create(bgfx_surf_p p,uint16_t width,uint16_t height,
493                           uint8_t      *ptr, uint16_t pitch,
494                           bgfx_palette_t *palette,
495                           uint32_t flags)
496{
497        SGL_MEMSET(p,0,sizeof(bgfx_surf_t));
498
499        if (!ptr && (flags & BGFX_SURF_PRIMARY))
500        {
501                SGL_DEBUG(("bgfx_create SGL_SURF_FULLSCREEN requires valid memory ptr. "));
502        }
503
504        p->bpp = 4; /* = 8bpp TODO support 4bpp */
505        p->flags = flags;
506        if (ptr)
507        {
508                p->surface.pitch = pitch;
509                p->surface.buf = ptr;
510                p->surface.width = width;
511                p->surface.height = height;
512        }
513        else
514        {
515                p->surface.pitch = width * p->bpp / 8;
516                if (p->surface.pitch & 0x1)
517                        p->surface.pitch += 1;
518
519                p->surface.width = width;
520                p->surface.height = height;
521                p->surface.buf = SGL_MALLOC(p->surface.pitch * p->surface.height);
522                p->flags |= BGFX_SURF_ALLOC;
523        }
524
525        if (palette)
526        {
527                SGL_MEMCPY(&p->palette,palette,sizeof(bgfx_palette_t));
528        }
529        return 0;
530}
531#endif
532/****************************************************************
533* bgfx_destroy
534*
535* INPUTS:       p - surface structure
536* OUTPUTS:      none
537* RETURNS:      none
538* FUNCTION:     free up surface resources
539*
540****************************************************************/
541void bgfx_destroy(bgfx_surf_p p)
542{
543        if (p->flags & BGFX_SURF_ALLOC)
544        {
545                SGL_FREE(p->surface.buf);
546                p->surface.buf = NULL;
547                return;
548        }
549}
550/****************************************************************
551* bgfx_get_info
552*
553* INPUTS:       p - surface structure
554* OUTPUTS:      w,h,flags - surface width,height and flags
555* RETURNS:      none
556* FUNCTION:     Return surface information (width,height, and flags)
557*
558****************************************************************/
559void bgfx_get_info(bgfx_surf_p p,uint16_t *w,uint16_t *h,uint16_t *pitch, uint32_t *flags)
560{
561        *w = p->surface.width;
562        *h = p->surface.height;
563        *pitch = p->surface.pitch;
564        *flags = p->flags;
565}
566/****************************************************************
567* bgfx_get_palette
568*
569* INPUTS:       p - surface structure
570* OUTPUTS:      palette_p - return current palette
571* RETURNS:      none
572* FUNCTION:     get the current palett
573*
574****************************************************************/
575#if SOFT_GFX_AS_IN_7003
576void bgfx_get_palette(bgfx_surf_p p,bgfx_palette_t *palette_p)
577{
578        if(p->format == GRAPHICS_FMT_P4)
579                SGL_MEMCPY(palette_p,&p->palette, sizeof(uint32_t) << 4);
580        else if(p->format == GRAPHICS_FMT_P8)
581                SGL_MEMCPY(palette_p,&p->palette, sizeof(uint32_t) << 8);
582//      SGL_MEMCPY(palette_p,&p->palette,sizeof(bgfx_palette_t));
583}
584#else
585void bgfx_get_palette(bgfx_surf_p p,bgfx_palette_t *palette_p)
586{
587        SGL_MEMCPY(palette_p,&p->palette,sizeof(bgfx_palette_t));
588}
589#endif
590/****************************************************************
591* bgfx_set_palette
592*
593* INPUTS:       p - surface structure
594*                       palette_p - the palette
595* OUTPUTS:      none
596* RETURNS:      none
597* FUNCTION:     set the global system palette
598*
599****************************************************************/
600#if SOFT_GFX_AS_IN_7003
601void bgfx_set_palette(bgfx_surf_p p, bgfx_palette_t *palette_p)
602{
603        if(p->format == GRAPHICS_FMT_P4)
604                SGL_MEMCPY(&p->palette,palette_p, sizeof(uint32_t) << 4);
605        else if(p->format == GRAPHICS_FMT_P8)
606                SGL_MEMCPY(&p->palette,palette_p, sizeof(uint32_t) << 8);
607//      SGL_MEMCPY(&p->palette,palette_p,sizeof(bgfx_palette_t));
608}
609#else
610void bgfx_set_palette(bgfx_surf_p p, bgfx_palette_t *palette_p)
611{
612        SGL_MEMCPY(&p->palette,palette_p,sizeof(bgfx_palette_t));
613}
614#endif
615/****************************************************************
616* bgfx_set_pixel
617*
618* INPUTS:       p - surface structure
619*                       x,y - coordinates
620*                       c - pixel value
621* OUTPUTS:      none
622* RETURNS:      none
623* FUNCTION:     set the pixel at x,y
624*
625****************************************************************/
626#if SOFT_GFX_AS_IN_7003
627void bgfx_set_pixel(bgfx_surf_p p,uint16_t x,uint16_t y,bgfx_pixel c)
628{
629        uint8_t *dst;
630
631#ifdef CONFIG_SGL_DEBUG
632        if ((x >= p->surface.width) || (y >= p->surface.height))
633        {
634                SGL_DEBUG(("bgfx_set_pixel param error (%p,%d,%d) ",p,x,y));
635                return;
636        }
637#endif
638
639        dst = (uint8_t*)p->surface.buf;
640        dst += y * p->surface.pitch + x * (p->bpp >> 3);
641#ifdef CONFIG_BGFX_SURF_RGB
642        if (p->flags & BGFX_SURF_RGB)
643        {
644                /* if RGB palette palette */
645                if (p->bpp <= 8) {
646                        /* make sure size of palette match if CLUT 8 is used */
647                        *((uint32_t*)dst) = bgfx_clut8_to_rgb(p->palette.clut,c);
648                        bgfx_cacheflush(dst,4);
649                }
650                else if (32 == p->bpp){
651                        *((uint32_t*)dst) = c;
652                        bgfx_cacheflush(dst, (p->bpp >> 3));
653                }
654                else {  /* For 16bit color format, Raymond, 20090304 */
655                        uint16_t c16;
656                        c = BPXL_MAKE_PIXEL(bgfx_colorformat_mapping(p->format),
657                                                                                        c>>24,
658                                                                                        (c>>16)&0xff,
659                                                                                        (c>>8)&0xff,
660                                                                                        c&0xff);
661                        c16 = (c & 0xffff);
662                        *((uint16_t*)dst) = c16;
663                        bgfx_cacheflush(dst, (p->bpp >> 3));
664                        return;
665                }
666        }
667        else
668#endif
669        {
670                /* AYUV P4 */
671                if(p->format == GRAPHICS_FMT_P4)
672                {
673                if (x & 1)
674                {
675                        *dst &= 0xF0;
676                        *dst |= (c & 0xF);
677                }
678                else
679                {
680                        *dst &= 0xF;
681                        *dst |= (c & 0xF) << 4;
682                }
683                }       
684                else if(p->format == GRAPHICS_FMT_P8)
685                {
686                        *dst &= 0x00;
687                        *dst |= (c & 0xFF);
688                }       
689                bgfx_cacheflush(dst,1);
690        }
691}
692
693void bgfx_set_pixel_direct(bgfx_surf_p p,uint16_t x,uint16_t y,bgfx_pixel c)
694{
695        uint8_t *dst;
696
697#ifdef CONFIG_SGL_DEBUG
698        if ((x >= p->surface.width) || (y >= p->surface.height))
699        {
700                SGL_DEBUG(("bgfx_set_pixel param error (%p,%d,%d) ",p,x,y));
701                return;
702        }
703#endif
704
705        dst = (uint8_t*)p->surface.buf;
706        dst += y * p->surface.pitch + x * (p->bpp >> 3);
707#ifdef CONFIG_BGFX_SURF_RGB
708        if (p->flags & BGFX_SURF_RGB)
709        {
710                /* if RGB palette palette */
711                if (p->bpp <= 8) {
712                        /* make sure size of palette match if CLUT 8 is used */
713                        *((uint32_t*)dst) = bgfx_clut8_to_rgb(p->palette.clut,c);
714                        bgfx_cacheflush(dst,4);
715                }
716                else if (32 == p->bpp){
717                        *((uint32_t*)dst) = c;
718                        bgfx_cacheflush(dst, (p->bpp >> 3));
719                }
720                else {  /* For 16bit color format, Raymond, 20090304 */
721                        uint16_t c16;
722                        c16 = (c & 0xffff);
723                        *((uint16_t*)dst) = c16;
724                        bgfx_cacheflush(dst, (p->bpp >> 3));
725                        return;
726                }
727        }
728        else
729#endif
730        {
731                /* AYUV P4 */
732                if(p->format == GRAPHICS_FMT_P4)
733                {
734                if (x & 1)
735                {
736                        *dst &= 0xF0;
737                        *dst |= (c & 0xF);
738                }
739                else
740                {
741                        *dst &= 0xF;
742                        *dst |= (c & 0xF) << 4;
743                }
744                }       
745                else if(p->format == GRAPHICS_FMT_P8)
746                {
747                        *dst &= 0x00;
748                        *dst |= (c & 0xFF);
749                }       
750                bgfx_cacheflush(dst,1);
751        }
752}
753#else
754void bgfx_set_pixel(bgfx_surf_p p,uint16_t x,uint16_t y,bgfx_pixel c)
755{
756        uint8_t *dst;
757
758        if ((x >= p->surface.width) || (y >= p->surface.height))
759        {
760                SGL_DEBUG(("bgfx_set_pixel param error (%p,%d,%d) ",p,x,y));
761                return;
762        }
763
764        dst = (uint8_t*)p->surface.buf;
765        dst += y * p->surface.pitch + (x * p->bpp)/8;
766#ifdef CONFIG_BGFX_SURF_RGB
767        if (p->flags & BGFX_SURF_RGB)
768        {
769                *((uint32_t*)dst) = bgfx_clut8_to_rgb(p->palette.clut,c);
770                bgfx_cacheflush(dst,4);
771        }
772        else
773#endif
774        {
775                if (x & 1)
776                {
777                        *dst &= 0xF0;
778                        *dst |= (c & 0xF);
779                }
780                else
781                {
782                        *dst &= 0xF;
783                        *dst |= (c & 0xF) << 4;
784                }
785                bgfx_cacheflush(dst,1);
786        }
787}
788#endif
789/****************************************************************
790* bgfx_get_pixel
791*
792* INPUTS:       p - surface structure
793*                       x,y - coordinates
794*                       c - pixel value
795* OUTPUTS:      none
796* RETURNS:      none
797* FUNCTION:     get the pixel value at x,y.  The bgfx_color will be the
798*                       actual pixel value.
799*
800* NOTE:  Not supported for RGB surfaces.  To get a pixel for RGB access buf
801* directly.
802*
803****************************************************************/
804#if SOFT_GFX_AS_IN_7003
805bgfx_pixel bgfx_get_pixel(bgfx_surf_p p,uint16_t x,uint16_t y)
806{
807        uint8_t *dst;
808       
809#ifdef CONFIG_SGL_DEBUG
810        if ((x >= p->surface.width) || (y >= p->surface.height))
811        {
812                SGL_DEBUG(("bgfx_get_pixel param error (%p,%d,%d) ",p,x,y));
813                return 0;
814        }
815#endif
816
817        dst = (uint8_t*)p->surface.buf;
818        dst += y * p->surface.pitch + x * (p->bpp >> 3);
819#ifdef CONFIG_BGFX_SURF_RGB
820        /* let application to check 16 or 32 bits? */
821        if (p->flags & BGFX_SURF_RGB)
822                return *((uint32_t*)dst);
823#endif
824        if (x & 1)
825        {
826                return (*dst  & 0xF0);
827        }
828
829        return (*dst >> 4);
830}
831
832
833bgfx_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)
834{
835        uint16_t pitch;
836        uint8_t bpp;
837       
838        BSTD_UNUSED(src_h);
839
840        switch(format)
841        {
842                case GRAPHICS_FMT_ARGB_888:
843                case GRAPHICS_FMT_RGBA_888:
844                        bpp = 32;
845                        pitch = src_w * (bpp >> 3);
846                        return (bgfx_pixel)(*(uint32_t *)((uint8_t *)pbuffer + des_y * pitch + des_x * (bpp >> 3)));
847                case GRAPHICS_FMT_RGB_565:
848                case GRAPHICS_FMT_WRGB_1555:
849                case GRAPHICS_FMT_RGBW_5551:
850                case GRAPHICS_FMT_ARGB_4444:
851                case GRAPHICS_FMT_RGBA_4444:
852                        bpp = 16;
853                        pitch = src_w * (bpp >> 3);
854                        return (bgfx_pixel)(*(uint16_t *)((uint8_t *)pbuffer + des_y * pitch + des_x * (bpp >> 3)));
855                case GRAPHICS_FMT_P4:
856                case GRAPHICS_FMT_P8:
857                default:
858                        SGL_DEBUG(("Unsupported format. "));
859                        break;
860        }
861        return -1;
862}
863#else
864bgfx_pixel bgfx_get_pixel(bgfx_surf_p p,uint16_t x,uint16_t y)
865{
866        uint8_t *dst;
867        if ((x >= p->surface.width) || (y >= p->surface.height))
868        {
869                SGL_DEBUG(("bgfx_get_pixel param error (%p,%d,%d) ",p,x,y));
870                return 0;
871        }
872        dst = (uint8_t*)p->surface.buf;
873        dst += y * p->surface.pitch + (x * p->bpp)/8;
874#ifdef CONFIG_BGFX_SURF_RGB
875        if (p->flags & BGFX_SURF_RGB)
876                return *((uint32_t*)dst);
877#endif
878        if (x & 1)
879        {
880                return (*dst  & 0xF0);
881        }
882
883        return (*dst >> 4);
884}
885#endif
886/****************************************************************
887* bgfx_h_draw_line
888*
889* INPUTS:       p - surface structure
890*                       x1,x2,y - coordinates
891*                       c - pixel value
892* OUTPUTS:      none
893* RETURNS:      none
894* FUNCTION:     Draw a horizontal line make of pixels defined by the value c.
895*
896*  JPF - these need to be optimized
897*
898****************************************************************/
899void bgfx_h_draw_line(bgfx_surf_p p,uint16_t x1,uint16_t x2,uint16_t y,
900                                         bgfx_pixel c)
901{
902#if 1
903        int w = x2 - x1;
904
905        if (w < 0)
906        {
907                w = -w;
908                bgfx_fill_rect(p,x2,y,(uint16_t)w,1, c);
909        }
910        else
911        {
912                bgfx_fill_rect(p,x1,y,(uint16_t)w,1, c);
913        }
914
915#else
916        uint8_t *dst;
917        uint16_t w = x2 - x1;
918        uint16_t off;
919
920        if ((x2 <= x1) || (y >= p->surface.height))
921        {
922                SGL_DEBUG(("bgfx_h_draw_line param error (%p,%d,%d,%d,0x%02lx) ",p,x1,x2,y,c));
923                return;
924        }
925
926        if (w > p->surface.width - x1)
927                w = p->surface.width - x1;
928        dst = (uint8_t*)p->surface.buf;
929        dst += (y * p->surface.pitch) + (x1 * p->bpp)/8;
930
931#ifdef CONFIG_BGFX_SURF_RGB
932        if (p->flags & BGFX_SURF_RGB)
933        {
934                uint32_t c32 = bgfx_clut8_to_rgb(p->palette.clut,c);
935                while (w--)
936                {
937                        *((uint32_t*)dst) = c32;
938                        dst += p->bpp/8;
939                }
940        }
941        else
942#endif
943        {
944                while (w--)
945                {
946                        off = (w * p->bpp)/8;
947                        if (w & 1)
948                        {
949                                dst[off] &= 0xF0;
950                                dst[off] |= (c & 0xF);
951                        }
952                        else
953                        {
954                                dst[off] &= 0xF;
955                                dst[off] |= (c & 0xF) << 4;
956                        }
957                }
958        }
959        bgfx_cacheflush(p->surface.buf,p->surface.pitch * p->surface.height);
960#endif
961}
962/****************************************************************
963* bgfx_v_draw_line
964*
965* INPUTS:       p - surface structure
966*                       x,y1,y2 - coordinates
967*                       c - pixel value
968* OUTPUTS:      none
969* RETURNS:      none
970* FUNCTION:     Draw a vertical line make of pixels defined by the value c.
971*
972*   JPF - these need to be optimized
973*
974****************************************************************/
975#if SOFT_GFX_AS_IN_7003
976void bgfx_v_draw_line(bgfx_surf_p p,uint16_t x,uint16_t y1,uint16_t y2,
977                                         bgfx_pixel c)
978{
979        uint8_t *dst;
980        uint16_t h = y2 - y1;
981        if ((y2 <= y1) || (x >= p->surface.width))
982        {
983                SGL_DEBUG(("bgfx_v_draw_line param error (%p,%d,%d,%d,0x%02lx) ",p,x,y1,y2,c));
984                return;
985        }
986
987        if (h > p->surface.height - y1)
988                h = p->surface.height - y1;
989        dst = (uint8_t*)p->surface.buf;
990        dst += y1 * p->surface.pitch + x * (p->bpp >> 3);
991
992#ifdef CONFIG_BGFX_SURF_RGB
993        if (p->flags & BGFX_SURF_RGB)
994        {
995                uint32_t c32;   /* Raymond, GFX convert ARGB input to other graphic format, 20090304 */
996               
997                if (p->bpp <= 8)
998                        c32 = bgfx_clut8_to_rgb(p->palette.clut,c);
999                else if (32 == p->bpp)
1000                        c32 = (uint32_t)c;
1001                else {  /* For 16bit color format, Raymond, 20090304 */
1002                        uint16_t c16;
1003                        c = BPXL_MAKE_PIXEL(bgfx_colorformat_mapping(p->format),
1004                                                                                        c>>24,
1005                                                                                        (c>>16)&0xff,
1006                                                                                        (c>>8)&0xff,
1007                                                                                        c&0xff);
1008                        c16 = (c & 0xffff);
1009                        while (h--)
1010                        {
1011                                *((uint16_t*)dst) = c16;
1012                                dst += p->surface.pitch;
1013                        }
1014                        bgfx_cacheflush(p->surface.buf,p->surface.pitch * p->surface.height);
1015                        return;
1016                }
1017                while (h--)
1018                {
1019                        *((uint32_t*)dst) = c32;
1020                        dst += p->surface.pitch;
1021                }
1022        }
1023        else
1024#endif
1025        {
1026                while (h--)
1027                {
1028                        /* AYUV P4 */
1029                        if(p->format == GRAPHICS_FMT_P4)
1030                        {
1031                        if (x & 1)
1032                        {
1033                                *dst &= 0xF0;
1034                                *dst |= (c & 0xF);
1035                        }
1036                        else
1037                        {
1038                                *dst &= 0xF;
1039                                *dst |= (c & 0xF) << 4;
1040                        }
1041                        }       
1042                        else if(p->format == GRAPHICS_FMT_P8)
1043                        {
1044                                *dst &= 0x00;
1045                                *dst |= (c & 0xFF);
1046                        }       
1047                        dst += p->surface.pitch;
1048                }
1049        }
1050        bgfx_cacheflush(p->surface.buf,p->surface.pitch * p->surface.height);
1051}
1052#else
1053void bgfx_v_draw_line(bgfx_surf_p p,uint16_t x,uint16_t y1,uint16_t y2,
1054                                         bgfx_pixel c)
1055{
1056        uint8_t *dst;
1057        uint16_t h = y2 - y1;
1058        if ((y2 <= y1) || (x >= p->surface.width))
1059        {
1060                SGL_DEBUG(("bgfx_v_draw_line param error (%p,%d,%d,%d,0x%02lx) ",p,x,y1,y2,c));
1061                return;
1062        }
1063
1064        if (h > p->surface.height - y1)
1065                h = p->surface.height - y1;
1066        dst = (uint8_t*)p->surface.buf;
1067        dst += y1 * p->surface.pitch + x * p->bpp/8;
1068
1069#ifdef CONFIG_BGFX_SURF_RGB
1070        if (p->flags & BGFX_SURF_RGB)
1071        {
1072                uint32_t c32 = bgfx_clut8_to_rgb(p->palette.clut,c);
1073                while (h--)
1074                {
1075                        *((uint32_t*)dst) = c32;
1076                        dst += p->surface.pitch;
1077                }
1078        }
1079        else
1080#endif
1081        {
1082                while (h--)
1083                {
1084                        if (x & 1)
1085                        {
1086                                *dst &= 0xF0;
1087                                *dst |= (c & 0xF);
1088                        }
1089                        else
1090                        {
1091                                *dst &= 0xF;
1092                                *dst |= (c & 0xF) << 4;
1093                        }
1094                        dst += p->surface.pitch;
1095                }
1096        }
1097        bgfx_cacheflush(p->surface.buf,p->surface.pitch * p->surface.height);
1098}
1099#endif
1100/****************************************************************
1101* bgfx_fill_rect
1102*
1103* INPUTS:       p - surface structure
1104*                       x1,x2,y1,y2 - coordinates
1105*                       c - pixel value
1106* OUTPUTS:      none
1107* RETURNS:      none
1108* FUNCTION:     Fill the rectangle with pixels defined by the value c.
1109*
1110*   JPF - these need to be optimized
1111*
1112****************************************************************/
1113/* TODO create optimized version of memset */
1114#if 0
1115static inline void *bgfx_memset(void *dest,int c,size_t count)
1116{
1117        uint8_t *d = dest;
1118        for(;count>0;count--) {
1119                *d++ = c;
1120        }
1121        return dest;
1122}
1123#else
1124#define bgfx_memset memset
1125#endif
1126
1127#if SOFT_GFX_AS_IN_7003
1128void bgfx_fill_rect(bgfx_surf_p p,uint16_t x,uint16_t y,uint16_t w,uint16_t h,
1129                                   bgfx_pixel c)
1130{
1131#if 0
1132        bgfx_fill_rect(p->fd,p->psurface[p->surf_idx],x,y,w,h,bgfx_clut8_to_rgb(p->palette.clut,c));
1133#else
1134#ifdef CONFIG_BGFX_SURF_RGB
1135        uint8_t *tdst;
1136        uint16_t i;
1137#endif
1138        uint8_t *dst;
1139        uint16_t j;     
1140
1141/* printf("-----surface buffer addr: %lx, X: %d, Y:%d, Width:%d, Height:%d----- ", p->surface.buf, x, y, w, h); */
1142
1143        if (y + h > p->surface.height)
1144                h = p->surface.height - y;
1145
1146        if (w + x > p->surface.width)
1147                w = p->surface.width - x;
1148
1149        dst = (uint8_t*)p->surface.buf;
1150        dst += y * p->surface.pitch + x * (p->bpp >> 3);
1151
1152#ifdef CONFIG_BGFX_SURF_RGB
1153        if (p->flags & BGFX_SURF_RGB)
1154        {
1155                uint32_t c32;
1156       
1157                if (p->bpp <= 8)
1158                        c32 = bgfx_clut8_to_rgb(p->palette.clut,c);
1159                else if (32 == p->bpp)
1160                        c32 = (uint32_t)c;
1161                else {  /* Raymond, GFX convert ARGB input to other graphic format, 20090304 */
1162                        uint16_t c16;
1163                        c = BPXL_MAKE_PIXEL(bgfx_colorformat_mapping(p->format),
1164                                                                                        c>>24,
1165                                                                                        (c>>16)&0xff,
1166                                                                                        (c>>8)&0xff,
1167                                                                                        c&0xff);
1168                        c16 = (c & 0xffff);
1169                        for (j = 0; j < h; ++j)
1170                        {
1171                                tdst = dst;
1172                                for (i = 0; i < w; ++i)
1173                                {
1174                                        *((uint16_t*)tdst) = c16;
1175                                        tdst += 2;
1176                                }
1177                                dst += p->surface.pitch;
1178                        }
1179                        bgfx_cacheflush(p->surface.buf,p->surface.pitch * p->surface.height);
1180                        return;
1181                }
1182
1183#if NON_OPTIMIZED
1184                for (j = 0; j < h; ++j)
1185                {
1186                        tdst = dst;
1187                        for (i = 0; i < w; ++i)
1188                        {
1189                                *((uint32_t*)tdst) = c32;
1190                                tdst += (p->bpp >> 3);
1191                        }
1192                        dst += p->surface.pitch;
1193                }
1194#else
1195        tdst = dst;       
1196        uint8_t *tmp_line = dst;       
1197
1198        for (i = 0; i < w; ++i)       
1199        {                       
1200            *((uint32_t*)tdst) = c32;
1201            tdst += 4;
1202        }
1203        dst += p->surface.pitch;
1204        for (j = 1; j < h; ++j)
1205        {
1206            tdst = dst;
1207            memcpy((void *)tdst, (const void*)tmp_line, w*4);
1208            dst += p->surface.pitch;
1209        }
1210#endif
1211                bgfx_cacheflush(p->surface.buf,p->surface.pitch * p->surface.height);
1212        }
1213        else
1214#endif
1215        {
1216                unsigned char two_pixel = 0;
1217                if(p->format == GRAPHICS_FMT_P4)
1218                        two_pixel = (c << 4) | c;
1219                else if(p->format == GRAPHICS_FMT_P8)
1220                        two_pixel = (c & 0xFF);
1221               
1222                for (j = 0; j < h; ++j)
1223                {
1224                        unsigned int num_bytes = w * (p->bpp >> 3);
1225                        //printf("\n****two_pixel=%x,num_bytes=%d, j=%d****\n",two_pixel,num_bytes,j);
1226                        if(p->format == GRAPHICS_FMT_P4)
1227                        {
1228                        if (x & 1)
1229                        {
1230                                *dst &= 0xF0;
1231                                *dst |= (c & 0xF);
1232                                if (w & 1)
1233                                {
1234                                        bgfx_memset(&dst[1],two_pixel,num_bytes);
1235                                }
1236                                else
1237                                {
1238                                        bgfx_memset(&dst[1],two_pixel,num_bytes - 1);
1239                                        dst[num_bytes] &= 0x0F;
1240                                        dst[num_bytes] |= (c & 0xF) << 4;
1241                                }
1242                        }
1243                        else
1244                        {
1245                                if (w & 1)
1246                                {
1247                                        bgfx_memset(dst,two_pixel,num_bytes);
1248                                        dst[num_bytes] &= 0x0F;
1249                                        dst[num_bytes] |= (c & 0xF) << 4;
1250                                }
1251                                else
1252                                        bgfx_memset(dst,two_pixel,num_bytes);
1253                        }
1254                        }
1255                        else if(p->format == GRAPHICS_FMT_P8)
1256                        {
1257                                bgfx_memset(dst,two_pixel,num_bytes);
1258                        }
1259                        dst += p->surface.pitch;
1260                }
1261        }
1262        bgfx_cacheflush(p->surface.buf,p->surface.pitch * p->surface.height);
1263#endif
1264}
1265#else
1266void bgfx_fill_rect(bgfx_surf_p p,uint16_t x,uint16_t y,uint16_t w,uint16_t h,
1267                                   bgfx_pixel c)
1268{
1269#if 0
1270        bgfx_fill_rect(p->fd,p->psurface[p->surf_idx],x,y,w,h,bgfx_clut8_to_rgb(p->palette.clut,c));
1271#else
1272#ifdef CONFIG_BGFX_SURF_RGB
1273        uint8_t *tdst;
1274        uint16_t i;
1275#endif
1276        uint8_t *dst;
1277        uint16_t j;     
1278               
1279        if (y + h > p->surface.height)
1280                h = p->surface.height - y;
1281
1282        if (w + x > p->surface.width)
1283                w = p->surface.width - x;
1284
1285        dst = (uint8_t*)p->surface.buf;
1286        dst += y * p->surface.pitch + x * p->bpp/8;
1287
1288#ifdef CONFIG_BGFX_SURF_RGB
1289        if (p->flags & BGFX_SURF_RGB)
1290        {
1291                uint32_t c32 = bgfx_clut8_to_rgb(p->palette.clut,c);
1292                for (j = 0; j < h; ++j)
1293                {
1294                        tdst = dst;
1295                        for (i = 0; i < w; ++i)
1296                        {
1297                                *((uint32_t*)tdst) = c32;
1298                                tdst += p->bpp/8;
1299                        }
1300                        dst += p->surface.pitch;
1301                }
1302        }
1303        else
1304#endif
1305        {
1306                unsigned char two_pixel = (c << 4) | c;
1307                for (j = 0; j < h; ++j)
1308                {
1309                        unsigned int num_bytes = (w * p->bpp)/8;
1310                        if (x & 1)
1311                        {
1312                                *dst &= 0xF0;
1313                                *dst |= (c & 0xF);
1314                                if (w & 1)
1315                                {
1316                                        bgfx_memset(&dst[1],two_pixel,num_bytes);
1317                                }
1318                                else
1319                                {
1320                                        bgfx_memset(&dst[1],two_pixel,num_bytes - 1);
1321                                        dst[num_bytes] &= 0x0F;
1322                                        dst[num_bytes] |= (c & 0xF) << 4;
1323                                }
1324                        }
1325                        else
1326                        {
1327                                if (w & 1)
1328                                {
1329                                        bgfx_memset(dst,two_pixel,num_bytes);
1330                                        dst[num_bytes] &= 0x0F;
1331                                        dst[num_bytes] |= (c & 0xF) << 4;
1332                                }
1333                                else
1334                                        bgfx_memset(dst,two_pixel,num_bytes);
1335                        }
1336                        dst += p->surface.pitch;
1337                }
1338        }
1339        bgfx_cacheflush(p->surface.buf,p->surface.pitch * p->surface.height);
1340#endif
1341}
1342#endif
1343/****************************************************************
1344* bgfx_render_glyph
1345*
1346* INPUTS:       p - surface structure
1347*                       x,y - coordinates
1348*                       a_char - character to render
1349*                       font_p - font definition
1350*                       c - color
1351* OUTPUTS:      none
1352* RETURNS:      character advance
1353* FUNCTION:     Fill the rectangle with pixels defined by the value c.
1354*
1355****************************************************************/
1356#define IT_OFFSET       3
1357
1358#if SOFT_GFX_AS_IN_7003
1359static inline int bgfx_render_glyph(bgfx_surf_p p,uint16_t x,uint16_t y,
1360                const unsigned long a_char, bgfx_font_t *font_p,bgfx_pixel c,
1361                bgfx_glyph_t * p_bgfx_glyph,bgfx_text_style style)
1362{
1363        int max_width,ybase;
1364        uint16_t row;
1365        uint8_t *src,*dst;
1366        bgfx_glyph_t * bgfx_glyph = p_bgfx_glyph;
1367        unsigned char   glyph_width;            /* width of the rendered character bitmap in pixels */
1368        unsigned char   glyph_height;           /* height of the rendered character bitmap in pixels */
1369
1370        ybase = y;
1371        if (x > p->surface.width)
1372        {
1373                SGL_TRACE(("bgfx_render_glyph x > width (%d,%d) ",x,p->surface.width));
1374                return 0;
1375        }
1376
1377        /* if using glyph cache use the get glyph rather than render directly to surface buffer */
1378        if (!bgfx_glyph && (font_p->cache_size > 0))
1379        {
1380                bgfx_glyph = bgfx_get_glyph(font_p,a_char);
1381        }
1382
1383        if (!bgfx_glyph)
1384        {
1385                SGL_DEBUG(("bgfx_render_glyph could not load glyph 0x%08lx ",a_char));
1386                return 0;
1387        }
1388        SGL_TRACE(("bgfx_render_glyph glyph (%p,%d,%d) ",bgfx_glyph->buf,bgfx_glyph->height,bgfx_glyph->width));
1389
1390        glyph_width = bgfx_glyph->width;
1391        glyph_height = bgfx_glyph->height;
1392
1393        if (bgfx_glyph->left + x > 0)
1394                x += bgfx_glyph->left;
1395        if (y-bgfx_glyph->top > 0)
1396                y -= bgfx_glyph->top;
1397        else
1398                y = 0;
1399
1400        if (glyph_height + y > p->surface.height)
1401                glyph_height = p->surface.height - y;
1402        if (glyph_width + x > p->surface.width)
1403                glyph_width = p->surface.width - x;
1404
1405        src = (uint8_t*)bgfx_glyph->buf;
1406        dst = (uint8_t*)p->surface.buf;
1407
1408        SGL_TRACE(("bgfx_render_glyph suface (%p(y = %d,x = %d,pitch = %d,bpp = %d) ",dst,y,x,p->surface.pitch, p->bpp));
1409
1410        dst += y * p->surface.pitch + x * p->bpp/8;
1411        if (style & eBGFX_ITALIC)
1412                max_width = BGFX_MIN(glyph_width + IT_OFFSET, p->surface.width - x);
1413        else
1414                max_width = BGFX_MIN(glyph_width, p->surface.width - x);
1415
1416        if (max_width <= 0)
1417        {
1418                if (glyph_width != 0)
1419                {
1420                        SGL_TRACE(("bgfx_render_glyph glyph_width = %d ", glyph_width));
1421                }
1422                return bgfx_glyph->advance;
1423        }
1424
1425        /* Render mono glyph */
1426        if (font_p->format & SGL_MONO)
1427        {
1428                SGL_TRACE(("bgfx_render_glyph Alpha 1 font "));
1429
1430#ifdef CONFIG_BGFX_SURF_RGB
1431                if (p->flags & BGFX_SURF_RGB)
1432                {
1433                        uint32_t c32;
1434                        uint16_t c16 = (c & 0xffff);
1435
1436                        if (p->bpp <= 8)
1437                                c32 = bgfx_clut8_to_rgb(p->palette.clut,c);
1438                        else {
1439                                if (32 == p->bpp)
1440                                        c32 = c;
1441                                //else
1442                                //      c16 = (c & 0xffff);
1443                        }
1444
1445                        if (p->bpp <= 8) {
1446                                for (row = 0; row < glyph_height; row++)
1447                                {
1448                                        bgfx_render_a1_to_rgb( src, dst, max_width,c32 );
1449
1450                                        src += bgfx_glyph->pitch;
1451                                        dst += p->surface.pitch;
1452                                }
1453                        }
1454                        else if (32 == p->bpp) {
1455                                for (row = 0; row < glyph_height; row++)
1456                                {
1457                                        *(uint32_t *)dst = c32;
1458                                        src += bgfx_glyph->pitch;
1459                                        dst += p->surface.pitch;
1460                                }
1461                        }
1462                        else {
1463                                for (row = 0; row < glyph_height; row++)
1464                                {
1465                                        *(uint16_t *)dst = c16;
1466                                        src += bgfx_glyph->pitch;
1467                                        dst += p->surface.pitch;
1468                                }
1469                        }
1470                }
1471                else
1472#endif
1473                {
1474                        uint16_t adjx = x;
1475                        for (row = 0; row < glyph_height; row++)
1476                        {
1477                                if (style & eBGFX_ITALIC)
1478                                {
1479                                        adjx = x + IT_OFFSET - ((row * IT_OFFSET)/glyph_height);
1480                                        dst = (uint8_t*)p->surface.buf;
1481                                        dst += (y + row) * p->surface.pitch + adjx * (p->bpp >> 3);
1482                                }
1483                                bgfx_render_a1_to_clut4( src, dst, max_width,c, adjx & 0x1 );
1484
1485                                src += bgfx_glyph->pitch;
1486                                dst += p->surface.pitch;
1487                        }
1488                }
1489        }
1490        else /* Render 8 bit grayscale glyph */
1491        {
1492                SGL_TRACE(("bgfx_render_glyph Alpha 8 font "));
1493#ifdef CONFIG_BGFX_SURF_RGB
1494                if (p->flags & BGFX_SURF_RGB)
1495                {
1496                        uint32_t c32;
1497                        uint16_t c16 = (c & 0xffff);
1498
1499                        if (p->bpp <= 8)
1500                                c32 = bgfx_clut8_to_rgb(p->palette.clut,c);
1501                        else {
1502                                if (32 == p->bpp)
1503                                        c32 = c;
1504                                //else
1505                                //      c16 = (c & 0xffff);
1506                        }
1507
1508                        if (p->bpp <= 8) {
1509                                for (row = 0; row < glyph_height; row++)
1510                                {
1511                                        bgfx_render_a8_to_rgb( src, dst, glyph_width,c32);
1512
1513                                        src += bgfx_glyph->pitch;
1514                                        dst += p->surface.pitch;
1515                                }
1516                        }
1517                        else if (32 == p->bpp) {
1518                                for (row = 0; row < glyph_height; row++)
1519                                {
1520                                        *(uint32_t *)dst = c32;
1521                                        src += bgfx_glyph->pitch;
1522                                        dst += p->surface.pitch;
1523                                }
1524                        }
1525                        else {
1526                                for (row = 0; row < glyph_height; row++)
1527                                {
1528                                        *(uint16_t *)dst = c16;
1529                                        src += bgfx_glyph->pitch;
1530                                        dst += p->surface.pitch;
1531                                }
1532                        }
1533                }
1534                else
1535#endif
1536                {
1537                        for (row = 0; row < glyph_height; row++)
1538                        {
1539                                bgfx_render_a8_to_clut4( src, dst, glyph_width,c );
1540
1541                                src += bgfx_glyph->pitch;
1542                                dst += p->surface.pitch;
1543                        }
1544                }
1545        }
1546        if (style & eBGFX_UNDERLINE)
1547                bgfx_h_draw_line(p,x,x + bgfx_glyph->advance,ybase,c);
1548        return bgfx_glyph->advance;
1549}
1550
1551#else
1552
1553static inline int bgfx_render_glyph(bgfx_surf_p p,uint16_t x,uint16_t y,
1554                                         const unsigned long a_char, bgfx_font_t *font_p,bgfx_pixel c,
1555                                          bgfx_glyph_t * p_bgfx_glyph,bgfx_text_style style)
1556{
1557        int max_width,ybase;
1558        uint16_t row;
1559        uint8_t *src,*dst;
1560        bgfx_glyph_t * bgfx_glyph = p_bgfx_glyph;
1561        unsigned char   glyph_width;            /* width of the rendered character bitmap in pixels */
1562        unsigned char   glyph_height;           /* height of the rendered character bitmap in pixels */
1563
1564        ybase = y;
1565        if (x > p->surface.width)
1566        {
1567                SGL_TRACE(("bgfx_render_glyph x > width (%d,%d) ",x,p->surface.width));
1568                return 0;
1569        }
1570
1571        /* if using glyph cache use the get glyph rather than render directly to surface buffer */
1572        if (!bgfx_glyph && (font_p->cache_size > 0))
1573        {
1574                bgfx_glyph = bgfx_get_glyph(font_p,a_char);
1575        }
1576
1577        if (!bgfx_glyph)
1578        {
1579                SGL_DEBUG(("bgfx_render_glyph could not load glyph 0x%08lx ",a_char));
1580                return 0;
1581        }
1582        SGL_TRACE(("bgfx_render_glyph glyph (%p,%d,%d) ",bgfx_glyph->buf,bgfx_glyph->height,bgfx_glyph->width));
1583
1584        glyph_width = bgfx_glyph->width;
1585        glyph_height = bgfx_glyph->height;
1586
1587        if (bgfx_glyph->left + x > 0)
1588                x += bgfx_glyph->left;
1589        if (y-bgfx_glyph->top > 0)
1590                y -= bgfx_glyph->top;
1591        else
1592                y = 0;
1593
1594        if (glyph_height + y > p->surface.height)
1595                glyph_height = p->surface.height - y;
1596        if (glyph_width + x > p->surface.width)
1597                glyph_width = p->surface.width - x;
1598
1599        src = (uint8_t*)bgfx_glyph->buf;
1600        dst = (uint8_t*)p->surface.buf;
1601
1602        SGL_TRACE(("bgfx_render_glyph suface (%p(y = %d,x = %d,pitch = %d,bpp = %d) ",dst,y,x,p->surface.pitch, p->bpp));
1603       
1604        dst += y * p->surface.pitch + x * p->bpp/8;
1605        if (style & eBGFX_ITALIC)
1606                max_width = BGFX_MIN(glyph_width + IT_OFFSET, p->surface.width - x);
1607        else
1608                max_width = BGFX_MIN(glyph_width, p->surface.width - x);
1609       
1610        if (max_width <= 0)
1611        {
1612                if (glyph_width != 0)
1613                {
1614                        SGL_TRACE(("bgfx_render_glyph glyph_width = %d ", glyph_width));
1615                }
1616                return bgfx_glyph->advance;
1617        }
1618
1619        /* Render mono glyph */
1620        if (font_p->format & SGL_MONO)
1621        {
1622                SGL_TRACE(("bgfx_render_glyph Alpha 1 font "));
1623
1624#ifdef CONFIG_BGFX_SURF_RGB
1625                if (p->flags & BGFX_SURF_RGB)
1626                {
1627                        uint32_t c32 = bgfx_clut8_to_rgb(p->palette.clut,c);
1628                        for (row = 0; row < glyph_height; row++)
1629                        {
1630                                bgfx_render_a1_to_rgb( src, dst, max_width,c32 );
1631
1632                                src += bgfx_glyph->pitch;
1633                                dst += p->surface.pitch;
1634                        }
1635                }
1636                else
1637#endif
1638                {
1639                        uint16_t adjx = x;
1640                        for (row = 0; row < glyph_height; row++)
1641                        {
1642                                if (style & eBGFX_ITALIC)
1643                                {
1644                                        adjx = x + IT_OFFSET - ((row * IT_OFFSET)/glyph_height);
1645                                        dst = (uint8_t*)p->surface.buf;
1646                                        dst += (y + row) * p->surface.pitch + adjx * p->bpp/8;
1647                                }
1648                                bgfx_render_a1_to_clut4( src, dst, max_width,c, adjx & 0x1 );
1649
1650                                src += bgfx_glyph->pitch;
1651                                dst += p->surface.pitch;
1652                        }
1653                }
1654        }
1655        else /* Render 8 bit grayscale glyph */
1656        {
1657                SGL_TRACE(("bgfx_render_glyph Alpha 8 font "));
1658#ifdef CONFIG_BGFX_SURF_RGB
1659                if (p->flags & BGFX_SURF_RGB)
1660                {
1661                        uint32_t c32 = bgfx_clut8_to_rgb(p->palette.clut,c);
1662                        for (row = 0; row < glyph_height; row++)
1663                        {
1664                                bgfx_render_a8_to_rgb( src, dst, glyph_width,c32);
1665
1666                                src += bgfx_glyph->pitch;
1667                                dst += p->surface.pitch;
1668                        }
1669                }
1670                else
1671#endif
1672                {
1673                        for (row = 0; row < glyph_height; row++)
1674                        {
1675                                bgfx_render_a8_to_clut4( src, dst, glyph_width,c );
1676
1677                                src += bgfx_glyph->pitch;
1678                                dst += p->surface.pitch;
1679                        }
1680                }
1681        }
1682        if (style & eBGFX_UNDERLINE)
1683                bgfx_h_draw_line(p,x,x + bgfx_glyph->advance,ybase,c);
1684        return bgfx_glyph->advance;
1685}
1686
1687#endif
1688/****************************************************************
1689* bgfx_draw_text
1690*
1691* INPUTS:       p - surface structure
1692*                       x,y - coordinates
1693*                       str_p - array of 32-bit unicode characters
1694                        str_len - number of 32-bit characters in array
1695*                       font_p - font definition
1696*                       c - color
1697* OUTPUTS:      none
1698* RETURNS:      none
1699* FUNCTION:     Fill the rectangle with pixels defined by the value c.
1700*
1701****************************************************************/
1702void bgfx_draw_text(bgfx_surf_p p,uint16_t x,uint16_t y,
1703                                   const unsigned long *str_p, int str_len, 
1704                                   bgfx_font_t *font_p,bgfx_pixel c, bgfx_text_style style)
1705{
1706        int offset;
1707
1708        SGL_TRACE(("bgfx_draw_text %ld characters. ",str_len));
1709       
1710        for (offset = 0; offset < str_len; offset++)
1711        {
1712                x += bgfx_render_glyph(p,x,y, str_p[offset], font_p,c,NULL,style);
1713        }
1714        bgfx_cacheflush(p->surface.buf,p->surface.pitch * p->surface.height);
1715}
1716/****************************************************************
1717* bgfx_draw_text_box
1718*
1719* INPUTS:       p - surface structure
1720*                       x,y - coordinates
1721*                       width,height - width and hegith of the text box to draw
1722*                       str_p - array of 32-bit unicode characters
1723                        str_len - number of 32-bit characters in array
1724*                       font_p - font definition
1725*                       c - color
1726                        line_spacing - line space
1727* OUTPUTS:      none
1728* RETURNS:      none
1729* FUNCTION:     Fill the rectangle with pixels defined by the value c.
1730*
1731****************************************************************/
1732#define MAX_TEXT_BOX_CHARS      512
1733#define MAX_LINES                       16
1734static unsigned long s_test_char = 0x00000057UL;
1735/* TODO:  Might want to improve macro to check for chars other than spaces */
1736#define SGL_IS_BREAK(x) ((x == 0x00000020) ? 1 : 0)
1737//#define SGL_VARIABL_LINE_HEIGHT
1738void bgfx_draw_text_box(bgfx_surf_p p,uint16_t x,uint16_t y,
1739                                                uint16_t width, uint16_t height,
1740                                                const unsigned long *str_p, int str_len, 
1741                                                bgfx_font_t *font_p,bgfx_pixel c, 
1742                                                uint16_t line_spacing)
1743{
1744        int offset,bw_off,line_idx;
1745        static bgfx_glyph_t * p_bgfx_glyph[MAX_TEXT_BOX_CHARS]; /* Not thread safe */
1746        static uint8_t brk_loc[MAX_TEXT_BOX_CHARS];
1747        uint16_t max_h[MAX_LINES],ch_w,test_max_h,bot;
1748        bgfx_glyph_t *p_test_glyph;
1749
1750        SGL_TRACE(("bgfx_draw_text_box(%d,%d,%d,%d,%d) %ld characters. ",x,y,width,height,line_spacing,str_len));
1751        if (str_len > MAX_TEXT_BOX_CHARS) 
1752        {
1753                SGL_DEBUG(("bgfx_draw_text %d > %d maximum characters. ",str_len,MAX_TEXT_BOX_CHARS));
1754                str_len = MAX_TEXT_BOX_CHARS;
1755        }
1756        bot = y + height;
1757        p_test_glyph = bgfx_get_glyph(font_p,s_test_char);
1758        if (p_test_glyph)
1759                test_max_h = p_test_glyph->height;
1760        else
1761                test_max_h = 0;
1762
1763        for (line_idx = 0; line_idx < MAX_LINES; ++line_idx)
1764                max_h[line_idx] = test_max_h;
1765       
1766        ch_w = 0;
1767        line_idx = 0;
1768        for (offset = 0; offset < str_len; offset++)
1769        {
1770                brk_loc[offset] = 0;
1771                p_bgfx_glyph[offset] = bgfx_get_glyph(font_p,str_p[offset]);
1772                if (p_bgfx_glyph[offset] == NULL)
1773                {
1774                        SGL_DEBUG(("%s:%d str[%d] = 0x%08x ",__FUNCTION__,__LINE__,offset,str_p[offset]));
1775                        /* if not a printable charactor, then use space instead */
1776                        p_bgfx_glyph[offset] = bgfx_get_glyph(font_p,0x00000020);
1777                        continue;
1778                }
1779                ch_w += p_bgfx_glyph[offset]->advance;
1780
1781                if (p_bgfx_glyph[offset]->height > max_h[line_idx]) 
1782                        max_h[line_idx] = p_bgfx_glyph[offset]->height;
1783
1784                if (ch_w >= width) 
1785                {
1786                        line_idx++;
1787                        for (bw_off = offset - 1; bw_off >= 0; --bw_off)
1788                        {
1789                                if (brk_loc[bw_off]) {
1790                                        bw_off = -1;
1791                                        break;
1792                                }
1793                                if (SGL_IS_BREAK(str_p[bw_off])) 
1794                                {
1795                                        brk_loc[bw_off] = 1;
1796                                        break;
1797                                }
1798                        }
1799
1800                        /* last resort, break on preceding character */
1801                        if (bw_off < 0) 
1802                        {
1803                                brk_loc[offset - 1] = 1;
1804                                ch_w = p_bgfx_glyph[offset]->advance;
1805                        }
1806                        else
1807                        {
1808                                offset = bw_off;
1809                                ch_w = 0;
1810                        }
1811                }
1812        }
1813
1814        /* offset y so text is inside box */
1815        line_idx = 0;
1816#ifdef SGL_VARIABL_LINE_HEIGHT
1817        y += max_h[line_idx];
1818#else
1819        y += test_max_h;
1820#endif
1821        ch_w = 0;
1822
1823        for (offset = 0; (offset < str_len) && (line_idx < MAX_LINES); offset++)
1824        {
1825                if (brk_loc[offset]) 
1826                {
1827                        line_idx++;
1828                        ch_w = 0;
1829#ifdef SGL_VARIABL_LINE_HEIGHT
1830                        y += line_spacing + max_h[line_idx];
1831                        if ((y - max_h[line_idx]) > bot) 
1832                                break;
1833#else
1834                        y += line_spacing + test_max_h;
1835                        if ((y - test_max_h) > bot) 
1836                                break;
1837#endif
1838                        continue;
1839                }
1840                ch_w += bgfx_render_glyph(p,x + ch_w,y, str_p[offset], font_p,c,p_bgfx_glyph[offset],eBGFX_NORMAL);
1841        }
1842        bgfx_cacheflush(p->surface.buf,p->surface.pitch * p->surface.height);
1843}
1844
1845/****************************************************************
1846* bgfx_render_file
1847*
1848* INPUTS:       p - surface structure
1849*                       x,y - coordinates
1850*                       file_p - file to get image from
1851*                       set_palette - use the palette in the file to set the
1852*                                               global palette.
1853* OUTPUTS:      none
1854* RETURNS:      non-zero on error
1855* FUNCTION:     Render the image in the file to the x,y location
1856*
1857****************************************************************/
1858#if (SOFT_GFX_AS_IN_7003 == 0)
1859int bgfx_render_file(bgfx_surf_p p,uint16_t x,uint16_t y,
1860                                        void *file_p,int set_palette)
1861{
1862        bcm_raw_8_t header;
1863        int result = -1;
1864        static uint8_t tbuf[SURF_WIDTH];
1865        uint16_t row,rows,rowbytes;
1866        uint8_t *dst_ptr;
1867        int palette_bytes;
1868#ifdef CONFIG_BGFX_SURF_RGB
1869        uint16_t i;
1870        uint8_t *r_ptr,*tdst;
1871#endif
1872
1873        if (bgfx_read(&header,1,sizeof(header),file_p) == sizeof(header))
1874        {
1875                if (header.type != RAW_TYPE || header.version != RAW_VERSION)
1876                {
1877                        SGL_DEBUG(("bgfx_render_file failed version,type invalid(0x%08lx,0x%08lx) ",header.type,header.version));
1878                        return -1;
1879                }
1880                SGL_TRACE(("header.version = 0x%08lx ",header.version));
1881                SGL_TRACE(("header.type = 0x%08lx ",header.type));
1882                SGL_TRACE(("header.clut_size = %d ",header.clut_size));
1883                SGL_TRACE(("header.color_key = 0x%02x ",header.color_key));
1884                SGL_TRACE(("header.pitch = %ld ",header.pitch));
1885                SGL_TRACE(("header.width = 0x%08x ",header.width));
1886                SGL_TRACE(("header.height = 0x%08x ",header.height));
1887
1888                palette_bytes = (sizeof(unsigned long) * header.clut_size);
1889                if (bgfx_read(&p->palette,1,palette_bytes,file_p) == palette_bytes)
1890                {
1891                        if (set_palette && (header.clut_size == PALETTE_SIZE))
1892                                bgfx_set_palette(p,&p->palette);
1893                }
1894
1895                if ((header.width == p->surface.width) && (header.height == p->surface.height) &&
1896                        (p->surface.pitch == header.pitch) && (x == 0) && (y == 0)
1897                                 && !(p->flags & BGFX_SURF_RGB))
1898                {
1899                        SGL_TRACE(("Fast Render "));
1900                        bgfx_read(p->surface.buf,1,header.pitch*header.height,file_p);
1901                }
1902                else if ((p->palette.clut[header.color_key] & 0xFF000000) != 0)
1903                {
1904                        SGL_TRACE(("Render - no color key "));
1905                        rowbytes = BGFX_MIN(header.width,p->surface.width - x) * p->bpp/8;
1906                        rows = BGFX_MIN(header.height, p->surface.height - y);
1907
1908                        dst_ptr = (uint8_t*)p->surface.buf;
1909                        dst_ptr += y * p->surface.pitch + x * p->bpp/8;
1910
1911#ifdef CONFIG_BGFX_SURF_RGB
1912                        if (p->flags & BGFX_SURF_RGB)
1913                        {
1914                                for (row = 0; row < rows; row++)
1915                                {
1916                                        bgfx_read(tbuf ,1,rowbytes,file_p);
1917                                        r_ptr = dst_ptr;
1918                                        for (i = 0; i < rowbytes; ++i)
1919                                        {
1920                                                uint32_t sr,sg,sb,sa,dr,dg,db,da,src_c;
1921                                                src_c = bgfx_clut8_to_rgb(p->palette.clut,tbuf[i]);
1922                                                sa = (src_c >> 24) & 0xFF;
1923                                                if (sa == 0xFF)
1924                                                {
1925                                                        *((uint32_t*)r_ptr) = src_c;
1926                                                }
1927                                                else
1928                                                {
1929                                                        sr = (src_c >> 16) & 0xFF;
1930                                                        sg = (src_c >> 8) & 0xFF;
1931                                                        sb = (src_c >> 0) & 0xFF;
1932                                                        da = (*((uint32_t*)r_ptr) >> 24) & 0xFF;
1933                                                        dr = (*((uint32_t*)r_ptr) >> 16) & 0xFF;
1934                                                        dg = (*((uint32_t*)r_ptr) >> 8) & 0xFF;
1935                                                        db = (*((uint32_t*)r_ptr) >> 0) & 0xFF;
1936                                               
1937                                                        dr = (((sr * sa)/0xFF) & 0xFF) + ((((0xFF - sa) * dr)/0xFF) & 0xFF);
1938                                                        dg = (((sg * sa)/0xFF) & 0xFF) + ((((0xFF - sa) * dg)/0xFF) & 0xFF);
1939                                                        db = (((sb * sa)/0xFF) & 0xFF) + ((((0xFF - sa) * db)/0xFF) & 0xFF);
1940
1941                                                        *((uint32_t*)r_ptr) = (da << 24) | (dr << 16) | (dg << 8) | db;
1942                                                }
1943                                                r_ptr += p->bpp/8;
1944                                        }
1945
1946                                        if (header.pitch > rowbytes)
1947                                        {
1948                                                bgfx_read(tbuf ,1,header.pitch - rowbytes,file_p);
1949                                        }
1950                                        dst_ptr += p->surface.pitch;
1951                                }
1952                        }
1953                        else
1954#endif
1955                        {
1956                                for (row = 0; row < rows; row++)
1957                                {
1958                                        bgfx_read(dst_ptr ,1,rowbytes,file_p);
1959                                        if (header.pitch > rowbytes)
1960                                        {
1961                                                bgfx_read(tbuf ,1,header.pitch - rowbytes,file_p);
1962                                        }
1963                                        dst_ptr += p->surface.pitch;
1964                                }
1965                        }
1966                }
1967                else
1968                {
1969                        SGL_TRACE(("Render - color key "));
1970                        rowbytes = BGFX_MIN(header.width,(p->surface.width - x)) * p->bpp/8;
1971                        rows = BGFX_MIN(header.height, (p->surface.height - y));
1972                        dst_ptr = (uint8_t*)p->surface.buf;
1973                        dst_ptr += y * p->surface.pitch + x * p->bpp/8;
1974
1975#ifdef CONFIG_BGFX_SURF_RGB
1976                        if (p->flags & BGFX_SURF_RGB)
1977                        {
1978                                for (row = 0; row < rows; row++)
1979                                {
1980                                        bgfx_read(tbuf ,1,rowbytes,file_p);
1981                                        r_ptr = dst_ptr;
1982                                        for (i = 0; i < rowbytes; ++i)
1983                                        {
1984                                                if (tbuf[i] != header.color_key)
1985                                                {
1986                                                        uint32_t sr,sg,sb,sa,dr,dg,db,da,src_c;
1987                                                        src_c = bgfx_clut8_to_rgb(p->palette.clut,tbuf[i]);
1988                                                        sa = (src_c >> 24) & 0xFF;
1989                                                        if (sa == 0xFF)
1990                                                        {
1991                                                                *((uint32_t*)r_ptr) = src_c;
1992                                                        }
1993                                                        else
1994                                                        {
1995                                                                sr = (src_c >> 16) & 0xFF;
1996                                                                sg = (src_c >> 8) & 0xFF;
1997                                                                sb = (src_c >> 0) & 0xFF;
1998                                                                da = (*((uint32_t*)r_ptr) >> 24) & 0xFF;
1999                                                                dr = (*((uint32_t*)r_ptr) >> 16) & 0xFF;
2000                                                                dg = (*((uint32_t*)r_ptr) >> 8) & 0xFF;
2001                                                                db = (*((uint32_t*)r_ptr) >> 0) & 0xFF;
2002
2003                                                                dr = (((sr * sa)/0xFF) & 0xFF) + ((((0xFF - sa) * dr)/0xFF) & 0xFF);
2004                                                                dg = (((sg * sa)/0xFF) & 0xFF) + ((((0xFF - sa) * dg)/0xFF) & 0xFF);
2005                                                                db = (((sb * sa)/0xFF) & 0xFF) + ((((0xFF - sa) * db)/0xFF) & 0xFF);
2006                                                                *((uint32_t*)r_ptr) = (da << 24) | (dr << 16) | (dg << 8) | db;
2007                                                        }
2008                                                }
2009                                                r_ptr += p->bpp/8;
2010                                        }
2011                                        if (header.pitch > rowbytes)
2012                                        {
2013                                                bgfx_read(tbuf ,1,header.pitch - rowbytes,file_p);
2014                                        }
2015                                        dst_ptr += p->surface.pitch;
2016                                }
2017                        }
2018                        else
2019#endif
2020                        {
2021                                for (row = 0; row < rows; row++)
2022                                {
2023                                        bgfx_read(dst_ptr ,1,rowbytes,file_p);
2024                                        if (header.pitch > rowbytes)
2025                                        {
2026                                                bgfx_read(tbuf ,1,header.pitch - rowbytes,file_p);
2027                                        }
2028                                        dst_ptr += p->surface.pitch;
2029                                }
2030                        }
2031                }
2032        }
2033        SGL_TRACE(("Render - done "));
2034        bgfx_cacheflush(p->surface.buf,p->surface.pitch * p->surface.height);
2035        result = 0;
2036        return result;
2037}
2038#else           /* Raymond, BGFX support rendering RGB 24bit bitmap, 20090305 */
2039
2040static uint32_t 
2041read_24(void *fin) 
2042{
2043        int b1, b2, b3;
2044
2045        bgfx_read(&b1,1,1,fin);
2046        bgfx_read(&b2,1,1,fin);
2047        bgfx_read(&b3,1,1,fin);
2048
2049        return  (uint32_t) ( (b1&0xFF) | ((b2&0xFF)<<8) | ((b3&0xFF)<<16) );
2050}
2051
2052int 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)
2053{
2054        int16_t x, y;
2055
2056        for(y=des_y + src_h- 1;y>=des_y;y--) {
2057                for(x=des_x;x<des_x + src_w;x++) {
2058                        bgfx_set_pixel(p, x, y, (0xff << 24) | read_24(file_p));
2059                }
2060        }
2061        return 0;
2062}
2063
2064int bgfx_render_buffer(bgfx_surf_p p, uint8_t format, uint16_t src_w, uint16_t src_h, uint16_t des_x, uint16_t des_y, void *pbuffer)
2065{
2066        uint16_t x, y;
2067        uint16_t c16;
2068        bgfx_pixel c24 = 0;
2069        uint8_t c24_r;
2070        uint8_t c24_g;
2071        uint8_t c24_b;
2072        uint8_t *p8 = (uint8_t *)pbuffer;
2073        int b1, b2, b3, b4;
2074
2075        for(y = des_y; y <= des_y + src_h- 1; y++) {
2076                for(x=des_x;x<des_x + src_w;x++) {
2077                        switch(format)
2078                        {
2079
2080                                case GRAPHICS_FMT_WRGB_1555:
2081                                        b1 = *p8++;
2082                                        b2 = *p8++;
2083                                        c16 = (uint16_t)((b1&0xFF) | ((b2&0xFF)<<8));
2084                                        c24_r = (c16 >> 7) & 0xf8;
2085                                        c24_g = (c16 >> 2) & 0xf8;
2086                                        c24_b = (c16 << 3) & 0xf8;
2087                                        c24 = (c24_r << 16) | (c24_g << 8) | (c24_b);
2088                                        if(c16 & 0x8000) /* alpha */
2089                                                c24 = c24 | (0xff << 24);
2090                                        break;
2091                                case GRAPHICS_FMT_ARGB_888:     /* ARGB8888 */
2092                                        b1 = *p8++;
2093                                        b2 = *p8++;
2094                                        b3 = *p8++;
2095                                        b4 = *p8++;
2096                                        c24 = (uint32_t) ( (b1&0xFF) | ((b2&0xFF)<<8) | ((b3&0xFF)<<16) | (b4%0xff)<<24);
2097                                        break;
2098                                case GRAPHICS_FMT_RGBW_5551:    /* TODO */
2099                                case GRAPHICS_FMT_ARGB_4444:    /* TODO */
2100                                case GRAPHICS_FMT_RGBA_4444:    /* TODO */
2101                                case GRAPHICS_FMT_P4:                   /* TODO */
2102                                case GRAPHICS_FMT_P8:                   /* TODO */
2103                                case GRAPHICS_FMT_RGBA_888:             /* TODO */
2104                                case GRAPHICS_FMT_RGB_565:              /* TODO */
2105                                default:
2106                                        SGL_DEBUG(("Unsupported format. "));
2107                                        break;
2108                        }
2109                        bgfx_set_pixel(p, x, y,  c24);
2110                }
2111        }
2112        return 0;
2113
2114
2115}
2116
2117
2118#endif
2119
2120
2121/****************************************************************
2122* bgfx_blit
2123*
2124* INPUTS:       p_src,p_dst - surface structure
2125*                       x,y - destination coordinates
2126* OUTPUTS:      none
2127* RETURNS:      non-zero on error
2128* FUNCTION:     Blit between the two surfaces, only the destination can be RGB
2129*
2130****************************************************************/
2131#if SOFT_GFX_AS_IN_7003
2132int bgfx_blit(bgfx_surf_p p_src, bgfx_surf_p p_dst, uint16_t x,uint16_t y)
2133{
2134        uint8_t *dst,*src;
2135        uint16_t j,w,h,rowbytes;
2136#ifdef CONFIG_BGFX_SURF_RGB
2137        uint16_t i;
2138        uint8_t *tdst;
2139#endif
2140
2141        SGL_TRACE(("bgfx_blit x,y (%d,%d) ",x,y));             
2142
2143        if ((x > p_dst->surface.width) || (y > p_dst->surface.height))
2144        {
2145                SGL_DEBUG(("bgfx_blit x,y (%d,%d) outside destination (%d,%d) ",x,y,
2146                                   p_dst->surface.width,p_dst->surface.height));
2147                return -1;
2148        }
2149
2150        w = p_src->surface.width;
2151        if (w > p_dst->surface.width - x)
2152                w = p_dst->surface.width - x;
2153        h = p_src->surface.height;
2154        if (h > p_dst->surface.height - y)
2155                h = p_dst->surface.height - y;
2156
2157        src = (uint8_t*)p_src->surface.buf;
2158        dst = (uint8_t*)p_dst->surface.buf;
2159        dst += y * p_dst->surface.pitch + x * (p_dst->bpp >> 3);
2160
2161#ifdef CONFIG_BGFX_SURF_RGB
2162        if (p_dst->flags & BGFX_SURF_RGB)
2163        {
2164                for (j = 0; j < h; ++j)
2165                {
2166                        tdst = dst;
2167
2168                        /* assume that destination and source format should be same */
2169                        if (p_dst->bpp <= 8) {
2170                                for (i = 0; i < w; ++i)
2171                                {
2172                                        if (src[i] != 0xFF)
2173                                                *((uint32_t*)tdst) = bgfx_clut8_to_rgb(p_src->palette.clut,src[i]);
2174                                        tdst += (p_dst->bpp >> 3);
2175                                }
2176                        }
2177                        else if (32 == p_dst->bpp) {
2178                                for (i = 0; i < (w << 2); i += 4, tdst += 4)
2179                                {
2180                                        *((uint32_t*)tdst) = *(uint32_t *)&src[i];
2181                                }
2182                        }
2183                        else {
2184                                for (i = 0; i < (w << 1); i += 2, tdst += 2)
2185                                {
2186                                        *((uint16_t*)tdst) = *(uint16_t *)&src[i];
2187                                }
2188                        }
2189                        dst += p_dst->surface.pitch;
2190                        src += p_src->surface.pitch;
2191                }
2192        }
2193        else
2194#endif
2195        {
2196                rowbytes = BGFX_MIN(p_src->surface.width,p_dst->surface.width - x) * (p_dst->bpp >> 3);
2197                for (j = 0; j < h; ++j)
2198                {
2199                        memcpy(dst,src,rowbytes);
2200                        dst += p_dst->surface.pitch;
2201                        src += p_src->surface.pitch;
2202                }
2203        }
2204        bgfx_cacheflush(p_dst->surface.buf,p_dst->surface.pitch * p_dst->surface.height);
2205        return 0;
2206}
2207
2208#else
2209
2210int bgfx_blit(bgfx_surf_p p_src, bgfx_surf_p p_dst, uint16_t x,uint16_t y)
2211{
2212        uint8_t *dst,*src;
2213        uint16_t j,w,h,rowbytes;
2214#ifdef CONFIG_BGFX_SURF_RGB
2215        uint16_t i;
2216        uint8_t *tdst;
2217#endif
2218
2219        SGL_TRACE(("bgfx_blit x,y (%d,%d) ",x,y));             
2220
2221        if ((x > p_dst->surface.width) || (y > p_dst->surface.height))
2222        {
2223                SGL_DEBUG(("bgfx_blit x,y (%d,%d) outside destination (%d,%d) ",x,y,
2224                                   p_dst->surface.width,p_dst->surface.height));
2225                return -1;
2226        }
2227
2228        w = p_src->surface.width;
2229        if (w > p_dst->surface.width - x)
2230                w = p_dst->surface.width - x;
2231        h = p_src->surface.height;
2232        if (h > p_dst->surface.height - y)
2233                h = p_dst->surface.height - y;
2234
2235        src = (uint8_t*)p_src->surface.buf;
2236        dst = (uint8_t*)p_dst->surface.buf;
2237        dst += y * p_dst->surface.pitch + x * p_dst->bpp/8;
2238
2239#ifdef CONFIG_BGFX_SURF_RGB
2240        if (p_dst->flags & BGFX_SURF_RGB)
2241        {
2242                for (j = 0; j < h; ++j)
2243                {
2244                        tdst = dst;
2245                        for (i = 0; i < w; ++i)
2246                        {
2247                                if (src[i] != 0xFF)
2248                                        *((uint32_t*)tdst) = bgfx_clut8_to_rgb(p_src->palette.clut,src[i]);
2249                                tdst += p_dst->bpp/8;
2250                        }
2251                        dst += p_dst->surface.pitch;
2252                        src += p_src->surface.pitch;
2253                }
2254        }
2255        else
2256#endif
2257        {
2258                rowbytes = BGFX_MIN(p_src->surface.width,p_dst->surface.width - x) * p_dst->bpp/8;
2259                for (j = 0; j < h; ++j)
2260                {
2261                        memcpy(dst,src,rowbytes);
2262                        dst += p_dst->surface.pitch;
2263                        src += p_src->surface.pitch;
2264                }
2265        }
2266        bgfx_cacheflush(p_dst->surface.buf,p_dst->surface.pitch * p_dst->surface.height);
2267        return 0;
2268}
2269#endif
2270
2271/****************************************************************
2272* INPUTS:       p_src,p_dst - source and destination buffer pointers
2273*                       sx
2274*                       dx
2275*                       w - width
2276* OUTPUTS:      none
2277* RETURNS:      non-zero on error
2278* FUNCTION:     Blit a region of one surface to another (for 4 bpp )
2279*
2280****************************************************************/
2281
2282static inline void bgfx_row_copy(unsigned char *src, unsigned char *dst,
2283                                  uint16_t sx,uint16_t dx,uint16_t w)
2284{
2285        unsigned int num_bytes = (w * 4)/8;
2286        int pix;
2287
2288        if (sx & 1)
2289        {
2290                if (dx & 1)
2291                {
2292                        *dst &= 0xF0;
2293                        *dst |= (*src & 0xF);
2294                        if (w & 1)
2295                        {
2296                                memcpy(&dst[1],&src[1],num_bytes);
2297                        }
2298                        else
2299                        {
2300                                memcpy(&dst[1],&src[1],num_bytes - 1);
2301                                dst[num_bytes] &= 0x0F;
2302                                dst[num_bytes] |= (src[num_bytes] & 0xF0);
2303                        }
2304                }
2305                else
2306                {
2307                        for (pix = 0; pix < w; ++pix)
2308                        {
2309                                if (pix & 1)
2310                                {
2311                                        *dst &= 0xF0;
2312                                        *dst |= (*src & 0xF0) >> 4;
2313                                        dst++;
2314                                }
2315                                else
2316                                {
2317                                        *dst &= 0x0F;
2318                                        *dst |= (*src & 0xF) << 4;
2319                                        src++;
2320                                }
2321                        }
2322                }
2323        }
2324        else
2325        {
2326                if (dx & 1)
2327                {
2328                        for (pix = 0; pix < w; ++pix)
2329                        {
2330                                if (pix & 1)
2331                                {
2332                                        *dst &= 0x0F;
2333                                        *dst |= (*src & 0xF) << 4;
2334                                        src++;
2335                                }
2336                                else
2337                                {
2338                                        *dst &= 0xF0;
2339                                        *dst |= (*src & 0xF0) >> 4;
2340                                        dst++;
2341                                }
2342                        }
2343                }
2344                else
2345                {
2346                        if (w & 1)
2347                        {
2348                                memcpy(dst,src,num_bytes);
2349                                dst[num_bytes] &= 0x0F;
2350                                dst[num_bytes] |= (src[num_bytes] & 0xF0);
2351                        }
2352                        else
2353                        {
2354                                memcpy(dst,src,num_bytes);
2355                        }
2356                }
2357        }
2358}
2359/****************************************************************
2360* INPUTS:       p_src,p_dst - source and destination surface structures
2361*                       sx,sy - source coordinates
2362*                       dx,dy - destination coordinates
2363*                       sw,sh - width and height of region
2364* OUTPUTS:      none
2365* RETURNS:      non-zero on error
2366* FUNCTION:     Blit a region of one surface to another
2367*
2368****************************************************************/
2369
2370#if SOFT_GFX_AS_IN_7003
2371int bgfx_blit_rect(bgfx_surf_p p_src, bgfx_surf_p p_dst, 
2372                                  uint16_t sx,uint16_t sy, uint16_t dx,uint16_t dy, 
2373                                  uint16_t sw,uint16_t sh, bool b_csc, bgfx_color_matrix_p p_csc)
2374{
2375        uint8_t *dst,*src;
2376        uint16_t j,w,h;
2377#ifdef CONFIG_BGFX_SURF_RGB
2378        uint8_t *tdst;
2379        int i;
2380#endif
2381
2382
2383        if ((dx >= p_dst->surface.width) || (dy >= p_dst->surface.height))
2384        {
2385                SGL_DEBUG(("bgfx_blit_rect dst_x,dst_y (%d,%d) outside destination (%d,%d) ",dx,dy,
2386                                        p_dst->surface.width,p_dst->surface.height));
2387                return -1;
2388        }
2389
2390        if ((sx >= p_src->surface.width) || (sy >= p_src->surface.height))
2391        {
2392                SGL_DEBUG(("bgfx_blit_rect src_x,src_y (%d,%d) outside source (%d,%d) ",sx,sy,
2393                                        p_src->surface.width,p_src->surface.height));
2394                return -1;
2395        }
2396
2397    if (p_dst->format == GRAPHICS_FMT_AYCbCr_888 && p_src->format != GRAPHICS_FMT_ARGB_888)
2398    {
2399                SGL_DEBUG(("bgfx_blit_rect dst_format=%d src_format=%d",p_dst->format, p_src->format));       
2400                SGL_DEBUG(("bgfx_blit_rect dst format YCbCr supported only if src format is ARGB8888"));
2401                return -1;       
2402    }
2403
2404        src = (uint8_t*)p_src->surface.buf;
2405        src += (sy * p_src->surface.pitch) + (sx * (p_src->bpp >> 3));
2406        dst = (uint8_t*)p_dst->surface.buf;
2407        dst += (dy * p_dst->surface.pitch) + (dx * (p_dst->bpp >> 3));
2408
2409        w = sw;
2410
2411        if (sw >= (p_src->surface.width - sx))
2412                w= p_src->surface.width - sx;
2413
2414        if (w >= p_dst->surface.width - dx)
2415                w = p_dst->surface.width - dx;
2416
2417        h = sh;
2418
2419        if (sh >= (p_src->surface.height - sy))
2420                h= p_src->surface.height - sy;
2421
2422        if (h >= p_dst->surface.height - dy)
2423                h = p_dst->surface.height - dy;
2424
2425
2426#ifdef CONFIG_BGFX_SURF_RGB
2427        if (p_dst->flags & BGFX_SURF_RGB)
2428        {
2429                for (j = 0; j < h; ++j)
2430                {
2431                        tdst = dst;
2432
2433                        if (p_dst->bpp <= 8) {
2434                                for (i = 0; i < w; ++i)
2435                                {
2436                                        if (src[i] != 0xFF)
2437                                                *((uint32_t*)tdst) = bgfx_clut8_to_rgb(p_src->palette.clut,src[i]);
2438                                        tdst += (p_dst->bpp >> 3);
2439                                }
2440                        }
2441                        else if (32 == p_dst->bpp) 
2442            {
2443               if(b_csc)
2444               {
2445                   if (p_dst->format == GRAPHICS_FMT_AYCbCr_888)
2446                   {
2447                        uint32_t rgb, y, cb, cr, a, r, g, b, shift;         
2448                        #define A p_csc->coeffMatrix
2449                        int32_t m0=A[0], m1=A[1], m2=A[2], m4=A[4];
2450                        int32_t m5=A[5], m6=A[6], m7=A[7], m9=A[9]; 
2451                        int32_t m10=A[10], m11=A[11], m12=A[12],  m14=A[14];
2452                        #undef A
2453
2454                        shift = p_csc->shift;
2455                       
2456                        for (i = 0; i < (w << 2); i += 4, tdst += 4)
2457                        {
2458                            rgb = *(uint32_t *)&src[i];
2459#ifdef COMPARE_PREVIOUS_PIXEL
2460                                                        if(i > 0 && rgb == *(uint32_t*)(&src[i-4]))
2461                                                        {
2462                                                            *((uint32_t*)tdst) = *((uint32_t*)(tdst-4));
2463                                                        }
2464                            else
2465#endif                               
2466                            {                               
2467                                a = ((rgb >> 24) & 0xff); 
2468                                r = ((rgb >> 16) & 0xff); 
2469                                g = (rgb >> 8) & 0xff;
2470                                b = rgb & 0xff;
2471                                #if 0
2472                                bgfx_csc_BT_601_RGB_2_YCbCr_macro(y, cb, cr, r, g, b);
2473                                *((uint32_t*)tdst) = ((rgb & 0xFF000000) | (y<<16) | (cb<<8) | cr);
2474                                #else
2475                                #if 0
2476                                bgfx_csc_RGB_2_YCbCr_macro_org(at, y, cb, cr, a, r, g, b);
2477                                *((uint32_t*)tdst) = ((at<<24) | (y<<16) | (cb<<8) | cr);
2478                                #else
2479                                bgfx_csc_RGB_2_YCbCr_macro(at, y, cb, cr, a, r, g, b);                               
2480                                *((uint32_t*)tdst) = ((a<<24) | (y<<16) | (cb<<8) | cr);
2481                                #endif
2482                                #endif
2483                            }
2484                        }
2485                        //SGL_DEBUG(("RGB (0x%x) -> YCbCr (0x%x)",rgb, ((at<<24) | (y<<16) | (cb<<8) | cr)));
2486                   }
2487               }
2488               else
2489               {
2490                    memcpy((void *)tdst, (void *)src, w*4);
2491               }
2492            }
2493                        else 
2494            {
2495                for (i = 0; i < (w << 1); i += 2, tdst += 2)
2496                {
2497                        *((uint16_t*)tdst) = *(uint16_t *)&src[i];
2498                }
2499            }
2500                        dst += p_dst->surface.pitch;
2501                        src += p_src->surface.pitch;
2502                }
2503        }
2504        else
2505#endif
2506        {
2507                for (j = 0; j < h; ++j)
2508                {
2509                        bgfx_row_copy(src,dst,sx,dx,w);
2510
2511                        dst += p_dst->surface.pitch;
2512                        src += p_src->surface.pitch;
2513                }
2514        }
2515        bgfx_cacheflush(p_dst->surface.buf,p_dst->surface.pitch * p_dst->surface.height);
2516        return 0;
2517}
2518
2519#else
2520
2521int bgfx_blit_rect(bgfx_surf_p p_src, bgfx_surf_p p_dst, 
2522                                  uint16_t sx,uint16_t sy, uint16_t dx,uint16_t dy, 
2523                                  uint16_t sw,uint16_t sh)
2524{
2525        uint8_t *dst,*src;
2526        uint16_t j,w,h;
2527#ifdef CONFIG_BGFX_SURF_RGB
2528        uint8_t *tdst;
2529#endif
2530
2531
2532        if ((dx >= p_dst->surface.width) || (dy >= p_dst->surface.height))
2533        {
2534                SGL_DEBUG(("bgfx_blit_rect dst_x,dst_y (%d,%d) outside destination (%d,%d) ",dx,dy,
2535                                   p_dst->surface.width,p_dst->surface.height));
2536                return -1;
2537        }
2538
2539        if ((sx >= p_src->surface.width) || (sy >= p_src->surface.height))
2540        {
2541                SGL_DEBUG(("bgfx_blit_rect src_x,src_y (%d,%d) outside source (%d,%d) ",sx,sy,
2542                                   p_src->surface.width,p_src->surface.height));
2543                return -1;
2544        }
2545       
2546        src = (uint8_t*)p_src->surface.buf;
2547        src += (sy * p_src->surface.pitch) + ((sx * p_src->bpp)/8);
2548        dst = (uint8_t*)p_dst->surface.buf;
2549        dst += (dy * p_dst->surface.pitch) + ((dx * p_dst->bpp)/8);
2550
2551    w = sw;
2552       
2553        if (sw >= (p_src->surface.width - sx))
2554                w= p_src->surface.width - sx;
2555       
2556        if (w >= p_dst->surface.width - dx)
2557                w = p_dst->surface.width - dx;
2558
2559        h = sh;
2560
2561        if (sh >= (p_src->surface.height - sy))
2562                h= p_src->surface.height - sy;
2563
2564        if (h >= p_dst->surface.height - dy)
2565                h = p_dst->surface.height - dy;
2566       
2567
2568#ifdef CONFIG_BGFX_SURF_RGB
2569        if (p_dst->flags & BGFX_SURF_RGB)
2570        {
2571                for (j = 0; j < h; ++j)
2572                {
2573                        tdst = dst;
2574                        for (i = 0; i < w; ++i)
2575                        {
2576                                if (src[i] != 0xFF)
2577                                        *((uint32_t*)tdst) = bgfx_clut8_to_rgb(p_src->palette.clut,src[i]);
2578                                tdst += p_dst->bpp/8;
2579                        }
2580                        dst += p_dst->surface.pitch;
2581                        src += p_src->surface.pitch;
2582                }
2583        }
2584        else
2585#endif
2586        {
2587                for (j = 0; j < h; ++j)
2588                {
2589                        bgfx_row_copy(src,dst,sx,dx,w);
2590
2591                        dst += p_dst->surface.pitch;
2592                        src += p_src->surface.pitch;
2593                }
2594        }
2595        bgfx_cacheflush(p_dst->surface.buf,p_dst->surface.pitch * p_dst->surface.height);
2596        return 0;
2597}
2598#endif
2599
2600
2601#if SOFT_GFX_AS_IN_7003
2602#if 0
2603/****************************************************************
2604 * INPUTS:      src1, src2 - source data pointer
2605 *                              bpp_src1, bpp_src2, bpp_dst - source and destination bits per pixel     
2606 *                              fmt_src1, fmt_src2, fmt_dst - source and distination color format
2607 *                              operation - alpha blending mode
2608 *                              alpha1 - specified alpha value for calculating R,G,B blending
2609 *                              alpha2 - specified alpha value for calculating A blending, if it's a bi-alpha format, alpha2 must = 0xff
2610 * OUTPUTS: none
2611 * RETURNS: pixel value
2612 * FUNCTION:    Blit a pixel of one surface to another
2613 *
2614 ****************************************************************/
2615static 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)
2616{
2617        uint32_t rt, gt, bt, at, rs, gs, bs, as;
2618        uint32_t p1;
2619        uint32_t p2;
2620
2621        if(bpp_src1 <= 8 || bpp_src2 <= 8 || bpp_dst <= 8) /* P4 or P8 */
2622        {
2623                SGL_DEBUG(("multi surface alpha blending only support RGB surfaces."));
2624                return -1;
2625        }
2626        if(bpp_src1 == 32)
2627                p1 = *(uint32_t *)src1;
2628        else    /* bpp = 16 */
2629                p1 = (uint32_t)(*(uint16_t *)src1);
2630
2631        if(bpp_src2 == 32)
2632                p2 = *(uint32_t *)src2;
2633        else    /* bpp = 16 */
2634                p2 = (uint32_t)(*(uint16_t *)src2);
2635
2636        BPXL_ConvertComponent(BPXL_eA8_R8_G8_B8, bgfx_colorformat_mapping(fmt_src1), p1, 2, &rs);
2637        BPXL_ConvertComponent(BPXL_eA8_R8_G8_B8, bgfx_colorformat_mapping(fmt_src2), p2, 2, &rt);
2638        BPXL_ConvertComponent(BPXL_eA8_R8_G8_B8, bgfx_colorformat_mapping(fmt_src1), p1, 1, &gs);
2639        BPXL_ConvertComponent(BPXL_eA8_R8_G8_B8, bgfx_colorformat_mapping(fmt_src2), p2, 1, &gt);
2640        BPXL_ConvertComponent(BPXL_eA8_R8_G8_B8, bgfx_colorformat_mapping(fmt_src1), p1, 0, &bs);
2641        BPXL_ConvertComponent(BPXL_eA8_R8_G8_B8, bgfx_colorformat_mapping(fmt_src2), p2, 0, &bt);
2642
2643        if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1)
2644        {
2645                as = alpha1;
2646                at = alpha1;
2647        }                                       
2648        else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC1_ALPHA)
2649        {
2650                BPXL_ConvertComponent(BPXL_eA8_R8_G8_B8, bgfx_colorformat_mapping(fmt_src1), p1, 3, &as);
2651                at = as;
2652        }
2653        else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC2_ALPHA)
2654        {
2655                BPXL_ConvertComponent(BPXL_eA8_R8_G8_B8, bgfx_colorformat_mapping(fmt_src2), p2, 3, &at);
2656                as = at;
2657        }
2658        else
2659        {
2660                BPXL_ConvertComponent(BPXL_eA8_R8_G8_B8, bgfx_colorformat_mapping(fmt_src1), p1, 3, &as);
2661                BPXL_ConvertComponent(BPXL_eA8_R8_G8_B8, bgfx_colorformat_mapping(fmt_src2), p2, 3, &at);
2662        }
2663
2664        SGL_TRACE(("******************** "));
2665        SGL_TRACE((" as=0x%x, rs=0x%x, gs=0x%x, bs=0x%x  ", as, rs, gs, bs));
2666        SGL_TRACE((" at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x  ", at, rt, gt, bt));
2667        SGL_TRACE(("******************** "));
2668
2669                /* Normal case formula
2670                * R     =       R1   *  Alpha1  +        R2     *        Alpha2  *   (1-Alpha1)
2671                * G     =       G1   *  Alpha1  +        G2     *        Alpha2  *   (1-Alpha1)   
2672                * B     =       B1   *  Alpha1  +        B2     *        Alpha2  *   (1-Alpha1)
2673                * Alpha =        1   -  (1   -  Alpha1)  *   (  1        -   Alpha2)   
2674                * R     =       R        /   Alpha       
2675                * G     =       G        /   Alpha       
2676                * B     =       B        /   Alpha       
2677                * (0<Alpha1<1, 0<Alpha2<1, 0<Alpha<1)
2678                *
2679                * Simplified as:
2680                * R = R1 * Alpha1 * ALPHA_MAX + R2 * Alpha2 * (ALPHA_MAX - Alpha1)
2681                * G = G1 * Alpha1 * ALPHA_MAX + G2 * Alpha2 * (ALPHA_MAX - Alpha1)
2682                * B = B1 * Alpha1 * ALPHA_MAX + B2 * Alpha2 * (ALPHA_MAX - Alpha1)
2683                * Alpha = Alpha1 * ALPHA_MAX + Alpha2 * ALPHA_MAX - Alpha1 * Alpha2
2684                * R = R / Alpha
2685                * G = G / Alpha
2686                * B = B / Alpha
2687                * (0<Alpha1<ALPHA_MAX, 0<Alpha2<ALPHA_MAX, 0<Alpha<ALPHA_MAX)
2688                */
2689                rt = ((rs * as) << 8) + (256 - as) * rt * at;
2690                gt = ((gs * as) << 8) + (256 - as) * gt * at;
2691                bt = ((bs * as) << 8) + (256 - as) * bt * at;
2692                at = (as << 8) + (at << 8) - as * at;
2693                rt = rt / at;
2694                gt = gt / at;
2695                bt = bt / at;
2696
2697        if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2)
2698                at = alpha2;
2699
2700        else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC1_ALPHA)
2701                BPXL_ConvertComponent(BPXL_eA8_R8_G8_B8, bgfx_colorformat_mapping(fmt_src1), p1, 3, &at);
2702        else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC2_ALPHA)
2703                BPXL_ConvertComponent(BPXL_eA8_R8_G8_B8, bgfx_colorformat_mapping(fmt_src2), p2, 3, &at);
2704        else    /* SURFBLIT_SET_DEST_ALPHA_WITH_AVG_ALPHA */
2705                at = (at >> 8);
2706
2707        SGL_TRACE(("******************** "));
2708        SGL_TRACE(("after blend, at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x ", at, rt, gt, bt));
2709        SGL_TRACE(("******************** "));
2710
2711        return BPXL_MAKE_PIXEL(bgfx_colorformat_mapping(fmt_dst), at, rt, gt, bt);
2712
2713}
2714#endif
2715
2716/* Blit rgb from two source pixel with same alpha
2717
2718Formula:
2719dst = (alpha * src + (ALPHA_MAX - alpha) * dst )/ALPHA_MAX
2720Simplified as: dst = (src - dst) * alpha >> (log2 ALPHA_MAX)  + dst
2721
2722special for ARGB8888
2723dst = (alpha * src + (256 - alpha) * dst )/256
2724Simplified as: dst = (src - dst) * alpha >> 8  + dst
2725
2726*/ 
2727#define bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, as)         \
2728        switch(as)                                                                                                                                      \
2729        {                                                                                                                                                               \
2730                case 255:                                                                                                                                       \
2731                        rt = rs;                                                                                                                                \
2732                        gt = gs;                                                                                                                                \
2733                        bt = bs;                                                                                                                                \
2734                        break;                                                                                                                                  \
2735                case 128:                                                                                                                                       \
2736                        rt = ((rs - rt) >> 1) + rt;                                                                                     \
2737                        gt = ((gs - gt) >> 1) + gt;                                                                                     \
2738                        bt = ((bs - bt) >> 1) + bt;                                                                                     \
2739                        break;                                                                                                                                  \
2740                case 64:                                                                                                                                        \
2741                        rt = ((rs - rt) >> 2) + rt;                                                                                     \
2742                        gt = ((gs - gt) >> 2) + gt;                                                                                     \
2743                        bt = ((bs - bt) >> 2) + bt;                                                                                     \
2744                        break;                                                                                                                                  \
2745                case 32:                                                                                                                                        \
2746                        rt = ((rs - rt) >> 3) + rt;                                                                                     \
2747                        gt = ((gs - gt) >> 3) + gt;                                                                                     \
2748                        bt = ((bs - bt) >> 3) + bt;                                                                                     \
2749                        break;                                                                                                                                  \
2750                case 16:                                                                                                                                        \
2751                        rt = ((rs - rt) >> 4) + rt;                                                                                     \
2752                        gt = ((gs - gt) >> 4) + gt;                                                                                     \
2753                        bt = ((bs - bt) >> 4) + bt;                                                                                     \
2754                        break;                                                                                                                                  \
2755                case 8:                                                                                                                                 \
2756                        rt = ((rs - rt) >> 5) + rt;                                                                                     \
2757                        gt = ((gs - gt) >> 5) + gt;                                                                                     \
2758                        bt = ((bs - bt) >> 5) + bt;                                                                                     \
2759                        break;                                                                                                                                  \
2760                case 4:                                                                                                                                 \
2761                        rt = ((rs - rt) >> 6) + rt;                                                                                     \
2762                        gt = ((gs - gt) >> 6) + gt;                                                                                     \
2763                        bt = ((bs - bt) >> 6) + bt;                                                                                     \
2764                        break;                                                                                                                                  \
2765                case 2:                                                                                                                                 \
2766                        rt = ((rs - rt) >> 7) + rt;                                                                                     \
2767                        gt = ((gs - gt) >> 7) + gt;                                                                                     \
2768                        bt = ((bs - bt) >> 7) + bt;                                                                                     \
2769                        break;                                                                                                                                  \
2770                case 1:                                                                                                                                 \
2771                        rt = ((rs - rt) >> 8) + rt;                                                                                     \
2772                        gt = ((gs - gt) >> 8) + gt;                                                                                     \
2773                        bt = ((bs - bt) >> 8) + bt;                                                                                     \
2774                        break;                                                                                                                                  \
2775                case 0:                                                                                                                                 \
2776                        break;                                                                                                                                  \
2777                default:                                                                                                                                        \
2778                        {                                                                                                                                               \
2779                                uint32_t shift = (as >> 8);                                                                             \
2780                                rt += (rs - rt)*shift;/* rt = rs * shift + rt - rt * shift; */                                                                  \
2781                                gt += (gs - gt)*shift; /* gt = gs * shift + gt - gt * shift; */                                                         \
2782                                bt += (bs - bt)*shift;/* bt = bs * shift + bt - bt * shift; */                                                          \
2783                        }                                                                                                                                               \
2784                }                                                                                                                                                       
2785
2786
2787/* Blit rgb from two source pixel with different alpha
2788* R     =       R1   *  Alpha1  +        R2     *        Alpha2  *   (1-Alpha1)
2789* G     =       G1   *  Alpha1  +        G2     *        Alpha2  *   (1-Alpha1)   
2790* B     =       B1   *  Alpha1  +        B2     *        Alpha2  *   (1-Alpha1)
2791* Alpha =        1   -  (1   -  Alpha1)  *   (  1        -   Alpha2)   
2792* R     =       R        /   Alpha       
2793* G     =       G        /   Alpha       
2794* B     =       B        /   Alpha       
2795* (0<Alpha1<1, 0<Alpha2<1, 0<Alpha<1)
2796*
2797* Simplified as:
2798* R = R1 * Alpha1 * ALPHA_MAX + R2 * Alpha2 * (ALPHA_MAX - Alpha1)
2799* G = G1 * Alpha1 * ALPHA_MAX + G2 * Alpha2 * (ALPHA_MAX - Alpha1)
2800* B = B1 * Alpha1 * ALPHA_MAX + B2 * Alpha2 * (ALPHA_MAX - Alpha1)
2801* Alpha = Alpha1 * ALPHA_MAX + Alpha2 * ALPHA_MAX - Alpha1 * Alpha2
2802* R = R / Alpha
2803* G = G / Alpha
2804* B = B / Alpha
2805* (0<Alpha1<ALPHA_MAX, 0<Alpha2<ALPHA_MAX, 0<Alpha<ALPHA_MAX)
2806*/ 
2807#ifdef SIMPLE_BLENDING_FORMULA
2808#define bgfx_blit_pixel_different_alphasrc_macro(rt, gt, bt, at, rs, gs, bs, as) \
2809        {                                                                                                                                                                                       \
2810                rt = rs * as + (256 - as) * rt;                                                                                 \
2811                gt = gs * as + (256 - as) * gt;                                                                                 \
2812                bt = bs * as + (256 - as) * bt;                                                                                 \
2813                at = ((as + at) << 8) - as * at; /* at = (as << 8) + (at << 8) - as * at; */                                                                                            \
2814                rt = (rt >> 8);                                                                                                                                         \
2815                gt = (gt >> 8);                                                                                                                                         \
2816                bt = (bt >> 8);                                                                                                                                         \
2817                at = (at >> 8);                                                                                                                                         \
2818        }
2819#else
2820#define bgfx_blit_pixel_different_alphasrc_macro(rt, gt, bt, at, rs, gs, bs, as)        \
2821        {                                                                                                                                                                                       \
2822                rt = ((rs * as) << 8) + (256 - as) * rt * at;                                                                           \
2823                gt = ((gs * as) << 8) + (256 - as) * gt * at;                                                                   \
2824                bt = ((bs * as) << 8) + (256 - as) * bt * at;                                                                   \
2825                at = (as << 8) + (at << 8) - as * at;                                                                                           \
2826                rt = rt / at;                                                                                                                                                   \
2827                gt = gt / at;                                                                                                                                                   \
2828                bt = bt / at;                                                                                                                                                   \
2829                at = (at >> 8);                                                                                                                                         \
2830        }
2831#endif
2832
2833#if 0
2834static int bgfx_blit_pixel_RGB565(void *src1, void *src2, unsigned int operation, uint32_t alpha1, uint32_t alpha2)
2835{
2836        uint32_t rt, gt, bt, at, rs, gs, bs, as;
2837        uint32_t p1;
2838        uint32_t p2;
2839
2840        p1 = (uint32_t)(*(uint16_t *)src1);
2841        p2 = (uint32_t)(*(uint16_t *)src2);
2842       
2843        rs = (p1 >> 11) & 0x1f;
2844        gs = (p1 >> 5) & 0x3f;
2845        bs = p1 & 0x1f;
2846        rt = (p2 >> 11) & 0x1f;
2847        gt = (p2 >> 5) & 0x3f;
2848        bt = p2 & 0x1f;
2849
2850        as = alpha1;
2851        at = alpha1;
2852
2853//#define SGL_TRACE(x) printf x
2854
2855        SGL_TRACE(("******************** "));
2856        SGL_TRACE((" as=0x%x, rs=0x%x, gs=0x%x, bs=0x%x  ", as, rs, gs, bs));
2857        SGL_TRACE((" at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x  ", at, rt, gt, bt));
2858        SGL_TRACE(("******************** "));
2859
2860        if(as == at)
2861                bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, as)
2862        else
2863                bgfx_blit_pixel_different_alphasrc_macro(rt, gt, bt, at, rs, gs, bs, as)
2864
2865        SGL_TRACE(("******************** "));
2866        SGL_TRACE(("after blend, rt=0x%x, gt=0x%x, bt=0x%x ", rt, gt, bt));
2867        SGL_TRACE(("******************** "));
2868
2869        return (rt << 11) | (gt << 5) | bt;
2870}
2871#endif
2872
2873static int bgfx_blit_pixel_RGB565_ideal(void *src1, void *src2, uint32_t alpha1, uint32_t alpha2)
2874{
2875        uint32_t rt, gt, bt, rs, gs, bs;
2876        uint32_t p1;
2877        uint32_t p2;
2878
2879    BSTD_UNUSED(alpha2);
2880
2881        p1 = *(uint16_t *)src1;
2882        p2 = *(uint16_t *)src2;
2883       
2884        rs = (p1 >> 11) & 0x1f;
2885        gs = (p1 >> 5) & 0x3f;
2886        bs = p1 & 0x1f;
2887        rt = (p2 >> 11) & 0x1f;
2888        gt = (p2 >> 5) & 0x3f;
2889        bt = p2 & 0x1f;
2890
2891        bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, alpha1)
2892
2893        return (rt << 11) | (gt << 5) | bt;
2894}
2895
2896static int bgfx_blit_pixel_ARGB4444(void *src1, void *src2, unsigned int operation, uint32_t alpha1, uint32_t alpha2)
2897{
2898        uint32_t rt, gt, bt, at, rs, gs, bs, as;
2899        uint32_t p1;
2900        uint32_t p2;
2901
2902        p1 = (uint32_t)(*(uint16_t *)src1);
2903        p2 = (uint32_t)(*(uint16_t *)src2);
2904       
2905        rs = (p1 >> 8) & 0xf;
2906        gs = (p1 >> 4) & 0xf;
2907        bs = p1 & 0xf;
2908        rt = (p2 >> 8) & 0xf;
2909        gt = (p2 >> 4) & 0xf;
2910        bt = p2 & 0xf;
2911
2912        if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1)
2913        {
2914                as = alpha1;
2915                at = alpha1;
2916        }                                       
2917        else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC1_ALPHA)
2918        {
2919                as = ((p1 >> 12) & 0xf) << 4;
2920                at = as;
2921        }
2922        else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC2_ALPHA)
2923        {
2924                at = ((p2 >> 12) & 0xf) << 4;
2925                as = at;
2926        }
2927        else
2928        {
2929                as = ((p1 >> 12) & 0xf) << 4;
2930                at = ((p2 >> 12) & 0xf) << 4;
2931        }
2932//#define SGL_TRACE(x) printf x
2933
2934        SGL_TRACE(("******************** "));
2935        SGL_TRACE((" as=0x%x, rs=0x%x, gs=0x%x, bs=0x%x  ", as, rs, gs, bs));
2936        SGL_TRACE((" at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x  ", at, rt, gt, bt));
2937        SGL_TRACE(("******************** "));
2938
2939        if(as == at)
2940                bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, as)
2941        else
2942                bgfx_blit_pixel_different_alphasrc_macro(rt, gt, bt, at, rs, gs, bs, as)
2943
2944        if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2)
2945                at = alpha2;
2946        else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC1_ALPHA)
2947                at = p1 & 0xf000;
2948        else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC2_ALPHA)
2949                at = p2 & 0xf000;
2950        else
2951                at = (at >> 4) << 12;
2952               
2953        SGL_TRACE(("******************** "));
2954        SGL_TRACE(("after blend, at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x ", at, rt, gt, bt));
2955        SGL_TRACE(("******************** "));
2956
2957        return at | (rt << 8) | (gt << 4) | bt;
2958}
2959
2960static int bgfx_blit_pixel_ARGB4444_ideal(void *src1, void *src2, uint32_t alpha1, uint32_t alpha2)
2961{
2962        uint32_t rt, gt, bt, rs, gs, bs;
2963        uint32_t p1;
2964        uint32_t p2;
2965
2966        p1 = *(uint16_t *)src1;
2967        p2 = *(uint16_t *)src2;
2968       
2969        rs = (p1 >> 8) & 0xf;
2970        gs = (p1 >> 4) & 0xf;
2971        bs = p1 & 0xf;
2972        rt = (p2 >> 8) & 0xf;
2973        gt = (p2 >> 4) & 0xf;
2974        bt = p2 & 0xf;
2975
2976        bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, alpha1)
2977
2978        return alpha2 | (rt << 8) | (gt << 4) | bt;
2979}
2980
2981static int bgfx_blit_pixel_RGBA4444(void *src1, void *src2, unsigned int operation, uint32_t alpha1, uint32_t alpha2)
2982{
2983        uint32_t rt, gt, bt, at, rs, gs, bs, as;
2984        uint32_t p1;
2985        uint32_t p2;
2986
2987        p1 = (uint32_t)(*(uint16_t *)src1);
2988        p2 = (uint32_t)(*(uint16_t *)src2);
2989
2990        rs = (p1 >> 12) & 0xf;
2991        gs = (p1 >> 8) & 0xf;
2992        bs = (p1 >> 4) & 0xf;
2993        rt = (p2 >> 12) & 0xf;
2994        gt = (p2 >> 8) & 0xf;
2995        bt = (p2 >> 4) & 0xf;
2996
2997        if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1)
2998        {
2999                as = alpha1;
3000                at = alpha1;
3001        }                                       
3002        else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC1_ALPHA)
3003        {
3004                as = (p1 & 0xf) << 4;
3005                at = as;
3006        }
3007        else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC2_ALPHA)
3008        {
3009                at = (p2 & 0xf) << 4;
3010                as = at;
3011        }
3012        else
3013        {
3014                as = (p1 & 0xf) << 4;
3015                at = (p2 & 0xf) << 4;
3016        }
3017//#define SGL_TRACE(x) printf x
3018
3019        SGL_TRACE(("******************** "));
3020        SGL_TRACE((" as=0x%x, rs=0x%x, gs=0x%x, bs=0x%x  ", as, rs, gs, bs));
3021        SGL_TRACE((" at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x  ", at, rt, gt, bt));
3022        SGL_TRACE(("******************** "));
3023
3024        if(as == at)
3025                bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, as)
3026        else
3027                bgfx_blit_pixel_different_alphasrc_macro(rt, gt, bt, at, rs, gs, bs, as)
3028
3029        if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2)
3030                at = alpha2;
3031        else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC1_ALPHA)
3032                at = p1 & 0xf;
3033        else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC2_ALPHA)
3034                at = p2 & 0xf;
3035        else
3036                at = (at >> 4);
3037
3038        SGL_TRACE(("******************** "));
3039        SGL_TRACE(("after blend, at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x ", at, rt, gt, bt));
3040        SGL_TRACE(("******************** "));
3041
3042        return (rt << 12) | (gt << 8) | (bt << 4) | at;
3043}
3044
3045static int bgfx_blit_pixel_RGBA4444_ideal(void *src1, void *src2, uint32_t alpha1, uint32_t alpha2)
3046{
3047        uint32_t rt, gt, bt, rs, gs, bs;
3048        uint32_t p1;
3049        uint32_t p2;
3050
3051        p1 = *(uint16_t *)src1;
3052        p2 = *(uint16_t *)src2;
3053
3054        rs = (p1 >> 12) & 0xf;
3055        gs = (p1 >> 8) & 0xf;
3056        bs = (p1 >> 4) & 0xf;
3057        rt = (p2 >> 12) & 0xf;
3058        gt = (p2 >> 8) & 0xf;
3059        bt = (p2 >> 4) & 0xf;
3060
3061        bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, alpha1)
3062
3063        return (rt << 12) | (gt << 8) | (bt << 4) | alpha2;
3064}
3065
3066static int bgfx_blit_pixel_WRGB1555(void *src1, void *src2, unsigned int operation, uint32_t alpha1, uint32_t alpha2)
3067{
3068        uint32_t rt, gt, bt, at, rs, gs, bs, as;
3069        uint32_t p1;
3070        uint32_t p2;
3071
3072        p1 = (uint32_t)(*(uint16_t *)src1);
3073        p2 = (uint32_t)(*(uint16_t *)src2);
3074       
3075        rs = (p1 >> 10) & 0x1f;
3076        gs = (p1 >> 5) & 0x1f;
3077        bs = p1 & 0x1f;
3078        rt = (p2 >> 10) & 0x1f;
3079        gt = (p2 >> 5) & 0x1f;
3080        bt = p2 & 0x1f;
3081
3082        if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1)
3083        {
3084                as = alpha1;
3085                at = alpha1;
3086        }                                       
3087        else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC1_ALPHA)
3088        {
3089                as = (p1 & 0x8000)? 0xff: 0;
3090                at = as;
3091        }
3092        else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC2_ALPHA)
3093        {
3094                at = (p2 & 0x8000)? 0xff: 0;
3095                as = at;
3096        }
3097        else
3098        {
3099                as = (p1 & 0x8000)? 0xff: 0;
3100                at = (p2 & 0x8000)? 0xff: 0;
3101        }
3102//#define SGL_TRACE(x) printf x
3103
3104        SGL_TRACE(("******************** "));
3105        SGL_TRACE((" as=0x%x, rs=0x%x, gs=0x%x, bs=0x%x  ", as, rs, gs, bs));
3106        SGL_TRACE((" at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x  ", at, rt, gt, bt));
3107        SGL_TRACE(("******************** "));
3108
3109        if(as == at)
3110                bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, as)
3111        else
3112                bgfx_blit_pixel_different_alphasrc_macro(rt, gt, bt, at, rs, gs, bs, as)
3113
3114        if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2)
3115                at = alpha2;
3116        else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC1_ALPHA)
3117                at = p1 & 0x8000;
3118        else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC2_ALPHA)
3119                at = p2 & 0x8000;
3120        else
3121                at = (at == 0xff)? 0x8000: 0;
3122
3123        SGL_TRACE(("******************** "));
3124        SGL_TRACE(("after blend, at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x ", at, rt, gt, bt));
3125        SGL_TRACE(("******************** "));
3126
3127        return at | (rt << 10) | (gt << 5) | bt;               
3128}
3129
3130static int bgfx_blit_pixel_WRGB1555_ideal(void *src1, void *src2, uint32_t alpha1, uint32_t alpha2)
3131{
3132        uint32_t rt, gt, bt, rs, gs, bs;
3133        uint32_t p1;
3134        uint32_t p2;
3135
3136        p1 = *(uint16_t *)src1;
3137        p2 = *(uint16_t *)src2;
3138       
3139        rs = (p1 >> 10) & 0x1f;
3140        gs = (p1 >> 5) & 0x1f;
3141        bs = p1 & 0x1f;
3142        rt = (p2 >> 10) & 0x1f;
3143        gt = (p2 >> 5) & 0x1f;
3144        bt = p2 & 0x1f;
3145
3146        bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, alpha1)
3147
3148        return alpha2 | (rt << 10) | (gt << 5) | bt;           
3149}
3150
3151
3152static int bgfx_blit_pixel_RGBW5551(void *src1, void *src2, unsigned int operation, uint32_t alpha1, uint32_t alpha2)
3153{
3154        uint32_t rt, gt, bt, at, rs, gs, bs, as;
3155        uint32_t p1;
3156        uint32_t p2;
3157
3158        p1 = (uint32_t)(*(uint16_t *)src1);
3159        p2 = (uint32_t)(*(uint16_t *)src2);
3160
3161        rs = (p1 >> 11) & 0x1f;
3162        gs = (p1 >> 6) & 0x1f;
3163        bs = (p1 >> 1) & 0x1f;
3164        rt = (p2 >> 11) & 0x1f;
3165        gt = (p2 >> 6) & 0x1f;
3166        bt = (p2 >> 1) & 0x1f;
3167
3168        if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1)
3169        {
3170                as = alpha1;
3171                at = alpha1;
3172        }                                       
3173        else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC1_ALPHA)
3174        {
3175                as = (p1 & 0x1)? 0xff: 0;
3176                at = as;
3177        }
3178        else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC2_ALPHA)
3179        {
3180                at = (p2 & 0x1)? 0xff: 0;
3181                as = at;
3182        }
3183        else
3184        {
3185                as = (p1 & 0x1)? 0xff: 0;
3186                at = (p2 & 0x1)? 0xff: 0;
3187        }
3188//#define SGL_TRACE(x) printf x
3189
3190        SGL_TRACE(("******************** "));
3191        SGL_TRACE((" as=0x%x, rs=0x%x, gs=0x%x, bs=0x%x  ", as, rs, gs, bs));
3192        SGL_TRACE((" at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x  ", at, rt, gt, bt));
3193        SGL_TRACE(("******************** "));
3194
3195        if(as == at)
3196                bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, as)
3197        else
3198                bgfx_blit_pixel_different_alphasrc_macro(rt, gt, bt, at, rs, gs, bs, as)
3199
3200        if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2)
3201                at = alpha2;
3202        else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC1_ALPHA)
3203                at = p1 & 0x1;
3204        else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC2_ALPHA)
3205                at = p2 & 0x1;
3206        else
3207                at = (at == 0xff)? 1: 0;
3208
3209        SGL_TRACE(("******************** "));
3210        SGL_TRACE(("after blend, at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x ", at, rt, gt, bt));
3211        SGL_TRACE(("******************** "));
3212
3213        return (rt << 11) | (gt << 6) | (bt << 1) | at;
3214}
3215
3216static int bgfx_blit_pixel_RGBW5551_ideal(void *src1, void *src2, uint32_t alpha1, uint32_t alpha2)
3217{
3218        uint32_t rt, gt, bt, rs, gs, bs;
3219        uint32_t p1;
3220        uint32_t p2;
3221
3222        p1 = *(uint16_t *)src1;
3223        p2 = *(uint16_t *)src2;
3224
3225        rs = (p1 >> 11) & 0x1f;
3226        gs = (p1 >> 6) & 0x1f;
3227        bs = (p1 >> 1) & 0x1f;
3228        rt = (p2 >> 11) & 0x1f;
3229        gt = (p2 >> 6) & 0x1f;
3230        bt = (p2 >> 1) & 0x1f;
3231
3232        bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, alpha1)
3233
3234        return (rt << 11) | (gt << 6) | (bt << 1) | alpha2;
3235}
3236
3237static int bgfx_blit_pixel_ARGB8888(void *src1, void *src2, unsigned int operation, uint32_t alpha1, uint32_t alpha2)
3238{
3239        uint32_t rt, gt, bt, at, rs, gs, bs, as;
3240        uint32_t p1;
3241        uint32_t p2;
3242
3243        p1 = *(uint32_t *)src1;
3244        p2 = *(uint32_t *)src2;
3245       
3246        rs = (p1 >> 16) & 0xff;
3247        gs = (p1 >> 8) & 0xff;
3248        bs = p1 & 0xff;
3249        rt = (p2 >> 16) & 0xff;
3250        gt = (p2 >> 8) & 0xff;
3251        bt = p2 & 0xff;
3252
3253        if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1)
3254        {
3255                as = alpha1;
3256                at = alpha1;
3257        }                                       
3258        else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC1_ALPHA)
3259        {
3260                as = (p1 >> 24) & 0xff;
3261                at = as;
3262        }
3263        else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC2_ALPHA)
3264        {
3265                at = (p2 >> 24) & 0xff;
3266                as = at;
3267        }
3268        else
3269        {
3270                as = (p1 >> 24) & 0xff;
3271                at = (p2 >> 24) & 0xff;
3272        }
3273//#define SGL_TRACE(x) printf x
3274
3275        SGL_TRACE(("******************** "));
3276        SGL_TRACE((" as=0x%x, rs=0x%x, gs=0x%x, bs=0x%x  ", as, rs, gs, bs));
3277        SGL_TRACE((" at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x  ", at, rt, gt, bt));
3278        SGL_TRACE(("******************** "));
3279
3280        if(as == at)
3281                bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, as)
3282        else
3283                bgfx_blit_pixel_different_alphasrc_macro(rt, gt, bt, at, rs, gs, bs, as)
3284
3285        if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2)
3286                at = alpha2;
3287        else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC1_ALPHA)
3288                at = p1 & 0xff000000;
3289        else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC2_ALPHA)
3290                at = p2 & 0xff000000;
3291        else
3292                at = (at << 24);
3293
3294        SGL_TRACE(("******************** "));
3295        SGL_TRACE(("after blend, at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x ", at, rt, gt, bt));
3296        SGL_TRACE(("******************** "));
3297
3298        return at | (rt << 16) | (gt << 8) | bt;
3299}
3300
3301static int bgfx_blit_pixel_ARGB8888_ideal(void *src1, void *src2, uint32_t alpha1, uint32_t alpha2)
3302{
3303        uint32_t rt, gt, bt, rs, gs, bs;
3304        uint32_t p1;
3305        uint32_t p2;
3306
3307        p1 = *(uint32_t *)src1;
3308        p2 = *(uint32_t *)src2;
3309       
3310        rs = (p1 >> 16) & 0xff;
3311        gs = (p1 >> 8) & 0xff;
3312        bs = p1 & 0xff;
3313        rt = (p2 >> 16) & 0xff;
3314        gt = (p2 >> 8) & 0xff;
3315        bt = p2 & 0xff;
3316
3317        bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, alpha1)
3318
3319        return alpha2 | (rt << 16) | (gt << 8) | bt;
3320}
3321
3322static int bgfx_blit_pixel_RGBA8888(void *src1, void *src2, unsigned int operation, uint32_t alpha1, uint32_t alpha2)
3323{
3324        uint32_t rt, gt, bt, at, rs, gs, bs, as;
3325        uint32_t p1;
3326        uint32_t p2;
3327
3328        p1 = *(uint32_t *)src1;
3329        p2 = *(uint32_t *)src2;
3330
3331        rs = (p1 >> 24) & 0xff;
3332        gs = (p1 >> 16) & 0xff;
3333        bs = (p1 >> 8) & 0xff;
3334        rt = (p2 >> 24) & 0xff;
3335        gt = (p2 >> 16) & 0xff;
3336        bt = (p2 >> 8) & 0xff;
3337
3338        if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1)
3339        {
3340                as = alpha1;
3341                at = alpha1;
3342        }                                       
3343        else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC1_ALPHA)
3344        {
3345
3346                as = p1 & 0xff;
3347                at = as;
3348        }
3349        else if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SRC2_ALPHA)
3350        {
3351
3352                at = p2 & 0xff;
3353                as = at;
3354        }
3355        else
3356        {
3357                as = p1 & 0xff;
3358                at = p2 & 0xff;
3359        }
3360//#define SGL_TRACE(x) printf x
3361
3362        SGL_TRACE(("******************** "));
3363        SGL_TRACE((" as=0x%x, rs=0x%x, gs=0x%x, bs=0x%x  ", as, rs, gs, bs));
3364        SGL_TRACE((" at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x  ", at, rt, gt, bt));
3365        SGL_TRACE(("******************** "));
3366
3367        if(as == at)
3368                bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, as)
3369        else
3370                bgfx_blit_pixel_different_alphasrc_macro(rt, gt, bt, at, rs, gs, bs, as)
3371
3372        if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2)
3373                at = alpha2;
3374        else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC1_ALPHA)
3375                at = p1 & 0xff;
3376        else if((operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SRC2_ALPHA)
3377                at = p2 & 0xff;
3378
3379        SGL_TRACE(("******************** "));
3380        SGL_TRACE(("after blend, at=0x%x, rt=0x%x, gt=0x%x, bt=0x%x ", at, rt, gt, bt));
3381        SGL_TRACE(("******************** "));
3382
3383        return (rt << 24) | (gt << 16) | (bt << 8) | at;
3384}
3385
3386static int bgfx_blit_pixel_RGBA8888_ideal(void *src1, void *src2, uint32_t alpha1, uint32_t alpha2)
3387{
3388        uint32_t rt, gt, bt, rs, gs, bs;
3389        uint32_t p1;
3390        uint32_t p2;
3391
3392        p1 = *(uint32_t *)src1;
3393        p2 = *(uint32_t *)src2;
3394
3395        rs = (p1 >> 24) & 0xff;
3396        gs = (p1 >> 16) & 0xff;
3397        bs = (p1 >> 8) & 0xff;
3398        rt = (p2 >> 24) & 0xff;
3399        gt = (p2 >> 16) & 0xff;
3400        bt = (p2 >> 8) & 0xff;
3401
3402        bgfx_blit_pixel_same_alphasrc_macro(rt, gt, bt, rs, gs, bs, alpha1)
3403
3404        return (rt << 24) | (gt << 16) | (bt << 8) | alpha2;
3405}
3406
3407static int bgfx_blit_pixel_ARGB8888_optimized(void *src1, void *src2)
3408{
3409        // note operation, alpha1, alpha2 all unused. Hardcoded to operation 0x33
3410#if 0
3411    /* Basic equation is:
3412                rt = (rs * as + (256 - as) * rt) >> 8; 
3413                gt = (gs * as + (256 - as) * gt) >> 8;         
3414                bt = (bs * as + (256 - as) * bt) >> 8;         
3415                at = (((as + at) << 8) - as * at) >> 8;
3416
3417        Most of the menu as values are 0xb2 (178 = 70%), 0xee (238 = 93%), 0xff (255 = 100%) you could approximate with:
3418        if (as=0)
3419        {
3420           use as=0 then the basic equation becomes:
3421                rt = rt; gt = gt; bt = bt; at = at;
3422           therefore, out pixel = src2 pixel;     
3423        }
3424        else if (as >= 0xee)
3425        {
3426            use as=0xff  so no need to extract rt/gt/bt and then compute by shifts
3427            Basic equation becomes:
3428                rt = (rs *as) >> 8;
3429            =>  rt = rs;
3430                gt = gs;
3431                bt = rs;
3432               
3433                at = ((256 + at) * 256 - 256 * at ) / 256
3434                   = 256
3435                   = as;
3436           therefore, out pixel = src1 pixel;                                               
3437        }
3438        else if (as >= 0xb2)
3439        {
3440            use as = 75%, at = 25% and then compute by shifts
3441            Basic equation becomes:
3442                rt = (rs * as + (256 - as) * rt) >> 8; 
3443                   = (rs * 256*3/4 + (256 - 256*3/4) * rt) / 256
3444                   = (rs * 3/4 + rt/4)
3445                   = (rs * 3 + rt) / 4
3446                   = (rs * 3 + rt) >> 2
3447            =>  rt = (rs + rs + rs + rt) >> 2
3448                gt = (gs + gs + gs + gt) >> 2
3449                bt = (bs + bs + bs + bt) >> 2
3450
3451                at = (((256*3/4 + 256/4) * 256) - 256*3/4 * 256/4) / 256;               
3452                   = ((256*256) - 256*256*3/16)/256;
3453                   = 256*13/16;
3454            =>  at = 208;
3455        }
3456        else
3457        {
3458            use basic equation
3459        }
3460    */
3461        register uint32_t rt, gt, bt, at, rs, gs, bs, as;
3462        register uint32_t p1,p2;
3463
3464        p2 = *(uint32_t *)src2;
3465        p1 = *(uint32_t *)src1;
3466        as = (p1 >> 24) & 0xff;
3467
3468    if(as == 0)
3469    {
3470        /* out pixel = src2 pixel */
3471        return p2;
3472    }
3473    else if (as >= 0xee)
3474    {
3475        /* out pixel = src1 pixel */
3476        return p1;
3477    }
3478    else if (as >= 0xb2)
3479    {
3480        /* Use as = 75%, at = 25%, basic equation simplifies to: */
3481        rs = (p1 >> 16) & 0xff;
3482        rt = (p2 >> 16) & 0xff;
3483        rt = (rs + rs + rs + rt) >> 2;
3484       
3485        gs = (p1 >> 8) & 0xff;
3486        gt = (p2 >> 8) & 0xff;
3487        gt = (gs + gs + gs + gt) >> 2;
3488       
3489        bs = p1 & 0xff;
3490        bt = p2 & 0xff;       
3491        bt = (bs + bs + bs + bt) >> 2;
3492
3493        at = 208;
3494    }
3495    else
3496    {
3497        /* Execute basic equation for all other cases */
3498        //bgfx_blit_pixel_different_alphasrc_macro(rt, gt, bt, at, rs, gs, bs, as);
3499        rs = (p1 >> 16) & 0xff;
3500        rt = (p2 >> 16) & 0xff;
3501        rt = (rs * as + (256 - as) * rt) >> 8; 
3502
3503        gs = (p1 >> 8) & 0xff;
3504        gt = (p2 >> 8) & 0xff;       
3505        gt = (gs * as + (256 - as) * gt) >> 8;         
3506
3507        bs = p1 & 0xff;
3508        bt = p2 & 0xff;       
3509        bt = (bs * as + (256 - as) * bt) >> 8;         
3510
3511        at = (p2 >> 24) & 0xff;
3512        at = (((as + at) << 8) - as * at) >> 8;         
3513    }   
3514#else
3515
3516        register uint32_t rt, gt, bt, at, rs, gs, bs, as;
3517        register uint32_t p1,p2;
3518    uint32_t tmp_at, tmp_as;
3519       
3520        p2 = *(uint32_t *)src2;
3521        p1 = *(uint32_t *)src1;
3522
3523        //bgfx_blit_pixel_different_alphasrc_macro(rt, gt, bt, at, rs, gs, bs, as);
3524        tmp_as = p1  & 0xff000000;
3525    if( tmp_as == 0 )
3526        return p2;
3527
3528    tmp_at = p2  & 0xff000000;       
3529    if(tmp_at == 0)
3530        return p1;
3531
3532    as = tmp_as >> 24;
3533    at = tmp_at >> 24;
3534   
3535    rs = (p1 >> 16) & 0xff;
3536        gs = (p1 >> 8) & 0xff;
3537    bs = p1 & 0xff;
3538   
3539    rt = (p2 >> 16) & 0xff;
3540        gt = (p2 >> 8) & 0xff;       
3541        bt = p2 & 0xff;       
3542        rt = (rs * as + (256 - as) * rt) >> 8; 
3543        gt = (gs * as + (256 - as) * gt) >> 8;         
3544        bt = (bs * as + (256 - as) * bt) >> 8;         
3545        at = (((as + at) << 8) - as * at) >> 8; 
3546
3547#endif
3548   
3549#if (PRINT_ON ==1)
3550        printf("p1=%x, p2=%x \r\n", p1,p2);
3551        printf("rs=%x, gs=%x, bs=%x\r\n", rs,gs,bs);
3552        printf("rt=%x, gt=%x, bt=%x\r\n", rt,gt,bt);
3553#endif
3554
3555#if 0
3556        //bgfx_blit_pixel_different_alphasrc_macro(rt, gt, bt, at, rs, gs, bs, as);
3557        rt = (rs * as + (256 - as) * rt) >> 8; 
3558        gt = (gs * as + (256 - as) * gt) >> 8;         
3559        bt = (bs * as + (256 - as) * bt) >> 8;         
3560        at = (((as + at) << 8) - as * at) >> 8;
3561#endif
3562
3563#if (PRINT_ON ==1)
3564        printf("rt=%x, gt=%x, bt=%x, at=%x\r\n", rt,gt,bt, at);
3565#endif
3566        return (at << 24) | (rt << 16) | (gt << 8) | bt;
3567}
3568
3569
3570/****************************************************************
3571 * INPUTS:      p_src1, p_src2, p_dst - source and destination surface structures
3572 *              s1x,s1y,s2x,s2y - source coordinates
3573 *              dx,dy - destination coordinates
3574 *              sw,sh - width and height of region
3575 *      operation - alpha blending settings
3576 *      alpha1 - specified alpha value for calculating R,G,B blending
3577 *      alpha2 - specified alpha value for calculating A blending
3578 * OUTPUTS: none
3579 * RETURNS: non-zero on error
3580 * FUNCTION:    Blit a region of one surface to another
3581 *
3582 ****************************************************************/
3583
3584int bgfx_blit_rect_multisuf_blending(bgfx_surf_p p_src1, bgfx_surf_p p_src2, bgfx_surf_p p_dst, 
3585                uint16_t s1x,uint16_t s1y, uint16_t s2x,uint16_t s2y, uint16_t dx,uint16_t dy, 
3586                uint16_t sw, uint16_t sh, unsigned int operation, uint32_t alpha1, uint32_t alpha2)
3587{
3588        uint8_t *dst,*src1, *src2;
3589        uint16_t j,w,h;
3590#ifdef CONFIG_BGFX_SURF_RGB
3591        uint8_t *tdst;
3592        uint32_t i;
3593        uint32_t dst_pitch;
3594        uint16_t dst_step;
3595#endif
3596
3597        if ((dx >= p_dst->surface.width) || (dy >= p_dst->surface.height))
3598        {
3599                SGL_DEBUG(("bgfx_blit_rect dst_x,dst_y (%d,%d) outside destination (%d,%d) ",dx,dy,
3600                                        p_dst->surface.width,p_dst->surface.height));
3601                return -1;
3602        }
3603
3604        if ((s1x >= p_src1->surface.width) || (s1y >= p_src1->surface.height))
3605        {
3606                SGL_DEBUG(("bgfx_blit_rect src_x,src_y (%d,%d) outside source (%d,%d) ",s1x,s1y,
3607                                        p_src1->surface.width,p_src1->surface.height));
3608                return -1;
3609        }
3610
3611        if ((s2x >= p_src2->surface.width) || (s2y >= p_src2->surface.height))
3612        {
3613                SGL_DEBUG(("bgfx_blit_rect src_x,src_y (%d,%d) outside source (%d,%d) ",s2x,s2y,
3614                                        p_src2->surface.width,p_src2->surface.height));
3615                return -1;
3616        }
3617
3618        src1 = (uint8_t*)p_src1->surface.buf;
3619        src1 += (s1y * p_src1->surface.pitch) + (s1x * (p_src1->bpp >> 3));
3620
3621        src2 = (uint8_t*)p_src2->surface.buf;
3622        src2 += (s2y * p_src2->surface.pitch) + (s2x * (p_src2->bpp >> 3));
3623
3624        dst = (uint8_t*)p_dst->surface.buf;
3625        dst += (dy * p_dst->surface.pitch) + (dx * (p_dst->bpp >> 3));
3626
3627        w = sw;
3628
3629        if (sw >= (p_src1->surface.width - s1x))
3630                w= p_src1->surface.width - s1x;
3631        if (w >= (p_src2->surface.width - s2x))
3632                w= p_src2->surface.width - s2x;
3633        if (w >= p_dst->surface.width - dx)
3634                w = p_dst->surface.width - dx;
3635        h = sh;
3636
3637        if (sh >= (p_src1->surface.height - s1y))
3638                h= p_src1->surface.height - s1y;
3639        if (sh >= (p_src2->surface.height - s2y))
3640                h= p_src2->surface.height - s2y;
3641        if (h >= p_dst->surface.height - dy)
3642                h = p_dst->surface.height - dy;
3643
3644        SGL_TRACE(("w=%d ", w));
3645        SGL_TRACE(("h=%d ", h));
3646        SGL_TRACE(("operation=%d ", operation));
3647
3648        dst_step = (p_dst->bpp >> 3);
3649        dst_pitch = dst_step * w;
3650#ifdef CONFIG_BGFX_SURF_RGB
3651        if (p_dst->flags & BGFX_SURF_RGB)
3652        {
3653                switch(p_dst->format)
3654                        {
3655                                case GRAPHICS_FMT_ARGB_888:
3656                                        alpha2 = (alpha2 << 24);
3657                                        if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1 && (operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2)
3658                                        {
3659                                                for (j = 0; j < h; ++j)
3660                                                {
3661                                                        tdst = dst;
3662                                                        for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step)
3663                            {
3664#ifdef COMPARE_PREVIOUS_PIXEL
3665                                                                if(i > 0 && *(uint32_t*)(&src1[i]) == *(uint32_t*)(&src1[i-dst_step]) && *(uint32_t*)(&src2[i]) == *(uint32_t*)(&src2[i-dst_step]))
3666                                                                {
3667//                                                                      memcpy(tdst, tdst - dst_step, dst_step);
3668                                                                    *((uint32_t*)tdst) = *((uint32_t*)(tdst - dst_step));
3669                                                                }
3670                                                                else
3671                                                                {
3672#endif
3673                                                                        *((uint32_t*)tdst) = bgfx_blit_pixel_ARGB8888_ideal(&src1[i], &src2[i], alpha1, alpha2);
3674                                                                }
3675                                                        }
3676                            dst += p_dst->surface.pitch;
3677                                                        src1 += p_src1->surface.pitch;
3678                                                        src2 += p_src2->surface.pitch;
3679                                                }
3680                                        }
3681                                        else
3682                                        {
3683                        uint32_t p1, p2, p3;
3684                        p1 = p_dst->surface.pitch;
3685                        p2 = p_src1->surface.pitch;
3686                        p3 = p_src2->surface.pitch;
3687
3688                        if(operation == 0x33)
3689                        {
3690                            for (j = h; j--; ) 
3691                                {
3692                                                        tdst = dst;
3693                             
3694                                                        for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step) 
3695                                                        {
3696#ifdef COMPARE_PREVIOUS_PIXEL
3697                                                                if(i != 0 && *(uint32_t*)(&src1[i]) == *(uint32_t*)(&src1[i-dst_step]) && *(uint32_t*)(&src2[i]) == *(uint32_t*)(&src2[i-dst_step]))
3698                                                                {
3699    //                                                                  memcpy(tdst, tdst - dst_step, dst_step);
3700                                                                        *((uint32_t*)tdst) = *((uint32_t*)(tdst - dst_step));
3701                                                                }
3702                                                                else
3703#endif
3704                                    {
3705                                        #if 0
3706                                                                        *((uint32_t*)tdst) = bgfx_blit_pixel_ARGB8888(&src1[i], &src2[i], operation, alpha1, alpha2);
3707                                        #else
3708                                        *((uint32_t*)tdst) = bgfx_blit_pixel_ARGB8888_optimized(&src1[i], &src2[i]); 
3709                                        #endif     
3710                                    }
3711                                                        }/* for i */ 
3712#if NON_OPTIMIZED                           
3713                                dst += p_dst->surface.pitch;
3714                                src1 += p_src1->surface.pitch;
3715                                src2 += p_src2->surface.pitch;
3716#else
3717                                                        dst += p1;
3718                                                        src1 += p2;
3719                                                        src2 += p3;
3720#endif
3721                                                }/* for j */
3722                        }
3723                        else
3724                        {
3725                            /* operation != 0x33 */
3726                            for (j = h; j--; ) 
3727                                {
3728                                                        tdst = dst;
3729                             
3730                                                        for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step) 
3731                                                        {
3732#ifdef COMPARE_PREVIOUS_PIXEL
3733                                                                if(i != 0 && *(uint32_t*)(&src1[i]) == *(uint32_t*)(&src1[i-dst_step]) && *(uint32_t*)(&src2[i]) == *(uint32_t*)(&src2[i-dst_step]))
3734                                                                {
3735    //                                                                  memcpy(tdst, tdst - dst_step, dst_step);
3736                                                                        *((uint32_t*)tdst) = *((uint32_t*)(tdst - dst_step));
3737                                                                }
3738                                                                else
3739#endif
3740                                    {
3741                                        #if 1
3742                                                                        *((uint32_t*)tdst) = bgfx_blit_pixel_ARGB8888(&src1[i], &src2[i], operation, alpha1, alpha2);
3743                                        #else
3744                                        *((uint32_t*)tdst) = bgfx_blit_pixel_ARGB8888_optimized(&src1[i], &src2[i]); 
3745                                        #endif     
3746                                    }
3747                                                        }/* for i */ 
3748#if NON_OPTIMIZED                           
3749                                dst += p_dst->surface.pitch;
3750                                src1 += p_src1->surface.pitch;
3751                                src2 += p_src2->surface.pitch;
3752#else
3753                                                        dst += p1;
3754                                                        src1 += p2;
3755                                                        src2 += p3;
3756#endif
3757                                                } /* for j */                           
3758                        }/* if - else operation == 0x33 */
3759                                        }
3760                                        break;
3761                                case GRAPHICS_FMT_RGBA_888:
3762                                        if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1 && (operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2)
3763                                        {
3764                                                for (j = 0; j < h; ++j)
3765                                                {
3766                                                        tdst = dst;
3767                                                        for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step)
3768#ifdef COMPARE_PREVIOUS_PIXEL
3769                                                                if(i > 0 && *(uint32_t*)(&src1[i]) == *(uint32_t*)(&src1[i-dst_step]) && *(uint32_t*)(&src2[i]) == *(uint32_t*)(&src2[i-dst_step]))
3770//                                                              memcpy(tdst, tdst - dst_step, dst_step);
3771                                                                *((uint32_t*)tdst) = *((uint32_t*)(tdst - dst_step));
3772                                                                else
3773#endif
3774                                                                        *((uint32_t*)tdst) = bgfx_blit_pixel_RGBA8888_ideal(&src1[i], &src2[i], alpha1, alpha2);
3775                                                        dst += p_dst->surface.pitch;
3776                                                        src1 += p_src1->surface.pitch;
3777                                                        src2 += p_src2->surface.pitch;
3778                                                }
3779                                        }
3780                                        else
3781                                        {
3782                                                for (j = 0; j < h; ++j)
3783                                                {
3784                                                        tdst = dst;
3785                                                        for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step)
3786#ifdef COMPARE_PREVIOUS_PIXEL
3787                                                                if(i > 0 && *(uint32_t*)(&src1[i]) == *(uint32_t*)(&src1[i-dst_step]) && *(uint32_t*)(&src2[i]) == *(uint32_t*)(&src2[i-dst_step]))
3788//                                                              memcpy(tdst, tdst - dst_step, dst_step);
3789                                                                *((uint32_t*)tdst) = *((uint32_t*)(tdst - dst_step));
3790                                                                else
3791#endif
3792                                                                *((uint32_t*)tdst) = bgfx_blit_pixel_RGBA8888(&src1[i], &src2[i], operation, alpha1, alpha2);
3793                                                        dst += p_dst->surface.pitch;
3794                                                        src1 += p_src1->surface.pitch;
3795                                                        src2 += p_src2->surface.pitch;
3796                                                }
3797                                        }
3798                                        break;
3799                                case GRAPHICS_FMT_WRGB_1555:
3800                                        if(alpha2 != 0xff && alpha2 != 0 && (operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2)
3801                                        {
3802                                                SGL_DEBUG(("GRAPHICS_FMT_WRGB_1555 format only support 0 or 255 alpha output! "));
3803                                                return -1;
3804                                        }
3805                                        else
3806                                                alpha2 = (alpha2 == 0xff)? 0x8000: 0;
3807                                        if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1 && (operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2)
3808                                        {
3809                                                for (j = 0; j < h; ++j)
3810                                                {
3811                                                        tdst = dst;
3812                                                        for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step)
3813#ifdef COMPARE_PREVIOUS_PIXEL
3814                                                                if(i > 0 && *(uint16_t*)(&src1[i]) == *(uint16_t*)(&src1[i-dst_step]) && *(uint16_t*)(&src2[i]) == *(uint16_t*)(&src2[i-dst_step]))
3815//                                                                      memcpy(tdst, tdst - dst_step, dst_step);
3816                                                                        *((uint16_t*)tdst) = *((uint16_t*)(tdst - dst_step));
3817                                                                else
3818#endif
3819                                                                        *((uint16_t*)tdst) = bgfx_blit_pixel_WRGB1555_ideal(&src1[i], &src2[i], alpha1, alpha2) & 0xffff;
3820                                                        dst += p_dst->surface.pitch;
3821                                                        src1 += p_src1->surface.pitch;
3822                                                        src2 += p_src2->surface.pitch;
3823                                                }
3824                                        }
3825                                        else
3826                                        {
3827                                                for (j = 0; j < h; ++j)
3828                                                {
3829                                                        tdst = dst;
3830                                                        for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step)
3831#ifdef COMPARE_PREVIOUS_PIXEL
3832                                                                if(i > 0 && *(uint16_t*)(&src1[i]) == *(uint16_t*)(&src1[i-dst_step]) && *(uint16_t*)(&src2[i]) == *(uint16_t*)(&src2[i-dst_step]))
3833//                                                                      memcpy(tdst, tdst - dst_step, dst_step);
3834                                                                        *((uint16_t*)tdst) = *((uint16_t*)(tdst - dst_step));
3835                                                                else
3836#endif
3837                                                                        *((uint16_t*)tdst) = bgfx_blit_pixel_WRGB1555(&src1[i], &src2[i], operation, alpha1, alpha2) & 0xffff;
3838                                                        dst += p_dst->surface.pitch;
3839                                                        src1 += p_src1->surface.pitch;
3840                                                        src2 += p_src2->surface.pitch;
3841                                                }
3842                                        }
3843                                        break;
3844                                case GRAPHICS_FMT_RGBW_5551:
3845                                        if(alpha2 != 0xff && alpha2 != 0 && (operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2)
3846                                        {
3847                                                SGL_DEBUG(("GRAPHICS_FMT_RGBW_5551 format only support 0 or 255 alpha output! "));
3848                                                return -1;
3849                                        }                                               
3850                                        else
3851                                                alpha2 = (alpha2 == 0xff)? 1: 0;
3852                                        if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1 && (operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2)
3853                                        {
3854                                                for (j = 0; j < h; ++j)
3855                                                {
3856                                                        tdst = dst;
3857                                                        for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step)
3858#ifdef COMPARE_PREVIOUS_PIXEL
3859                                                                if(i > 0 && *(uint16_t*)(&src1[i]) == *(uint16_t*)(&src1[i-dst_step]) && *(uint16_t*)(&src2[i]) == *(uint16_t*)(&src2[i-dst_step]))
3860//                                                                      memcpy(tdst, tdst - dst_step, dst_step);
3861                                                                        *((uint16_t*)tdst) = *((uint16_t*)(tdst - dst_step));
3862                                                                else
3863#endif
3864                                                                        *((uint16_t*)tdst) = bgfx_blit_pixel_RGBW5551_ideal(&src1[i], &src2[i], alpha1, alpha2) & 0xffff;
3865                                                        dst += p_dst->surface.pitch;
3866                                                        src1 += p_src1->surface.pitch;
3867                                                        src2 += p_src2->surface.pitch;
3868                                                }
3869                                        }
3870                                        else
3871                                        {
3872                                                for (j = 0; j < h; ++j)
3873                                                {
3874                                                        tdst = dst;
3875                                                        for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step)
3876#ifdef COMPARE_PREVIOUS_PIXEL
3877                                                                if(i > 0 && *(uint16_t*)(&src1[i]) == *(uint16_t*)(&src1[i-dst_step]) && *(uint16_t*)(&src2[i]) == *(uint16_t*)(&src2[i-dst_step]))
3878//                                                                      memcpy(tdst, tdst - dst_step, dst_step);
3879                                                                        *((uint16_t*)tdst) = *((uint16_t*)(tdst - dst_step));
3880                                                                else
3881#endif
3882                                                                        *((uint16_t*)tdst) = bgfx_blit_pixel_RGBW5551(&src1[i], &src2[i], operation, alpha1, alpha2) & 0xffff;
3883                                                        dst += p_dst->surface.pitch;
3884                                                        src1 += p_src1->surface.pitch;
3885                                                        src2 += p_src2->surface.pitch;
3886                                                }
3887                                        }
3888                                        break;
3889                                case GRAPHICS_FMT_ARGB_4444:
3890                                        alpha2 = ((alpha2 >> 4) << 12);
3891                                        if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1 && (operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2)
3892                                        {
3893                                                for (j = 0; j < h; ++j)
3894                                                {
3895                                                        tdst = dst;
3896                                                        for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step)
3897#ifdef COMPARE_PREVIOUS_PIXEL
3898                                                        if(i > 0 && *(uint16_t*)(&src1[i]) == *(uint16_t*)(&src1[i-dst_step]) && *(uint16_t*)(&src2[i]) == *(uint16_t*)(&src2[i-dst_step]))
3899//                                                              memcpy(tdst, tdst - dst_step, dst_step);
3900                                                                *((uint16_t*)tdst) = *((uint16_t*)(tdst - dst_step));
3901                                                        else
3902#endif
3903                                                                *((uint16_t*)tdst) = bgfx_blit_pixel_ARGB4444_ideal(&src1[i], &src2[i], alpha1, alpha2) & 0xffff;
3904                                                        dst += p_dst->surface.pitch;
3905                                                        src1 += p_src1->surface.pitch;
3906                                                        src2 += p_src2->surface.pitch;
3907                                                }
3908                                        }
3909                                        else
3910                                        {
3911                                                for (j = 0; j < h; ++j)
3912                                                {
3913                                                        tdst = dst;
3914                                                        for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step)
3915#ifdef COMPARE_PREVIOUS_PIXEL
3916                                                        if(i > 0 && *(uint16_t*)(&src1[i]) == *(uint16_t*)(&src1[i-dst_step]) && *(uint16_t*)(&src2[i]) == *(uint16_t*)(&src2[i-dst_step]))
3917//                                                              memcpy(tdst, tdst - dst_step, dst_step);
3918                                                                *((uint16_t*)tdst) = *((uint16_t*)(tdst - dst_step));
3919                                                        else
3920#endif
3921                                                                *((uint16_t*)tdst) = bgfx_blit_pixel_ARGB4444(&src1[i], &src2[i], operation, alpha1, alpha2) & 0xffff;
3922                                                        dst += p_dst->surface.pitch;
3923                                                        src1 += p_src1->surface.pitch;
3924                                                        src2 += p_src2->surface.pitch;
3925                                                }
3926                                        }
3927                                        break;
3928                                case GRAPHICS_FMT_RGBA_4444:
3929                                        alpha2 = (alpha2 >> 4);
3930                                        if((operation & 0x0f) == SURFBLIT_BLEND_WITH_SPEC_ALPHA1 && (operation & 0xf0) == SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2)
3931                                        {
3932                                                for (j = 0; j < h; ++j)
3933                                                {
3934                                                        tdst = dst;
3935                                                        for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step)
3936#ifdef COMPARE_PREVIOUS_PIXEL
3937                                                        if(i > 0 && *(uint16_t*)(&src1[i]) == *(uint16_t*)(&src1[i-dst_step]) && *(uint16_t*)(&src2[i]) == *(uint16_t*)(&src2[i-dst_step]))
3938//                                                              memcpy(tdst, tdst - dst_step, dst_step);
3939                                                                *((uint16_t*)tdst) = *((uint16_t*)(tdst - dst_step));
3940                                                        else
3941#endif
3942                                                                *((uint16_t*)tdst) = bgfx_blit_pixel_RGBA4444_ideal(&src1[i], &src2[i], alpha1, alpha2) & 0xffff;
3943                                                        dst += p_dst->surface.pitch;
3944                                                        src1 += p_src1->surface.pitch;
3945                                                        src2 += p_src2->surface.pitch;
3946                                                }
3947                                        }
3948                                        else
3949                                        {
3950                                                for (j = 0; j < h; ++j)
3951                                                {
3952                                                        tdst = dst;
3953                                                        for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step)
3954#ifdef COMPARE_PREVIOUS_PIXEL
3955                                                        if(i > 0 && *(uint16_t*)(&src1[i]) == *(uint16_t*)(&src1[i-dst_step]) && *(uint16_t*)(&src2[i]) == *(uint16_t*)(&src2[i-dst_step]))
3956//                                                              memcpy(tdst, tdst - dst_step, dst_step);
3957                                                                *((uint16_t*)tdst) = *((uint16_t*)(tdst - dst_step));
3958                                                        else
3959#endif
3960                                                                *((uint16_t*)tdst) = bgfx_blit_pixel_RGBA4444(&src1[i], &src2[i], operation, alpha1, alpha2) & 0xffff;
3961                                                        dst += p_dst->surface.pitch;
3962                                                        src1 += p_src1->surface.pitch;
3963                                                        src2 += p_src2->surface.pitch;
3964                                                }
3965                                        }
3966                                        break;
3967                                case GRAPHICS_FMT_RGB_565:
3968                                        if(alpha2 != 0xff || (operation & 0xf0) != SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2 || (operation & 0x0f) != SURFBLIT_BLEND_WITH_SPEC_ALPHA1)
3969                                        {
3970                                                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! "));
3971                                                return -1;
3972                                        }                                               
3973                                        for (j = 0; j < h; ++j)
3974                                        {
3975                                                tdst = dst;
3976                                                for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step)
3977#ifdef COMPARE_PREVIOUS_PIXEL
3978                                                        if(i > 0 && *(uint16_t*)(&src1[i]) == *(uint16_t*)(&src1[i-dst_step]) && *(uint16_t*)(&src2[i]) == *(uint16_t*)(&src2[i-dst_step]))
3979//                                                              memcpy(tdst, tdst - dst_step, dst_step);
3980                                                                *((uint16_t*)tdst) = *((uint16_t*)(tdst - dst_step));
3981                                                        else
3982#endif
3983                                                                *((uint16_t*)tdst) = bgfx_blit_pixel_RGB565_ideal(&src1[i], &src2[i], alpha1, alpha2) & 0xffff;
3984                                                dst += p_dst->surface.pitch;
3985                                                src1 += p_src1->surface.pitch;
3986                                                src2 += p_src2->surface.pitch;
3987                                        }
3988                                        break;
3989                                default:
3990                                        SGL_DEBUG(("Not supported formats for multi surface alpha blending."));
3991                                        return -1;
3992                                }
3993        }
3994        else
3995#endif
3996        {
3997                SGL_DEBUG(("multi surface alpha blending only support RGB surfaces."));
3998                return -1;
3999        }
4000        bgfx_cacheflush(p_dst->surface.buf,p_dst->surface.pitch * p_dst->surface.height);
4001        return 0;
4002}
4003
4004/****************************************************************
4005*
4006* INPUTS:       p_src - source palette pointer
4007* OUTPUTS:      none
4008* RETURNS:      none
4009* FUNCTION: Map palette from RGB to YUV
4010* Raymond, 20090211
4011****************************************************************/
4012void bgfx_mapping_palette(unsigned int *p_src, unsigned int size)
4013{
4014unsigned int i;
4015unsigned int a, r, g, b, y, u, v;
4016        SGL_TRACE(("----------palette size =%d---------- ", size));
4017        for(i=0; i<size; i++){
4018                SGL_TRACE(("----------ARGB ui_comp.ui_palette[%d]=%x---------- ", i, *(p_src + i)));
4019                a = (*(p_src + i) >> 24) & 0xFF;
4020                r = (*(p_src + i) >> 16) & 0xFF;
4021                g = (*(p_src + i) >> 8) & 0xFF;
4022                b = (*(p_src + i) >> 0) & 0xFF;
4023#if 1
4024                bgfx_csc_BT_601_RGB_2_YCbCr_macro(y,u,v,r,g,b);
4025#else
4026                y = (0.257 * r) + (0.504 * g) + (0.098 * b) + 16;
4027                v =  (0.439 * r) - (0.368 * g) - (0.071 * b) + 128;
4028                u = -(0.148 * r) - (0.291 * g) + (0.439 * b) + 128;
4029                *(p_src + i) = (a << 24) | (y << 16) | (u << 8) | v;
4030#endif
4031                SGL_TRACE(("----------AYUV ui_comp.ui_palette[%d]=%x---------- ", i, *(p_src + i)));
4032        }
4033}
4034#endif
4035
4036/****************************************************************
4037 * INPUTS:      p_src,p_dst - source and destination surface structures
4038 *                      sx,sy - source coordinates
4039 *                      dx,dy - destination coordinates
4040 *                      sw,sh - width and height of region
4041 * OUTPUTS:     none
4042 * RETURNS:     non-zero on error
4043 * FUNCTION:    anti-flutter filter a region of one surface to another
4044 *
4045 ****************************************************************/
4046inline void bgfx_AFF_ARGB_888(uint32_t * q,uint32_t * q1, uint32_t *q2, uint32_t * dst, uint8_t coef)
4047{
4048        register uint32_t a,r,g,b; 
4049        register uint32_t r1,g1,b1;
4050        register uint32_t r2,g2,b2;
4051        register uint32_t q_val, q1_val, q2_val;       
4052        register uint32_t  mask_3rd_byte = 0x00ff0000;
4053
4054    BSTD_UNUSED(coef);
4055        q_val = *q;
4056        a = (q_val&0xff000000);
4057        r = (q_val&mask_3rd_byte);
4058        g = (q_val&0x0000ff00);
4059        b = (q_val&0x000000ff);
4060
4061        q1_val = *q1;
4062        r1 = (q1_val&mask_3rd_byte);
4063        g1 = (q1_val&0x0000ff00);
4064        b1 = (q1_val&0x000000ff);
4065
4066        q2_val = *q2;
4067        r2 = (q2_val&mask_3rd_byte);
4068        g2 = (q2_val&0x0000ff00);
4069        b2 = (q2_val&0x000000ff);
4070
4071        *dst = a | (((r1 + (r<<1) + r2)>>2)&mask_3rd_byte) | (((g1 + (g<<1) + g2)>>2)&0x0000ff00) |(((b1 + (b<<1) + b2)>>2)&0x000000ff);
4072       
4073}
4074inline void bgfx_AFF_RGBA_888(uint32_t * q,uint32_t * q1, uint32_t *q2, uint32_t * dst, uint8_t coef)
4075{
4076        register uint32_t a,r,g,b; 
4077        register uint32_t r1,g1,b1;
4078        register uint32_t r2,g2,b2;
4079        register uint32_t q_val, q1_val, q2_val;
4080        register uint32_t  mask_3rd_byte = 0x00ff0000;
4081        register uint32_t  mask_4rd_byte = 0xff000000;
4082
4083    BSTD_UNUSED(coef);
4084   
4085        q_val = *q; 
4086        a = (q_val&0x000000ff);
4087        r = (q_val&mask_4rd_byte);
4088        g = (q_val&mask_3rd_byte);
4089        b = (q_val&0x0000ff00);
4090
4091        q1_val = *q1;
4092        r1 = (q1_val&mask_4rd_byte);
4093        g1 = (q1_val&mask_3rd_byte);
4094        b1 = (q1_val&0x0000ff00);
4095
4096        q2_val = *q2;
4097        r2 = (q2_val&mask_4rd_byte);
4098        g2 = (q2_val&mask_3rd_byte);
4099        b2 = (q2_val&0x0000ff00);
4100       
4101       
4102        *dst = (((r1 + (r<<1) + r2)>>2)&mask_4rd_byte) | (((g1 + (g<<1) + g2)>>2)&mask_3rd_byte) |(((b1 + (b<<1) + b2)>>2)&0x0000ff00) | a;
4103
4104}
4105
4106inline void bgfx_AFF_RGB_565(uint16_t *p, uint16_t * p1, uint16_t * p2, uint16_t * dst, uint8_t coef)
4107{
4108        register uint32_t r,g,b; 
4109        register uint32_t r1,g1,b1;
4110        register uint32_t r2,g2,b2;
4111        register uint32_t p_val, p1_val, p2_val;
4112
4113    BSTD_UNUSED(coef);
4114   
4115        p_val = (uint32_t)*p;
4116        r = (p_val&0xf800);
4117        g = (p_val&0x07e0);
4118        b = (p_val&0x001f);
4119
4120        p1_val = (uint32_t)*p1;
4121        r1 = (p1_val&0xf800);
4122        g1 = (p1_val&0x07e0);
4123        b1 = (p1_val&0x001f);
4124
4125        p2_val = (uint32_t)*p2;
4126        r2 = (p2_val&0xf800);
4127        g2 = (p2_val&0x07e0);
4128        b2 = (p2_val&0x001f);
4129       
4130       
4131        *dst = (((r1 + (r<<1) + r2)>>2)&0xf800) | (((g1 + (g<<1) + g2)>>2)&0x07e0) | (((b1 + (b<<1) + b2)>>2)&0x001f);
4132
4133}
4134
4135inline void bgfx_AFF_WRGB_1555(uint16_t *p, uint16_t * p1, uint16_t * p2, uint16_t * dst, uint8_t coef)
4136{
4137        register uint32_t a,r,g,b; 
4138        register uint32_t r1,g1,b1;
4139        register uint32_t r2,g2,b2;
4140        register uint32_t p_val, p1_val, p2_val;
4141
4142    BSTD_UNUSED(coef);
4143   
4144        p_val = (uint32_t)*p;
4145        a = (p_val&0x8000);
4146        r = (p_val&0x7c00);
4147        g = (p_val&0x03e0);
4148        b = (p_val&0x001f);
4149
4150        p1_val = (uint32_t)*p1;
4151        r1 = (p1_val&0x7c00);
4152        g1 = (p1_val&0x03e0);
4153        b1 = (p1_val&0x001f);
4154
4155        p2_val = (uint32_t)*p2;
4156        r2 = (p2_val&0x7c00);
4157        g2 = (p2_val&0x03e0);
4158        b2 = (p2_val&0x001f);
4159
4160
4161        *dst = a | (((r1 + (r<<1) + r2)>>2)&0x7c00) | (((g1 + (g<<1) + g2)>>2)&0x03e0) | (((b1 + (b<<1) + b2)>>2)&0x001f);
4162
4163}
4164
4165inline void bgfx_AFF_RGBW_5551(uint16_t *p, uint16_t * p1, uint16_t * p2, uint16_t * dst, uint8_t coef)
4166{
4167        register uint32_t a,r,g,b; 
4168        register uint32_t r1,g1,b1;
4169        register uint32_t r2,g2,b2;
4170        register uint32_t p_val, p1_val, p2_val;
4171
4172    BSTD_UNUSED(coef);
4173   
4174        p_val = (uint32_t)*p;
4175        a = (p_val&0x0001);
4176        r = (p_val&0xf800);
4177        g = (p_val&0x07c0);
4178        b = (p_val&0x003e);
4179
4180        p1_val = (uint32_t)*p1;
4181        r1 = (p1_val&0xf800);
4182        g1 = (p1_val&0x07c0);
4183        b1 = (p1_val&0x003e);
4184
4185        p2_val = (uint32_t)*p2;
4186        r2 = (p2_val&0xf800);
4187        g2 = (p2_val&0x07c0);
4188        b2 = (p2_val&0x003e);
4189
4190
4191        *dst = (((r1 + (r<<1) + r2)>>2)&0xf800) | (((g1 + (g<<1) + g2)>>2)&0x07c0) | (((b1 + (b<<1) + b2)>>2)&0x003e) | a;
4192}
4193
4194inline void bgfx_AFF_ARGB_4444(uint16_t *p, uint16_t * p1, uint16_t * p2, uint16_t * dst, uint8_t coef)
4195{
4196        register uint32_t a,r,g,b; 
4197        register uint32_t r1,g1,b1;
4198        register uint32_t r2,g2,b2; 
4199        register uint32_t p_val, p1_val, p2_val;
4200
4201    BSTD_UNUSED(coef);
4202   
4203        p_val = (uint32_t)*p;
4204        a = (p_val&0xf000);
4205        r = (p_val&0x0f00);
4206        g = (p_val&0x00f0);
4207        b = (p_val&0x000f);
4208
4209        p1_val = (uint32_t)*p1;
4210        r1 = (p1_val&0x0f00);
4211        g1 = (p1_val&0x00f0);
4212        b1 = (p1_val&0x000f);
4213
4214        p2_val = (uint32_t)*p2;
4215        r2 = ((p2_val&0x0f00) >> 8);
4216        g2 = ((p2_val&0x00f0) >> 4);
4217        b2 = (p2_val&0x000f);
4218
4219       
4220        *dst =  a | (((r1 + (r<<1) + r2)>>2)&0x0f00) | (((g1 + (g<<1) + g2)>>2)&0x00f0) | (((b1 + (b<<1) + b2)>>2)&0x000f);
4221}       
4222
4223inline void bgfx_AFF_RGBA_4444(uint16_t *p, uint16_t * p1, uint16_t * p2, uint16_t * dst, uint8_t coef)
4224{
4225        register uint32_t a,r,g,b; 
4226        register uint32_t r1,g1,b1;
4227        register uint32_t r2,g2,b2; 
4228        register uint32_t p_val, p1_val, p2_val;
4229
4230    BSTD_UNUSED(coef);
4231   
4232        p_val = (uint32_t)*p;
4233        a = (p_val&0x000f);
4234        r = (p_val&0xf000);
4235        g = (p_val&0x0f00);
4236        b = (p_val&0x00f0);
4237
4238        p1_val = (uint32_t)*p1;
4239        r1 = (p1_val&0xf000);
4240        g1 = (p1_val&0x0f00);
4241        b1 = (p1_val&0x00f0);
4242
4243        p2_val = (uint32_t)*p2;
4244        r2 = (p2_val&0xf000);
4245        g2 = (p2_val&0x0f00);
4246        b2 = (p2_val&0x00f0);
4247
4248
4249        *dst = (((r1 + (r<<1) + r2)>>2)&0xf000) | (((g1 + (g<<1) + g2)>>2)&0x0f00) | (((b1 + (b<<1) + b2)>>2)&0x00f0) | a;
4250}
4251
4252void bgfx_soft_AFF_V(uint8_t * dst, uint8_t * src, uint16_t width, uint16_t height, uint16_t pitch, int format, uint8_t vcoef)
4253{
4254        register int i,j,k;
4255        register uint16_t *p,*p1,*p2;
4256        register uint8_t Bpp;
4257        register uint32_t *q,*q1,*q2;
4258        register uint16_t *last16=NULL;
4259        register uint32_t *last32=NULL;
4260        uint16_t tmp16; 
4261        uint32_t tmp32;
4262
4263        //printf("\n%s: dst=%p,src=%p,(%d,%d),pitch=%d\n",__func__,dst,src,width,height,pitch);
4264       
4265        switch (format)
4266        {
4267                case GRAPHICS_FMT_ARGB_888:
4268                case GRAPHICS_FMT_RGBA_888:
4269                        Bpp = 4;
4270                        last32 = (uint32_t *)SGL_MALLOC(width*4);
4271                        if(last32 == NULL)
4272                        {
4273                                printf("%s: SGL_MALLOC %d error\n",__func__,width*4);
4274                                return;
4275                        }
4276                        break;
4277                case GRAPHICS_FMT_RGB_565:
4278                case GRAPHICS_FMT_WRGB_1555:
4279                case GRAPHICS_FMT_RGBW_5551:
4280                case GRAPHICS_FMT_ARGB_4444:
4281                case GRAPHICS_FMT_RGBA_4444:
4282                        Bpp = 2;
4283                        last16 = (uint16_t *)SGL_MALLOC(width*2);
4284                        if(last16 == NULL)
4285                        {
4286                                printf("%s: SGL_MALLOC %d error\n",__func__,width*2);
4287                                return;
4288                        }
4289                        break;
4290                default:
4291                        SGL_DEBUG(("%s: unsupported foramt %d", __func__, format));
4292                        return;
4293        }
4294
4295        /*no filtered on the first and last line, reserve the original value */ 
4296        /*anti-flutter filter*/
4297        switch (format)
4298        {
4299                case GRAPHICS_FMT_ARGB_888:
4300                        /*compute the second line and save temporarily*/
4301                        if(height > 2)
4302                        {
4303                                k = pitch;
4304                                for(j=0; j<width; j++,k+=Bpp) 
4305                                {
4306                                        q = (uint32_t *)(((uint32_t)src)+k);
4307                                        q1 = (uint32_t *)(((uint32_t)src)+k-pitch);
4308                                        q2 = (uint32_t *)(((uint32_t)src)+k+pitch);
4309
4310                                        bgfx_AFF_ARGB_888(q,q1,q2,last32+j,vcoef);                             
4311                                }
4312                        }       
4313                       
4314                        for(i=2; i<height-1; i++)/*per row, to use cache*/
4315                        {
4316                                k = i*pitch;
4317                                for(j=0; j<width; j++,k+=Bpp) 
4318                                {
4319                                        q = (uint32_t *)(((uint32_t)src)+k);
4320                                        q1 = (uint32_t *)(((uint32_t)src)+k-pitch);
4321                                        q2 = (uint32_t *)(((uint32_t)src)+k+pitch);
4322
4323                                        bgfx_AFF_ARGB_888(q,q1,q2,&tmp32,vcoef);
4324                                        q1 = (uint32_t *)(((uint32_t)dst)+k-pitch);
4325                                        *q1 = last32[j];
4326                                        last32[j] = tmp32;                                     
4327                                }
4328                        }
4329                        break;
4330                case GRAPHICS_FMT_RGBA_888:
4331                        /*compute the second line and save temporarily*/
4332                        if(height > 2)
4333                        {
4334                                k = pitch;
4335                                for(j=0; j<width; j++,k+=Bpp) 
4336                                {
4337                                        q = (uint32_t *)(((uint32_t)src)+k);
4338                                        q1 = (uint32_t *)(((uint32_t)src)+k-pitch);
4339                                        q2 = (uint32_t *)(((uint32_t)src)+k+pitch);
4340
4341                                        bgfx_AFF_RGBA_888(q,q1,q2,last32+j,vcoef);                             
4342                                }
4343                        }       
4344                        for(i=2; i<height-1; i++)/*per row, to use cache*/
4345                        {
4346                                k = i*pitch;
4347                                for(j=0; j<width; j++,k+=Bpp) 
4348                                {
4349                                        q = (uint32_t *)(((uint32_t)src)+k);
4350                                        q1 = (uint32_t *)(((uint32_t)src)+k-pitch);
4351                                        q2 = (uint32_t *)(((uint32_t)src)+k+pitch);
4352
4353                                        bgfx_AFF_RGBA_888(q,q1,q2,&tmp32,vcoef);
4354                                        q1 = (uint32_t *)(((uint32_t)dst)+k-pitch);
4355                                        *q1 = last32[j];
4356                                        last32[j] = tmp32;
4357                                }
4358                        }
4359                       
4360                        break;
4361                case GRAPHICS_FMT_RGB_565:
4362                        /*compute the second line and save temporarily*/
4363                        if(height > 2)
4364                        {
4365                                k = pitch;
4366                                for(j=0; j<width; j++,k+=Bpp) 
4367                                {
4368                                        p = (uint16_t *)(((uint32_t)src)+k);
4369                                        p1 = (uint16_t *)(((uint32_t)src)+k-pitch);
4370                                        p2 = (uint16_t *)(((uint32_t)src)+k+pitch);
4371                                       
4372                                        bgfx_AFF_RGB_565(p,p1,p2,last16+j,vcoef);                                       
4373                                }
4374                        }       
4375                        for(i=2; i<height-1; i++)/*per row, to use cache*/
4376                        {
4377                                k = i*pitch;
4378                                for(j=0; j<width; j++,k+=Bpp) 
4379                                {
4380                                        p = (uint16_t *)(((uint32_t)src)+k);
4381                                        p1 = (uint16_t *)(((uint32_t)src)+k-pitch);
4382                                        p2 = (uint16_t *)(((uint32_t)src)+k+pitch);
4383                                       
4384                                        bgfx_AFF_RGB_565(p,p1,p2,&tmp16,vcoef);
4385                                        p1 = (uint16_t *)(((uint32_t)dst)+k-pitch);
4386                                        *p1 = last16[j];
4387                                        last16[j] = tmp16;
4388                                }
4389                        }
4390                        break;
4391                case GRAPHICS_FMT_WRGB_1555:
4392                        /*compute the second line and save temporarily*/
4393                        if(height > 2)
4394                        {
4395                                k = pitch;
4396                                for(j=0; j<width; j++,k+=Bpp) /*to save only one filtered value, filtered per column*/
4397                                {
4398                                        p = (uint16_t *)((uint32_t)src+k);
4399                                        p1 = (uint16_t *)((uint32_t)src+k-pitch);
4400                                        p2 = (uint16_t *)((uint32_t)src+k+pitch);
4401
4402                                        bgfx_AFF_WRGB_1555(p,p1,p2,last16+j,vcoef);                                     
4403                                }
4404                        }
4405                        for(i=2; i<height-1; i++)/*per row, to use cache*/
4406                        {
4407                                k = i*pitch;
4408                                for(j=0; j<width; j++,k+=Bpp) /*to save only one filtered value, filtered per column*/
4409                                {
4410                                        p = (uint16_t *)((uint32_t)src+k);
4411                                        p1 = (uint16_t *)((uint32_t)src+k-pitch);
4412                                        p2 = (uint16_t *)((uint32_t)src+k+pitch);
4413
4414                                        bgfx_AFF_WRGB_1555(p,p1,p2,&tmp16,vcoef);
4415                                        p1 = (uint16_t *)(((uint32_t)dst)+k-pitch);
4416                                        *p1 = last16[j];
4417                                        last16[j] = tmp16;
4418                                }
4419                        }
4420                        break;
4421                case GRAPHICS_FMT_RGBW_5551:
4422                        /*compute the second line and save temporarily*/
4423                        if(height > 2)
4424                        {
4425                                k = pitch;
4426                                for(j=0; j<width; j++,k+=Bpp) /*to save only one filtered value, filtered per column*/
4427                                {
4428                                        p = (uint16_t *)((uint32_t)src+k);
4429                                        p1 = (uint16_t *)((uint32_t)src+k-pitch);
4430                                        p2 = (uint16_t *)((uint32_t)src+k+pitch);                                       
4431
4432                                        bgfx_AFF_RGBW_5551(p,p1,p2,last16+j,vcoef);                                     
4433                                }
4434                        }
4435                        for(i=2; i<height-1; i++)/*per row, to use cache*/
4436                        {
4437                                k = i*pitch;
4438                                for(j=0; j<width; j++,k+=Bpp) /*to save only one filtered value, filtered per column*/
4439                                {
4440                                        p = (uint16_t *)((uint32_t)src+k);
4441                                        p1 = (uint16_t *)((uint32_t)src+k-pitch);
4442                                        p2 = (uint16_t *)((uint32_t)src+k+pitch);                                       
4443
4444                                        bgfx_AFF_RGBW_5551(p,p1,p2,&tmp16,vcoef);
4445                                        p1 = (uint16_t *)(((uint32_t)dst)+k-pitch);
4446                                        *p1 = last16[j];
4447                                        last16[j] = tmp16;
4448                                }
4449                        }
4450                       
4451                        break;
4452                case GRAPHICS_FMT_ARGB_4444:
4453                        /*compute the second line and save temporarily*/
4454                        if(height > 2)
4455                        {
4456                                k = pitch;
4457                                for(j=0; j<width; j++,k+=Bpp) /*to save only one filtered value, filtered per column*/
4458                                {
4459                                        p = (uint16_t *)((uint32_t)src+k);
4460                                        p1 = (uint16_t *)((uint32_t)src+k-pitch);
4461                                        p2 = (uint16_t *)((uint32_t)src+k+pitch);                                       
4462
4463                                        bgfx_AFF_ARGB_4444(p,p1,p2,last16+j,vcoef);
4464                                }
4465                        }
4466                        for(i=2; i<height-1; i++)/*per row, to use cache*/
4467                        {
4468                                k = i*pitch;
4469                                for(j=0; j<width; j++,k+=Bpp) /*to save only one filtered value, filtered per column*/
4470                                {
4471                                        p = (uint16_t *)((uint32_t)src+k);
4472                                        p1 = (uint16_t *)((uint32_t)src+k-pitch);
4473                                        p2 = (uint16_t *)((uint32_t)src+k+pitch);                                       
4474
4475                                        bgfx_AFF_ARGB_4444(p,p1,p2,&tmp16,vcoef);
4476                                        p1 = (uint16_t *)(((uint32_t)dst)+k-pitch);
4477                                        *p1 = last16[j];
4478                                        last16[j] = tmp16;
4479                                }
4480                        }
4481                       
4482                        break;
4483                case GRAPHICS_FMT_RGBA_4444:
4484                        /*compute the second line and save temporarily*/
4485                        if(height > 2)
4486                        {
4487                                k = pitch;
4488                                for(j=0; j<width; j++,k+=Bpp) /*to save only one filtered value, filtered per column*/
4489                                {
4490                                        p = (uint16_t *)((uint32_t)src+k);
4491                                        p1 = (uint16_t *)((uint32_t)src+k-pitch);
4492                                        p2 = (uint16_t *)((uint32_t)src+k+pitch);                                       
4493
4494                                        bgfx_AFF_RGBA_4444(p,p1,p2,last16+j,vcoef);                             
4495                                }
4496                        }
4497                        for(i=2; i<height-1; i++)/*per row, to use cache*/
4498                        {
4499                                k = i*pitch;
4500                                for(j=0; j<width; j++,k+=Bpp) /*to save only one filtered value, filtered per column*/
4501                                {
4502                                        p = (uint16_t *)((uint32_t)src+k);
4503                                        p1 = (uint16_t *)((uint32_t)src+k-pitch);
4504                                        p2 = (uint16_t *)((uint32_t)src+k+pitch);                                       
4505
4506                                        bgfx_AFF_RGBA_4444(p,p1,p2,&tmp16,vcoef);
4507                                        p1 = (uint16_t *)(((uint32_t)dst)+k-pitch);
4508                                        *p1 = last16[j];
4509                                        last16[j] = tmp16;
4510                                }
4511                        }
4512                       
4513                        break;
4514        }
4515
4516        /*save the last second line*/
4517        if(last32 != NULL)
4518        {
4519                if(height > 2)
4520                {
4521                        k = (height-2)*pitch;
4522                        memcpy(dst+k, last32,width*4); 
4523                }       
4524                SGL_FREE(last32);
4525        }
4526
4527        if(last16 != NULL)
4528        {
4529                if(height > 2)
4530                {
4531                        k = (height-2)*pitch;
4532                        memcpy(dst+k, last16,width*2); 
4533                }       
4534                SGL_FREE(last16);
4535        }
4536       
4537}
4538
4539#ifdef SW_ANTI_FLUTTER_FILTER_HORIZONTAL
4540static 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)
4541{
4542        int i,j,k,l;
4543        uint16_t *p,*p1,*p2;
4544        uint16_t last16=0;
4545        uint32_t *q, *q1, *q2;
4546        uint32_t last32=0;
4547        uint32_t tmp32;
4548        uint16_t tmp16;
4549        uint8_t Bpp;
4550
4551        printf("\n%s: dst=%p,src=%p,(%d,%d),pitch=%d\n",__func__,dst,src,width,height,pitch);
4552
4553       
4554        switch (format)
4555        {
4556                case GRAPHICS_FMT_ARGB_888:
4557                case GRAPHICS_FMT_RGBA_888:
4558                        Bpp = 4;
4559                        break;
4560                case GRAPHICS_FMT_RGB_565:
4561                case GRAPHICS_FMT_WRGB_1555:
4562                case GRAPHICS_FMT_RGBW_5551:
4563                case GRAPHICS_FMT_ARGB_4444:
4564                case GRAPHICS_FMT_RGBA_4444:
4565                        Bpp = 2;
4566                        break;
4567                default:
4568                        SGL_DEBUG(("%s: unsupported foramt %d", __func__, format));
4569                        return;
4570        }
4571
4572        /*no filtered on the first and last column, reserve the original value */       
4573        /*anti-flutter, filter*/
4574        switch (format)
4575        {
4576                case GRAPHICS_FMT_ARGB_888:
4577                        for(i=0; i<height; i++)
4578                        {
4579                                /*no filtered on first column*/ 
4580                                last32 = *((uint32_t *)(((uint32_t)dst)+i*pitch));
4581                                k = i*pitch;                           
4582                                for(j=1; j<width-1; j++)
4583                                {
4584                                        k = k + Bpp;
4585
4586                                        q = (uint32_t *)(((uint32_t)src)+k);
4587                                        q1 = (uint32_t *)(((uint32_t)src)+k-4);
4588                                        q2 = (uint32_t *)(((uint32_t)src)+k+4);
4589                                       
4590                                        bgfx_AFF_ARGB_888(q,q1,q2,&tmp32,hcoef);
4591                                        q1 = (uint32_t *)(((uint32_t)dst)+k-4);/*update last pixel*/
4592                                        *q1=last32;
4593                                        last32 = tmp32;
4594                                }
4595                                q1 = (uint32_t *)(((uint32_t)dst)+k);/*update last pixel*/
4596                                *q1=last32;
4597                               
4598                        }
4599                        break;
4600                case GRAPHICS_FMT_RGBA_888:
4601                        for(i=0; i<height; i++)
4602                        {
4603                                /*no filtered on first column*/ 
4604                                last32 = *((uint32_t *)(((uint32_t)dst)+i*pitch));
4605                                k = i*pitch;                           
4606                                for(j=1; j<width-1; j++)
4607                                {
4608                                        k = k + Bpp;
4609
4610                                        q = (uint32_t *)(((uint32_t)src)+k);
4611                                        q1 = (uint32_t *)(((uint32_t)src)+k-4);
4612                                        q2 = (uint32_t*)(((uint32_t)src)+k+4);
4613                                       
4614                                        bgfx_AFF_RGBA_888(q,q1,q2,&tmp32,hcoef);
4615                                        q1 = (uint32_t *)(((uint32_t)dst)+k-4);/*update last pixel*/
4616                                        *q1=last32;
4617                                        last32 = tmp32;
4618                                }
4619                                q1 = (uint32_t *)(((uint32_t)dst)+k);/*update last pixel*/
4620                                *q1=last32;
4621                        }                       
4622                        break;
4623                case GRAPHICS_FMT_RGB_565:
4624                        for(i=0; i<height; i++)
4625                        {
4626                                /*no filtered on first column*/ 
4627                                last16 = *((uint16_t *)(((uint32_t)dst)+i*pitch));
4628                                k = i*pitch;                           
4629                                for(j=1; j<width-1; j++)
4630                                {
4631                                        k = k + Bpp;
4632
4633                                        p = (uint16_t *)(((uint32_t)src)+k);
4634                                        p1 = (uint16_t *)(((uint32_t)src)+k-2);
4635                                        p2 = (uint16_t *)(((uint32_t)src)+k+2);
4636                                       
4637                                        bgfx_AFF_RGB_565(p,p1,p2,&tmp16,hcoef);
4638                                        p1 = (uint16_t *)(((uint32_t)dst)+k-2);/*update last pixel*/
4639                                        *p1=last16;
4640                                        last16 = tmp16;
4641                                }
4642                                p1 = (uint16_t *)(((uint32_t)dst)+k);/*update last pixel*/
4643                                *p1=last16;
4644                        }                       
4645                        break;
4646                case GRAPHICS_FMT_WRGB_1555:
4647                        for(i=0; i<height; i++)
4648                        {
4649                                /*no filtered on first column*/ 
4650                                last16 = *((uint16_t *)(((uint32_t)dst)+i*pitch));
4651                                k = i*pitch;                           
4652                                for(j=1; j<width-1; j++)
4653                                {
4654                                        k = k + Bpp;
4655
4656                                        p = (uint16_t *)(((uint32_t)src)+k);
4657                                        p1 = (uint16_t *)(((uint32_t)src)+k-2);
4658                                        p2 = (uint16_t *)(((uint32_t)src)+k+2);
4659                                       
4660                                        bgfx_AFF_WRGB_1555(p,p1,p2,&tmp16,hcoef);
4661                                        p1 = (uint16_t *)(((uint32_t)dst)+k-2);/*update last pixel*/
4662                                        *p1=last16;
4663                                        last16 = tmp16;
4664                                }
4665                                p1 = (uint16_t *)(((uint32_t)dst)+k);/*update last pixel*/
4666                                *p1=last16;
4667                        }
4668                        break;
4669                case GRAPHICS_FMT_RGBW_5551:
4670                        for(i=0; i<height; i++)
4671                        {
4672                                /*no filtered on first column*/ 
4673                                last16 = *((uint16_t *)(((uint32_t)dst)+i*pitch));
4674                                k = i*pitch;                           
4675                                for(j=1; j<width-1; j++)
4676                                {
4677                                        k = k + Bpp;
4678
4679                                        p = (uint16_t *)(((uint32_t)src)+k);
4680                                        p1 = (uint16_t *)(((uint32_t)src)+k-2);
4681                                        p2 = (uint16_t *)(((uint32_t)src)+k+2);
4682                                       
4683                                        bgfx_AFF_RGBW_5551(p,p1,p2,&tmp16,hcoef);
4684                                        p1 = (uint16_t *)(((uint32_t)dst)+k-2);/*update last pixel*/
4685                                        *p1=last16;
4686                                        last16 = tmp16;                                         
4687                                }
4688                                p1 = (uint16_t *)(((uint32_t)dst)+k);/*update last pixel*/
4689                                *p1=last16;
4690                        }
4691                        break;
4692                case GRAPHICS_FMT_ARGB_4444:
4693                        for(i=0; i<height; i++)
4694                        {
4695                                /*no filtered on first column*/ 
4696                                last16 = *((uint16_t *)(((uint32_t)dst)+i*pitch));
4697                                k = i*pitch;                           
4698                                for(j=1; j<width-1; j++)
4699                                {
4700                                        k = k + Bpp;
4701
4702                                        p = (uint16_t *)(((uint32_t)src)+k);
4703                                        p1 = (uint16_t *)(((uint32_t)src)+k-2);
4704                                        p2 = (uint16_t *)(((uint32_t)src)+k+2);
4705                                       
4706                                        bgfx_AFF_ARGB_4444(p,p1,p2,&tmp16,hcoef);
4707                                        p1 = (uint16_t *)(((uint32_t)dst)+k-2);/*update last pixel*/
4708                                        *p1=last16;
4709                                        last16 = tmp16;
4710                                }
4711                                p1 = (uint16_t *)(((uint32_t)dst)+k);/*update last pixel*/
4712                                *p1=last16;
4713                        }
4714                        break;
4715                case GRAPHICS_FMT_RGBA_4444:
4716                        for(i=0; i<height; i++)
4717                        {
4718                                /*no filtered on first column*/ 
4719                                last16 = *((uint16_t *)(((uint32_t)dst)+i*pitch));
4720                                k = i*pitch;                           
4721                                for(j=1; j<width-1; j++)
4722                                {
4723                                        k = k + Bpp;
4724
4725                                        p = (uint16_t *)(((uint32_t)src)+k);
4726                                        p1 = (uint16_t *)(((uint32_t)src)+k-2);
4727                                        p2 = (uint16_t *)(((uint32_t)src)+k+2);
4728                                       
4729                                        bgfx_AFF_RGBA_4444(p,p1,p2,&tmp16,hcoef);
4730                                        p1 = (uint16_t *)(((uint32_t)dst)+k-2);/*update last pixel*/
4731                                        *p1=last16;
4732                                        last16 = tmp16;
4733                                }
4734                                p1 = (uint16_t *)(((uint32_t)dst)+k);/*update last pixel*/
4735                                *p1=last16;
4736                        }
4737                        break;
4738        }
4739
4740
4741}
4742#endif
4743
4744
4745int bgfx_anti_flutter_filter(bgfx_surf_p p_src, bgfx_surf_p p_dst, 
4746                uint16_t sx,uint16_t sy, uint16_t dx,uint16_t dy, 
4747                uint16_t sw,uint16_t sh)
4748{
4749        uint8_t *dst,*src;
4750        uint16_t w,h;
4751
4752        switch (p_src->format)
4753    {
4754        case GRAPHICS_FMT_ARGB_888:
4755        case GRAPHICS_FMT_RGBA_888:
4756        case GRAPHICS_FMT_RGB_565:
4757        case GRAPHICS_FMT_WRGB_1555:
4758        case GRAPHICS_FMT_RGBW_5551:
4759        case GRAPHICS_FMT_ARGB_4444:
4760        case GRAPHICS_FMT_RGBA_4444:
4761                break;
4762
4763        case GRAPHICS_FMT_P4:
4764        case GRAPHICS_FMT_P8:
4765                SGL_DEBUG(("%s: can not filter foramt %d", __func__, p_src->format));
4766                return -1;
4767
4768        default:
4769            SGL_DEBUG(("%s: unsupported foramt %d", __func__, p_src->format));
4770            return -1;
4771    }
4772
4773        if ((dx >= p_dst->surface.width) || (dy >= p_dst->surface.height))
4774        {
4775                SGL_DEBUG(("%s dst_x,dst_y (%d,%d) outside destination (%d,%d) ",__func__,dx,dy,
4776                                        p_dst->surface.width,p_dst->surface.height));
4777                return -1;
4778        }
4779
4780        if ((sx >= p_src->surface.width) || (sy >= p_src->surface.height))
4781        {
4782                SGL_DEBUG(("%s src_x,src_y (%d,%d) outside source (%d,%d) ",__func__,sx,sy,
4783                                        p_src->surface.width,p_src->surface.height));
4784                return -1;
4785        }
4786
4787        src = (uint8_t*)p_src->surface.buf;
4788        src += (sy * p_src->surface.pitch) + ((sx * p_src->bpp)/8);
4789        dst = (uint8_t*)p_dst->surface.buf;
4790        dst += (dy * p_dst->surface.pitch) + ((dx * p_dst->bpp)/8);
4791
4792        w = sw;
4793
4794        if (sw >= (p_src->surface.width - sx))
4795                w= p_src->surface.width - sx;
4796
4797        if (w >= p_dst->surface.width - dx)
4798                w = p_dst->surface.width - dx;
4799
4800        h = sh;
4801
4802        if (sh >= (p_src->surface.height - sy))
4803                h= p_src->surface.height - sy;
4804
4805        if (h >= p_dst->surface.height - dy)
4806                h = p_dst->surface.height - dy;
4807
4808        bgfx_soft_AFF_V(dst,src,w,h,p_src->surface.pitch,p_src->format,0);
4809#if defined SW_ANTI_FLUTTER_FILTER_HORIZONTAL
4810        bgfx_soft_AFF_H(dst,src,w,h,p_src->surface.pitch,p_src->format,0);
4811#endif
4812
4813        return 0;
4814
4815}
4816
4817/****************************************************************
4818 * INPUTS:      p - surface structure
4819 *                x,y - coordinates
4820 *                w,h - width and height of region
4821 *          c - constant color in ARGB8888 format
4822 * OUTPUTS: none
4823 * RETURNS: non-zero on error
4824 * FUNCTION: Fills the region as per following rule:
4825 *         const color c -> AcRcGcBc  (src1)
4826 *         surface     p -> AiRiGiBi  (src2)
4827 *         blended outpout -> AiRoGoBo
4828 *         where Ro = Ac * Rc + (1 - Ac) * Ri
4829 *               Go = Ac * Gc + (1 - Ac) * Gi
4830 *               Bo = Ac * Bc + (1 - Ac) * Bi
4831 ****************************************************************/
4832#if 0
4833int bgfx_blend_fill_rect(bgfx_surf_p p, uint16_t x,uint16_t y, uint16_t w, uint16_t h,
4834        bgfx_pixel c)
4835{
4836        uint8_t *dst;
4837        uint16_t j;
4838    unsigned int operation;
4839    uint8_t alpha1, alpha2;
4840#ifdef CONFIG_BGFX_SURF_RGB
4841        uint8_t *tdst;
4842    uint32_t i=0, dst_step, last_pixel=0;
4843#endif
4844
4845        if ((x >= p->surface.width) || (y >= p->surface.height))
4846        {
4847                SGL_DEBUG(("bgfx_blend_fill_rect x,y (%d,%d) w,h (%d,%d)\n",x,y,
4848                                        p->surface.width,p->surface.height));
4849                return -1;
4850        }
4851
4852        dst = (uint8_t*)p->surface.buf;
4853        dst += (y * p->surface.pitch) + ((x * p->bpp)/8);
4854
4855        if (w >= p->surface.width - x)
4856                w = p->surface.width - x;
4857
4858        if (h >= p->surface.height - y)
4859                h = p->surface.height - y;
4860
4861    /* Support available only for colorOp = eBlend and alphaOp = eIgnore */
4862    operation = SURFBLIT_BLEND_WITH_AVG_ALPHA | SURFBLIT_SET_DEST_ALPHA_WITH_SRC2_ALPHA;
4863    alpha1 = BPXL_GET_COMPONENT(BPXL_eA8_B8_G8_R8, c, 3);
4864    alpha2 = 1;
4865
4866        SGL_TRACE(("w=%d", w));
4867        SGL_TRACE(("h=%d", h));
4868        SGL_TRACE(("operation=0x%x alpha1=0x%x alpha2=0x%x", operation, alpha1, alpha2));
4869
4870    dst_step = p->bpp / 8;
4871#ifdef CONFIG_BGFX_SURF_RGB   
4872        if (p->flags & BGFX_SURF_RGB)
4873        {
4874                for (j = 0; j < h; ++j)
4875                {
4876                        tdst = dst;
4877                        for(i = 0; i < dst_step * w; i += dst_step, tdst += dst_step)
4878                        {
4879                                if(p->bpp == 32)
4880                                {
4881#ifdef COMPARE_PREVIOUS_PIXEL
4882                                        if(i > 0 && *(uint32_t*)(&dst[i]) == last_pixel)
4883                                        {                     
4884                      *((uint32_t*)tdst) = *(uint32_t*)(tdst - dst_step);
4885                                        }
4886                    else                       
4887#endif                       
4888                    {
4889                        last_pixel = *(uint32_t*)(&dst[i]);
4890                                        *((uint32_t*)tdst) = bgfx_blit_pixel(&c, &dst[i],
4891                                    32/*bpp of const color*/, p->bpp, p->bpp,
4892                                    GRAPHICS_FMT_ARGB_888, p->format, p->format,
4893                                    operation, alpha1, alpha2);
4894                    }
4895                                }
4896                else if(p->bpp == 16)
4897                                {
4898                  *((uint16_t*)tdst) = bgfx_blit_pixel(&c, &dst[i],
4899                                32/*bpp of const color*/, p->bpp, p->bpp,
4900                                GRAPHICS_FMT_ARGB_888, p->format, p->format,
4901                                operation, alpha1, alpha2) & 0xffff;
4902                }
4903                        }
4904                        dst += p->surface.pitch;
4905                }
4906        }
4907        else
4908#endif
4909        {
4910                SGL_DEBUG(("multi surface alpha blending only support RGB surfaces."));
4911                return -1;
4912        }
4913        bgfx_cacheflush(p->surface.buf, p->surface.pitch * p->surface.height);
4914        return 0;
4915}
4916#else
4917 int bgfx_blend_fill_rect(bgfx_surf_p p, uint16_t x,uint16_t y, uint16_t w, uint16_t h, 
4918        bgfx_pixel c)
4919{
4920        register uint8_t *dst;
4921        register uint32_t i, j;
4922        register uint32_t rt, gt, bt, rs, gs, bs, as;
4923#ifdef CONFIG_BGFX_SURF_RGB
4924        register uint8_t *tdst;
4925        register uint32_t dst_step;
4926        register uint32_t dst_pitch;
4927        register uint32_t last_pixel=0;
4928#endif
4929
4930        if ((x >= p->surface.width) || (y >= p->surface.height))
4931        {
4932                SGL_DEBUG(("bgfx_blend_fill_rect x,y (%d,%d) w,h (%d,%d)\n",x,y,
4933                                        p->surface.width,p->surface.height));
4934                return -1;
4935        }
4936
4937        dst = (uint8_t*)p->surface.buf;
4938        dst += (y * p->surface.pitch) + ((x * p->bpp)/8);
4939
4940        if (w >= p->surface.width - x)
4941                w = p->surface.width - x;
4942
4943        if (h >= p->surface.height - y)
4944                h = p->surface.height - y;
4945
4946        /* Support available only for colorOp = eBlend and alphaOp = eIgnore */
4947
4948        SGL_TRACE(("w=%d", w));
4949        SGL_TRACE(("h=%d", h));
4950
4951        dst_step = p->bpp / 8;
4952        dst_pitch = dst_step * w;
4953       
4954#ifdef CONFIG_BGFX_SURF_RGB   
4955        if (p->flags & BGFX_SURF_RGB)
4956        {
4957                if(p->bpp == 32)  {
4958                        as = (c >> 24) & 0xff;
4959                        rs = (c >> 16) & 0xff;
4960                        gs = (c >> 8) & 0xff;
4961                        bs = c & 0xff;
4962                        for (j = 0; j < h; ++j)
4963                        {
4964                                tdst = dst;
4965                                for(i = 0; i < dst_pitch; i += dst_step, tdst += dst_step)
4966                                {
4967#ifdef COMPARE_PREVIOUS_PIXEL
4968                                        if(i > 0 && *(uint32_t*)(&dst[i]) == last_pixel)  {  *((uint32_t*)tdst) = *(uint32_t*)(tdst - dst_step);  }
4969                                        else                       
4970#endif                       
4971                                        {
4972                                                last_pixel = *(uint32_t*)(&dst[i]); 
4973                                                {
4974                                                        rt = (last_pixel >> 16) & 0xff;
4975                                                        gt = (last_pixel >> 8) & 0xff;       
4976                                                        bt = last_pixel & 0xff;
4977                                                       
4978                                                        rt = (rs * as + (256 - as) * rt) >> 8; 
4979                                                        gt = (gs * as + (256 - as) * gt) >> 8;         
4980                                                        bt = (bs * as + (256 - as) * bt) >> 8; 
4981
4982                                                        *(uint32_t*)(&dst[i]) = (last_pixel & 0xff000000) | (rt << 16) | (gt << 8) | bt ; 
4983                                                }
4984                                        }
4985                                }
4986                                dst += p->surface.pitch;
4987                        } 
4988                }
4989                else if(p->bpp == 16) {
4990                        as = (c >> 12) & 0xf;
4991                        rs = (c >> 8) & 0xf;
4992                        gs = (c >> 4) & 0xf;
4993                        bs = c & 0xf;
4994                        for (j = 0; j < h; ++j)
4995                        {
4996                                tdst = dst;
4997                                for(i = 0; i < dst_step * w; i += dst_step, tdst += dst_step)
4998                                {
4999                                        last_pixel = *(uint16_t*)(&dst[i]); 
5000                                        {
5001                                                        rt = (last_pixel >> 8) & 0xf;
5002                                                        gt = (last_pixel >> 4) & 0xf;       
5003                                                        bt = last_pixel & 0xf;
5004                                                       
5005                                                        rt = (rs * as + (16 - as) * rt) >> 4;   
5006                                                        gt = (gs * as + (16 - as) * gt) >> 4;           
5007                                                        bt = (bs * as + (16 - as) * bt) >> 4;   
5008
5009                                                        *(uint16_t*)(&dst[i]) = (last_pixel & 0xf000) | (rt << 8) | (gt << 4) | bt ; 
5010                                        }
5011                                }
5012                                dst += p->surface.pitch;
5013                        }
5014                }
5015        }
5016        else
5017#endif
5018        {
5019                SGL_DEBUG(("multi surface alpha blending only support RGB surfaces."));
5020                return -1;
5021        }
5022        bgfx_cacheflush(p->surface.buf, p->surface.pitch * p->surface.height);
5023        return 0;
5024}
5025
5026#endif
5027
5028/****************************************************************
5029* Copy a rectangle area from one surface to the other with scaling.
5030*               Copy the source surface at (sx,sy) to the destination at (dx,dy)
5031****************************************************************/
5032int bgfx_blit_rect_scale(bgfx_surf_p p_src,             /* pointer to initialized source surface structure */ 
5033                                bgfx_surf_p p_dst,              /* pointer to initialized destination surface structure */     
5034                                          uint16_t sx,                  /* source horizontal location in pixels */
5035                                          uint16_t sy,                           /* source vertical location in pixels */
5036                                          uint16_t dx,                           /* destination horizontal location in pixels */
5037                                          uint16_t dy,                           /* destination vertical location in pixels */
5038                                          uint16_t sw,                  /* source width in pixel */
5039                                          uint16_t sh,/* source height in pixel */
5040                                          uint16_t dw,/* destination width in pixel*/
5041                                          uint16_t dh)  /* destination width in pixel*/                 
5042{
5043    uint8_t *dst,*src;
5044#ifdef CONFIG_BGFX_SURF_RGB
5045    uint32_t h_int_step, v_int_step;
5046    register uint32_t src_i, src_j,cur_y,cur_x,i,j,*pdst,*psrc;
5047#endif
5048
5049    if( (NULL == p_src) || (NULL == p_dst)) 
5050    {
5051        return BERR_TRACE(NEXUS_INVALID_PARAMETER); 
5052    }
5053
5054
5055    if ((dx >= p_dst->surface.width) || (dy >= p_dst->surface.height))
5056    {
5057        SGL_DEBUG(("bgfx_blit_rect_scale dst_x,dst_y (%d,%d) outside destination (%d,%d) ",dx,dy,
5058                    p_dst->surface.width,p_dst->surface.height));
5059        return -1;
5060    }
5061
5062    if ((sx >= p_src->surface.width) || (sy >= p_src->surface.height))
5063    {
5064        SGL_DEBUG(("bgfx_blit_rect_scale src_x,src_y (%d,%d) outside source (%d,%d) ",sx,sy,
5065                    p_src->surface.width,p_src->surface.height));
5066        return -1;
5067    }
5068
5069    /* only same pixelformat scaling is supported now.*/
5070    src = (uint8_t*)p_src->surface.buf;
5071    src += (sy * p_src->surface.pitch) + (sx * (p_src->bpp >> 3));
5072    dst = (uint8_t*)p_dst->surface.buf;
5073    dst += (dy * p_dst->surface.pitch) + (dx * (p_dst->bpp >> 3));
5074
5075    /* adjust width and height */
5076    if (sw >= (p_src->surface.width - sx))
5077        sw= p_src->surface.width - sx;
5078
5079    if (dw >= p_dst->surface.width - dx)
5080        dw = p_dst->surface.width - dx;
5081
5082    if (sh >= (p_src->surface.height - sy))
5083        sh= p_src->surface.height - sy;
5084
5085    if (dh >= p_dst->surface.height - dy)
5086        dh = p_dst->surface.height - dy;
5087
5088    h_int_step = ((sw << _BGFX_CALC_OFFSET) / dw);
5089    v_int_step = ((sh << _BGFX_CALC_OFFSET) / dh);
5090
5091#ifdef CONFIG_BGFX_SURF_RGB
5092    if (p_dst->flags & BGFX_SURF_RGB)
5093    {
5094        cur_y = 0;
5095        for( i = 0; i < dh; i++ )
5096        {
5097            cur_y += v_int_step;
5098            src_i = (cur_y - v_int_step) >> _BGFX_CALC_OFFSET;
5099            psrc = (uint32_t*)(src + p_src->surface.pitch * src_i);
5100            pdst = (uint32_t*)(dst + p_dst->surface.pitch * i);
5101
5102            cur_x = 0;
5103            for (j = 0; j < dw;j++)
5104            {
5105                cur_x += h_int_step;
5106                src_j = (cur_x - h_int_step) >> _BGFX_CALC_OFFSET;
5107                pdst[j] = psrc[src_j];
5108            }
5109        }
5110    }
5111#endif
5112    bgfx_cacheflush(p_dst->surface.buf,p_dst->surface.pitch * p_dst->surface.height);
5113    return 0;
5114
5115}
5116
5117/****************************************************************
5118* Copy a rectangle area from one surface to the other with scaling.
5119*               Copy the source surface at (sx,sy) to the destination at (dx,dy)
5120****************************************************************/
5121int bgfx_blit_rect_scale_v_up_h_up(bgfx_surf_p p_src,           /* pointer to initialized source surface structure */ 
5122                                bgfx_surf_p p_dst,              /* pointer to initialized destination surface structure */     
5123                                          uint16_t sx,                  /* source horizontal location in pixels */
5124                                          uint16_t sy,                           /* source vertical location in pixels */
5125                                          uint16_t dx,                           /* destination horizontal location in pixels */
5126                                          uint16_t dy,                           /* destination vertical location in pixels */
5127                                          uint16_t sw,                  /* source width in pixel */
5128                                          uint16_t sh,/* source height in pixel */
5129                                          uint16_t dw,/* destination width in pixel*/
5130                                          uint16_t dh)  /* destination width in pixel*/         
5131{
5132        uint8_t *line_p_src, *line_p_dst;
5133        uint8_t *pxl_p_src, *pxl_p_dst;
5134        register uint32_t i, j, k, cur_y, cur_x, dst_x, dst_y, next_x, next_y;
5135        uint32_t h_scl_step, v_scl_step;
5136        uint32_t  pixel_bytes, vs_line_shift;
5137        int as, rs, gs, bs;
5138        int  at, rt, gt, bt;  /* May be negative */
5139        uint32_t pxl_t;
5140
5141        /* 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); */
5142
5143        pixel_bytes = p_src->bpp >> 3;
5144        h_scl_step = ((dw << _BGFX_CALC_OFFSET) / sw);
5145        v_scl_step = ((dh << _BGFX_CALC_OFFSET) / sh);
5146
5147        /* Horizontal scaling */
5148        cur_y = 0;
5149        /* dst_y = 0; */
5150        line_p_src = (uint8_t*)p_src->surface.buf;
5151        line_p_src += p_src->surface.pitch * sy;
5152        line_p_dst = (uint8_t*)p_dst->surface.buf;
5153        line_p_dst += p_dst->surface.pitch * dy;
5154        for (i = 0; i < sh; i++)
5155        {
5156                pxl_p_src = line_p_src + pixel_bytes * sx;
5157                pxl_p_dst = line_p_dst + pixel_bytes * dx;
5158                dst_x = 0;
5159                cur_x = 0;
5160                for(j = 0; j < (uint32_t)(sw - 1); j++)
5161                {
5162                        cur_x += h_scl_step;
5163                        next_x = cur_x >> _BGFX_CALC_OFFSET;
5164                        pxl_t = *(uint32_t*)pxl_p_src;
5165                        as = ((pxl_t >> 24) & 0xff) << _BGFX_CALC_OFFSET;
5166                        rs = ((pxl_t >> 16) & 0xff) << _BGFX_CALC_OFFSET;
5167                        gs = ((pxl_t >> 8) & 0xff) << _BGFX_CALC_OFFSET;
5168                        bs = (pxl_t & 0xff) << _BGFX_CALC_OFFSET;
5169                        pxl_t = *((uint32_t*)(pxl_p_src + pixel_bytes));
5170                        at = ((pxl_t >> 24) & 0xff) << _BGFX_CALC_OFFSET;
5171                        rt = ((pxl_t >> 16) & 0xff) << _BGFX_CALC_OFFSET;
5172                        gt = ((pxl_t >> 8) & 0xff) << _BGFX_CALC_OFFSET;
5173                        bt = (pxl_t & 0xff) << _BGFX_CALC_OFFSET;
5174                        at = (at - as) / (int)(next_x - dst_x);
5175                        rt = (rt - rs) / (int)(next_x - dst_x);
5176                        gt = (gt - gs) / (int)(next_x - dst_x);
5177                        bt = (bt - bs) / (int)(next_x - dst_x);
5178                        /* printf("!!! (%d, %d, %d), 0x%08x, (%d, %d, %d)\n", rs, gs, bs, pxl_t, rt, gt, bt); */
5179                        for(k = dst_x; k < next_x; k++) {
5180                                /* printf("!!! I read src %d and write to dst %d\n", j, k); */
5181                                *((uint32_t*)pxl_p_dst) =
5182                                        ((as >>_BGFX_CALC_OFFSET) << 24) |
5183                                        ((rs >>_BGFX_CALC_OFFSET) << 16) |
5184                                        ((gs >>_BGFX_CALC_OFFSET) << 8) |
5185                                        (bs >>_BGFX_CALC_OFFSET) ;
5186                                pxl_p_dst += pixel_bytes;
5187                                as += at;
5188                                rs += rt;
5189                                gs += gt;
5190                                bs += bt;
5191                        }
5192                        pxl_p_src += pixel_bytes;
5193                        dst_x = next_x;
5194                }
5195                /* margin pixels*/
5196                while (dst_x < dw) {
5197                        *((uint32_t*)pxl_p_dst) = *((uint32_t*)pxl_p_src);
5198                        dst_x++;
5199                        pxl_p_dst += pixel_bytes;
5200                }
5201                line_p_src += p_src->surface.pitch;
5202                cur_y += v_scl_step;
5203                next_y = cur_y >> _BGFX_CALC_OFFSET;
5204#if 1
5205                line_p_dst = p_dst->surface.buf;
5206                line_p_dst += (p_dst->surface.pitch * (dy +next_y));
5207#else
5208                line_p_dst += (p_dst->surface.pitch);
5209#endif
5210        }
5211
5212#if 1
5213        /* Vertical scaling "source" are actually lines in dest surface*/
5214        dst_y = 0;
5215        cur_y = 0;
5216        line_p_dst =  (uint8_t*)p_dst->surface.buf;
5217        line_p_dst += p_dst->surface.pitch * dy;
5218        for (i = 0; i < (uint32_t)(sh - 1); i++)
5219        {
5220                pxl_p_dst = line_p_dst + pixel_bytes * dx;
5221                pxl_p_src = line_p_dst + pixel_bytes * dx;
5222                cur_y += v_scl_step;
5223                next_y = cur_y >> _BGFX_CALC_OFFSET;
5224                vs_line_shift = (p_dst->surface.pitch * (next_y - dst_y));
5225                for(j = 0; j < dw; j++)
5226                {
5227                        pxl_t = *(uint32_t*)pxl_p_src;
5228                        as = ((pxl_t >> 24) & 0xff) << _BGFX_CALC_OFFSET;
5229                        rs = ((pxl_t >> 16) & 0xff) << _BGFX_CALC_OFFSET;
5230                        gs = ((pxl_t >> 8) & 0xff) << _BGFX_CALC_OFFSET;
5231                        bs = (pxl_t & 0xff) << _BGFX_CALC_OFFSET;
5232                        pxl_t = *((uint32_t*)(pxl_p_src +  vs_line_shift));
5233                        at = ((pxl_t >> 24) & 0xff) << _BGFX_CALC_OFFSET;
5234                        rt = ((pxl_t >> 16) & 0xff) << _BGFX_CALC_OFFSET;
5235                        gt = ((pxl_t >> 8) & 0xff) << _BGFX_CALC_OFFSET;
5236                        bt = (pxl_t & 0xff) << _BGFX_CALC_OFFSET;
5237                        at = (at - as) / (int)(next_y - dst_y);
5238                        rt = (rt - rs) / (int)(next_y - dst_y);
5239                        gt = (gt - gs) / (int)(next_y - dst_y);
5240                        bt = (bt -bs) / (int)(next_y - dst_y);
5241                        /* printf("!!! (%d, %d, %d), 0x%08x, (%d, %d, %d)\n", rs, gs, bs, pxl_t, rt, gt, bt); */
5242                        for(k = dst_y; k < next_y; k++) {
5243                                *((uint32_t*)pxl_p_dst) =
5244                                        ((as >>_BGFX_CALC_OFFSET) << 24) |
5245                                        ((rs >>_BGFX_CALC_OFFSET) << 16) |
5246                                        ((gs >>_BGFX_CALC_OFFSET) << 8) |
5247                                        (bs >>_BGFX_CALC_OFFSET) ;
5248                                pxl_p_dst += p_dst->surface.pitch;
5249                                as += at;
5250                                rs += rt;
5251                                gs += gt;
5252                                bs += bt;
5253                        }
5254                        pxl_p_src += pixel_bytes;
5255                        pxl_p_dst = pxl_p_src;
5256                }
5257                line_p_dst += vs_line_shift;
5258                dst_y = next_y;
5259        }       
5260        /* margin pixels*/
5261        dst_y++;
5262        line_p_dst = p_dst->surface.buf;
5263        line_p_dst += p_dst->surface.pitch * dst_y + pixel_bytes * dx; /* line pointer shift */
5264        while ( dst_y <= dh ) {
5265                memcpy(line_p_dst, (line_p_dst - p_dst->surface.pitch), pixel_bytes * dw);
5266                dst_y++;
5267                line_p_dst += p_dst->surface.pitch;
5268        }
5269#endif
5270        return 0;
5271}
5272
5273/****************************************************************
5274* Copy a rectangle area from one surface to the other with scaling.
5275*               Copy the source surface at (sx,sy) to the destination at (dx,dy)
5276****************************************************************/
5277int bgfx_blit_rect_scale_v_down_h_down(bgfx_surf_p p_src,               /* pointer to initialized source surface structure */ 
5278                                bgfx_surf_p p_dst,              /* pointer to initialized destination surface structure */     
5279                                          uint16_t sx,                  /* source horizontal location in pixels */
5280                                          uint16_t sy,                           /* source vertical location in pixels */
5281                                          uint16_t dx,                           /* destination horizontal location in pixels */
5282                                          uint16_t dy,                           /* destination vertical location in pixels */
5283                                          uint16_t sw,                  /* source width in pixel */
5284                                          uint16_t sh,/* source height in pixel */
5285                                          uint16_t dw,/* destination width in pixel*/
5286                                          uint16_t dh)  /* destination width in pixel*/         
5287{
5288        uint8_t  *line_p_dst;
5289        uint8_t *pxl_p_src, *pxl_p_dst;
5290        register uint32_t i, j, ii, jj, cur_y, cur_x, src_x, src_y, next_x, next_y;
5291        uint32_t h_scl_step, v_scl_step;
5292        uint32_t  pixel_bytes, vs_pxl_cnt;
5293        uint8_t as, rs, gs, bs;
5294        int  at, rt, gt, bt;  /* May be negative */
5295        uint32_t pxl_t; 
5296
5297        /* 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); */
5298
5299        pixel_bytes = p_src->bpp >> 3;
5300        h_scl_step = ((sw << _BGFX_CALC_OFFSET) /dw);
5301        v_scl_step = ((sh << _BGFX_CALC_OFFSET) / dh);
5302
5303        /* Horizontal scaling */
5304        src_y = 0;
5305        cur_y = 0;
5306        line_p_dst = p_dst->surface.buf;
5307        line_p_dst += p_dst->surface.pitch * dy;
5308        for (i = 0; i < dh; i++)
5309        {
5310                pxl_p_dst = line_p_dst + pixel_bytes * dx;
5311                cur_y += v_scl_step;
5312                next_y = cur_y >> _BGFX_CALC_OFFSET;
5313                src_x = 0;
5314                cur_x = 0;
5315                for(j = 0; j < dw; j++)
5316                {
5317                        cur_x += h_scl_step;
5318                        next_x = cur_x >> _BGFX_CALC_OFFSET;
5319                        vs_pxl_cnt = (next_x - src_x) * (next_y - src_y);
5320                        at = rt = gt = bt = 0;
5321                        /* Accumulation */
5322                        for (ii = src_y; ii < next_y; ii++) {
5323                                pxl_p_src = (uint8_t*)p_src->surface.buf;
5324                                pxl_p_src += p_src->surface.pitch * sy + pixel_bytes * sx;
5325                                pxl_p_src += (p_src->surface.pitch * ii + pixel_bytes * src_x);
5326                                for (jj = src_x; jj < next_x; jj++) {
5327                                        pxl_t = *(uint32_t*)pxl_p_src;
5328                                        as = (pxl_t >> 24) & 0xff;
5329                                        rs = (pxl_t >> 16) & 0xff;
5330                                        gs = (pxl_t >> 8) & 0xff;
5331                                        bs = pxl_t & 0xff;
5332                                        at += as;  rt += rs;  gt += gs; bt += bs;
5333                                        pxl_p_src += pixel_bytes;
5334                                }
5335                        }
5336                        as = ((at << 4) / vs_pxl_cnt + 8) >> 4;
5337                        rs = ((rt << 4) / vs_pxl_cnt + 8) >> 4;
5338                        gs = ((gt << 4) / vs_pxl_cnt + 8) >> 4;
5339                        bs = ((bt << 4) / vs_pxl_cnt + 8) >> 4;
5340                        *((uint32_t*)pxl_p_dst) = (as << 24) |(rs << 16) | (gs << 8) | bs ;
5341                        pxl_p_dst += pixel_bytes;
5342                        src_x = next_x;
5343                }               
5344                line_p_dst += (p_dst->surface.pitch);
5345                src_y = next_y;
5346        }
5347
5348        return 0;
5349}
Note: See TracBrowser for help on using the repository browser.