source: svn/newcon3bcm2_21bu/nexus/lib/softgfx/src/b_softgfx.c @ 46

Last change on this file since 46 was 46, checked in by megakiss, 11 years ago

459Mhz로 OTC 주파수 변경

  • Property svn:executable set to *
File size: 33.9 KB
Line 
1/***************************************************************************
2* (c)2003-2009 Broadcom Corporation
3
4* This program is the proprietary software of Broadcom Corporation and/or its
5* licensors, and may only be used, duplicated, modified or distributed pursuant
6* to the terms and conditions of a separate, written license agreement executed
7* between you and Broadcom (an "Authorized License"). Except as set forth in an
8* Authorized License, Broadcom grants no license (express or implied), right to
9* use, or waiver of any kind with respect to the Software, and Broadcom expressly
10* reserves all rights in and to the Software and all intellectual property rights
11* therein. IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU HAVE NO RIGHT TO USE THIS
12* SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY NOTIFY BROADCOM AND DISCONTINUE
13* ALL USE OF THE SOFTWARE. 
14*   
15* Except as expressly set forth in the Authorized License,
16*   
17* 1.     This program, including its structure, sequence and organization,
18* constitutes the valuable trade secrets of Broadcom, and you shall use all
19* reasonable efforts to protect the confidentiality thereof, and to use this
20* information only in connection with your use of Broadcom integrated circuit
21* products.
22
23* 2.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
24* AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
25* WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
26* THE SOFTWARE.  BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES
27* OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE,
28* LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION
29* OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF
30* USE OR PERFORMANCE OF THE SOFTWARE.
31
32* 3.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS
33* LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR
34* EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR
35* USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF
36* THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT
37* ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
38* LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF
39* ANY LIMITED REMEDY.
40*
41* $brcm_Workfile: $
42* $brcm_Revision: $
43* $brcm_Date: $
44*
45* Description: Soft Graphics Applib Implementation
46*
47* Revision History:
48*
49* $brcm_Log: $
50*
51***************************************************************************/
52#include "b_softgfx_lib.h"
53#include "b_softgfx_priv.h"
54
55/* Define below macro to 1 for profiling softgfx API's */
56#define PROFILE_SOFTGFX 0
57#define GRAPHICS_DESTRIPE
58#if PROFILE_SOFTGFX
59#include <sys/time.h>
60#endif /* PROFILE_SOFTGFX */
61
62
63BDBG_MODULE(b_softgfx);
64
65
66#define NA 0
67static uint32_t B_SoftGfx_ColorOpMapping[B_SoftGfx_BlitColorOp_eMax] = 
68{
69    NA,                             /* B_SoftGfx_BlitColorOp_eCopySource */
70    SURFBLIT_BLEND_WITH_SPEC_ALPHA1,/* B_SoftGfx_BlitColorOp_eUseConstantAlpha */
71    SURFBLIT_BLEND_WITH_SRC1_ALPHA, /* B_SoftGfx_BlitColorOp_eUseSourceAlpha */
72    SURFBLIT_BLEND_WITH_SRC2_ALPHA, /* B_SoftGfx_BlitColorOp_eUseDestAlpha */
73    SURFBLIT_BLEND_WITH_AVG_ALPHA,  /* B_SoftGfx_BlitColorOp_eUseBlendEquation */
74};
75
76static uint32_t B_SoftGfx_AlphaOpMapping[B_SoftGfx_BlitAlphaOp_eMax] = 
77{
78    SURFBLIT_SET_DEST_ALPHA_WITH_SRC1_ALPHA, /* B_SoftGfx_BlitAlphaOp_eCopySource */
79    SURFBLIT_SET_DEST_ALPHA_WITH_SRC2_ALPHA, /* B_SoftGfx_BlitAlphaOp_eCopyDest */
80    SURFBLIT_SET_DEST_ALPHA_WITH_SPEC_ALPHA2,/* B_SoftGfx_BlitAlphaOp_eCopyConstant */
81    SURFBLIT_SET_DEST_ALPHA_WITH_AVG_ALPHA  /* B_SoftGfx_BlitAlphaOp_eUseBlendEquation */
82};
83
84static B_SoftGfx_BlitSettings sDefaultBlitSettings = {
85    NULL, /* srcsurface */
86    NULL, /* dstsurface */
87    NULL, /* outsurface */
88    {0, 0, 0, 0}, /* srcrect */
89    0, 0, /* dstx, dsty */
90    0, 0, /* outx, outy */
91    B_SoftGfx_BlitColorOp_eCopySource, /* colorOp */
92    B_SoftGfx_BlitAlphaOp_eCopySource, /* alphaOp */   
93    0, /* constAlphaColorOp */
94    0, /* constAlphaAlphaOp */
95    false, /* bApplyAntiFlutterFilter */
96    false, /* conversionMatrixEnabled */
97    { /* conversionMatrix */
98        0, /* shift */
99        {1, 0, 0, 0, 0,
100         0, 1, 0, 0, 0, 
101         0, 0, 1, 0, 0,
102         0, 0, 0, 1, 0}/* coeffMatrix */
103    }
104};
105
106static B_SoftGfx_ScaleSettings sDefaultScaleSettings = {
107    NULL, /* srcsurface */
108    NULL, /* outsurface */
109    {0, 0, 0, 0}, /* srcrect */
110    {0, 0, 0, 0}, /* outrect */
111    false
112};
113
114
115static bool B_SoftGfx_IsSupportedFillPixelFormat(NEXUS_PixelFormat format)
116{
117    switch (format)   
118    {
119        case NEXUS_PixelFormat_ePalette8:
120        case NEXUS_PixelFormat_eA8_R8_G8_B8:
121#if B_SOFTGFX_RGBA8888_SUPPORT
122        case NEXUS_PixelFormat_eR8_G8_B8_A8:
123#endif /* B_SOFTGFX_RGBA8888_SUPPORT */
124        case NEXUS_PixelFormat_eR5_G6_B5:
125        case NEXUS_PixelFormat_eA1_R5_G5_B5:
126        case NEXUS_PixelFormat_eR5_G5_B5_A1:
127        case NEXUS_PixelFormat_eA4_R4_G4_B4:
128        case NEXUS_PixelFormat_eR4_G4_B4_A4:
129        case NEXUS_PixelFormat_eA8_Y8_Cb8_Cr8:           
130            return true;
131        default:
132            BDBG_ERR(("Unsupported pixel format %d",format));
133            return false;
134    }/* switch */
135}
136
137static bool B_SoftGfx_IsSupportedBlitPixelFormat(NEXUS_PixelFormat format)
138{
139    switch (format)   
140    {
141        case NEXUS_PixelFormat_eA8_R8_G8_B8:
142#if B_SOFTGFX_RGBA8888_SUPPORT
143        case NEXUS_PixelFormat_eR8_G8_B8_A8:
144#endif /* B_SOFTGFX_RGBA8888_SUPPORT */
145        case NEXUS_PixelFormat_eR5_G6_B5:
146        case NEXUS_PixelFormat_eA1_R5_G5_B5:
147        case NEXUS_PixelFormat_eR5_G5_B5_A1:
148        case NEXUS_PixelFormat_eA4_R4_G4_B4:
149        case NEXUS_PixelFormat_eR4_G4_B4_A4:
150        case NEXUS_PixelFormat_eA8_Y8_Cb8_Cr8:
151            return true;
152        default:
153            BDBG_ERR(("Unsupported pixel format %d",format));
154            return false;
155    }/* switch */
156}
157
158
159static int bsoftgfx_create_surface(
160    bgfx_surf_p soft_sur, /* Output param */
161    NEXUS_SurfaceHandle surface
162    )
163{
164    bgfx_palette_t palette, *p_plt=NULL;
165    NEXUS_SurfaceCreateSettings sCreateSettings;
166    NEXUS_SurfaceMemory sMemory; 
167       
168    BDBG_ASSERT(soft_sur);
169    BDBG_ASSERT(surface);
170
171    NEXUS_Surface_GetCreateSettings(surface, &sCreateSettings);
172    NEXUS_Surface_GetMemory(surface, &sMemory); 
173
174    BDBG_MSG(("bsoftgfx_create_surface: Nexus Surface->createSettings -> pixel_format=%d palettepixelformat=%d, bpp=%d pitch=%d",
175        sCreateSettings.pixelFormat, sCreateSettings.palettePixelFormat, sCreateSettings.bitsPerPixel,
176        sMemory.pitch));       
177
178    if((sMemory.palette != NULL) && (sMemory.numPaletteEntries != 0))
179    {
180        BKNI_Memset(palette.clut, 0, sizeof(uint32_t)*PALETTE_SIZE);
181        BKNI_Memcpy(palette.clut, sMemory.palette, sizeof(uint32_t)*sMemory.numPaletteEntries);
182        p_plt = &palette;
183    }
184    else
185    {
186        p_plt = NULL;
187    }
188
189    soft_sur->format = sCreateSettings.pixelFormat;   
190   
191    return bgfx_create(soft_sur, 
192                        sCreateSettings.width, 
193                        sCreateSettings.height,
194                        0, 0,
195                        (uint8_t *)sMemory.buffer, 
196                                sMemory.pitch,
197                        p_plt,
198                                BGFX_SURF_RGB); /* assuming only RGB surface is sufficient */
199}
200
201static void bsoftgfx_destroy_surface(bgfx_surf_p soft_sur)
202{
203    bgfx_destroy(soft_sur);
204    return;
205}
206
207/***************************************************************************
208Summary:
209Get default settings for B_SoftGfx_Open
210***************************************************************************/
211void B_SoftGfx_GetDefaultOpenSettings(
212   B_SoftGfx_OpenSettings *pSettings /* [out] */
213   )
214{
215    BKNI_Memset(pSettings, 0, sizeof(*pSettings));
216    return;
217}
218
219/***************************************************************************
220Summary:
221Open a Soft Graphics interface for blit and fill operations.
222***************************************************************************/
223B_SoftGfxHandle B_SoftGfx_Open(   
224    const B_SoftGfx_OpenSettings *pSettings
225    )
226{
227    B_SoftGfx_OpenSettings defaultOpenSettings;
228    B_SoftGfxHandle gfx;
229
230    gfx = BKNI_Malloc(sizeof(*gfx));
231    if(!gfx) { BERR_TRACE(NEXUS_OUT_OF_SYSTEM_MEMORY); goto err_alloc; }
232
233    BKNI_Memset(gfx, 0, sizeof(*gfx));
234    BDBG_OBJECT_SET(gfx, B_SoftGfx);
235
236    if(!pSettings){
237        B_SoftGfx_GetDefaultOpenSettings(&defaultOpenSettings);
238        pSettings = &defaultOpenSettings;
239    }
240
241    gfx->sOpenSettings = *pSettings;
242
243    return gfx;
244
245err_alloc:
246    return NULL;
247}
248
249/***************************************************************************
250Summary:
251Close a Soft Graphics interface.
252***************************************************************************/
253void B_SoftGfx_Close(
254    B_SoftGfxHandle handle
255    )
256{
257    BDBG_OBJECT_ASSERT(handle, B_SoftGfx);
258    BKNI_Free(handle);
259    return;
260}
261
262/***************************************************************************
263Summary:
264Get default settings for the structure.
265***************************************************************************/
266void B_SoftGfx_GetDefaultFillSettings(
267    B_SoftGfx_FillSettings *pSettings /* [out] */
268    )
269{
270    BKNI_Memset(pSettings, 0, sizeof(*pSettings));
271    pSettings->colorOp = B_SoftGfx_FillOp_eCopy;
272    pSettings->alphaOp = B_SoftGfx_FillOp_eCopy;
273}
274
275/***************************************************************************
276Summary:
277Fill, tint or otherwise modify the pixels of an area of a surface using a constant
278value. This routine modifies the color channels and/or the alpha channel of the
279pixels of a surface using a constant value.
280
281Notes:
2821) Normal fill opeartion can be achieved by specifying both colorOp and alphaOp
283   as B_SoftGfx_FillOp_eCopy
284
2852) If surface is in palette format then color represents the index to the clut.
286   If surface is in non-palette format, say ARGB8888 or ARGB4444, then color
287   parameter has to be in the ARGB8888 format.
288
289   Ex: In ARGB4444 BLUE color is represented by 0xF00F. But, for filling an
290   ARGB4444 surface with solid BLUE color, the color parameter should be 0xFF0000FF
291   (as in ARGB8888 format).
292
2933) Only B_SoftGfx_FillOp_eCopy operation is supported for palette surface.
294
2954) Color channels of a non-paletter surface can be blended with the color channels
296   of the constant color using constant alpha. For such operations, user needs
297   to specify :
298    colorOp = B_SoftGfx_FillOp_eBlend
299    alphaOp = B_SoftGfx_FillOp_eIgnore
300
301***************************************************************************/
302NEXUS_Error B_SoftGfx_Fill(
303    B_SoftGfxHandle handle,
304    const B_SoftGfx_FillSettings *pSettings
305    )
306{
307    bgfx_surf_t sur;
308    NEXUS_Error err = NEXUS_SUCCESS;
309    NEXUS_SurfaceCreateSettings sCreateSettings;
310    NEXUS_SurfaceMemory sMemory; 
311    uint16_t width = 0;
312    uint16_t height = 0;
313#if PROFILE_SOFTGFX
314    struct timeval tv1,tv2;
315#endif /* PROFILE_SOFTGFX */   
316
317    BDBG_OBJECT_ASSERT(handle, B_SoftGfx);
318    if(!pSettings) { return BERR_TRACE(NEXUS_INVALID_PARAMETER); }
319
320    BDBG_MSG(("B_SoftGfx_Fill: surface=0x%x rect[%d,%d,%d,%d] color=0x%x colorOp=%d alphaOp=%d",
321        pSettings->surface, pSettings->rect.x,pSettings->rect.y,
322        pSettings->rect.width, pSettings->rect.height, pSettings->color,
323        pSettings->colorOp, pSettings->alphaOp));
324
325    /* Validate parameters & settings for fill */
326    NEXUS_Surface_GetCreateSettings(pSettings->surface, &sCreateSettings);
327    NEXUS_Surface_GetMemory(pSettings->surface, &sMemory);
328
329    if(!B_SoftGfx_IsSupportedFillPixelFormat(sCreateSettings.pixelFormat))
330        return BERR_TRACE(NEXUS_INVALID_PARAMETER);
331
332    if(pSettings->rect.x < 0 || pSettings->rect.y < 0)
333    {
334        BDBG_ERR(("Negative coordinates [x,y]=[%d,%d] are not supported!",
335            pSettings->rect.x,pSettings->rect.y));
336        return BERR_TRACE(NEXUS_INVALID_PARAMETER);
337    }
338
339    if((pSettings->rect.width == 0 && pSettings->rect.height != 0) ||
340       (pSettings->rect.width != 0 && pSettings->rect.height == 0)) 
341    {
342        BDBG_ERR(("Either height[%d] / width[%d] is 0",
343            pSettings->rect.width,pSettings->rect.height));
344        return BERR_TRACE(NEXUS_INVALID_PARAMETER);       
345    }
346       
347    /* create soft_surface */
348    bsoftgfx_create_surface(&sur, pSettings->surface);   
349
350    /* width,height of 0,0 fills the entire surface */
351    if(pSettings->rect.width == 0 && pSettings->rect.height == 0)
352    {
353        width = sCreateSettings.width;
354        height = sCreateSettings.height;     
355    }
356    else
357    {
358        width = pSettings->rect.width;
359        height = pSettings->rect.height;
360    }   
361
362    if((pSettings->colorOp == B_SoftGfx_FillOp_eCopy) &&
363       (pSettings->alphaOp == B_SoftGfx_FillOp_eCopy))
364    {
365#if PROFILE_SOFTGFX
366        gettimeofday(&tv1,NULL);
367#endif /* PROFILE_SOFTGFX */
368       
369        /* Normal fill operation */
370        bgfx_fill_rect(&sur, pSettings->rect.x, pSettings->rect.y, 
371                       width, height, pSettings->color);
372
373#if PROFILE_SOFTGFX
374        gettimeofday(&tv2,NULL);       
375        BDBG_ERR(("bgfx_fill_rect = %d ms",(int)((tv2.tv_sec-tv1.tv_sec)*1000+(tv2.tv_usec-tv1.tv_usec)/1000)));
376#endif /* PROFILE_SOFTGFX */       
377
378    }
379    else if ((pSettings->colorOp == B_SoftGfx_FillOp_eBlend) &&
380             (pSettings->alphaOp == B_SoftGfx_FillOp_eIgnore) &&
381             (sMemory.palette == NULL)&&
382             (sCreateSettings.pixelFormat != NEXUS_PixelFormat_eR5_G6_B5))
383    {
384#if PROFILE_SOFTGFX
385        gettimeofday(&tv1,NULL);
386#endif /* PROFILE_SOFTGFX */
387
388        /* Blend color channels with constant color using constant alpha */
389        err = bgfx_blend_fill_rect(&sur, pSettings->rect.x, pSettings->rect.y, 
390                       width, height, pSettings->color);
391
392#if PROFILE_SOFTGFX
393        gettimeofday(&tv2,NULL);       
394        BDBG_ERR(("bgfx_blend_fill_rect = %d ms",(int)((tv2.tv_sec-tv1.tv_sec)*1000+(tv2.tv_usec-tv1.tv_usec)/1000)));
395#endif /* PROFILE_SOFTGFX */       
396
397    }
398    else
399    {
400        BDBG_ERR(("B_SoftGfx_Fill: Not supported colorOp=%d alphaOp=%d palette=%p",
401            pSettings->colorOp, pSettings->alphaOp, sMemory.palette));
402        err = NEXUS_NOT_SUPPORTED;
403    }
404       
405    /* destroy soft_surface */
406    bsoftgfx_destroy_surface(&sur);
407
408    return err;
409}
410
411/***************************************************************************
412Summary:
413Get default settings for the structure.
414***************************************************************************/
415void B_SoftGfx_GetDefaultBlitSettings(
416    B_SoftGfx_BlitSettings *pSettings /* [out] */
417    )
418{
419    *pSettings = sDefaultBlitSettings;
420    return;
421}
422
423/***************************************************************************
424Summary:
425Perform a block transfer (blit) from one or two surfaces to an output.
426
427Description:
428Blit can be a simple blit or alpha blended blit. See B_SoftGfx_BlitSettings
429for details.
430***************************************************************************/
431NEXUS_Error B_SoftGfx_Blit(
432    B_SoftGfxHandle              handle,
433    const B_SoftGfx_BlitSettings *pSettings
434    )
435{
436    NEXUS_Error err = NEXUS_SUCCESS;   
437    bgfx_surf_t src, dst, out;
438    NEXUS_SurfaceCreateSettings sSrcCreateSettings, sDstCreateSettings, sOutCreateSettings;
439    bgfx_color_matrix_t sColorMatrix;
440    unsigned int i=0;
441#if PROFILE_SOFTGFX
442    struct timeval tv1,tv2;
443#endif /* PROFILE_SOFTGFX */
444
445    BDBG_OBJECT_ASSERT(handle, B_SoftGfx);
446    if(!pSettings) { return BERR_TRACE(NEXUS_INVALID_PARAMETER); }
447
448    BDBG_MSG(("B_SoftGfx_Blit: src=%p rect[%d,%d,%d,%d] \ndst=%p [x,y]=[%d,%d]"
449        " out=%p [x,y]=[%d,%d] \n colorOp=%d, alphaOp=%d"
450        " constAlphaAlphaOp=0x%x constAlphaColorOp=0x%x", 
451        pSettings->srcsurface, pSettings->srcrect.x,pSettings->srcrect.y,
452        pSettings->srcrect.width, pSettings->srcrect.height,
453        pSettings->dstsurface, pSettings->dstx, pSettings->dsty,
454        pSettings->outsurface, pSettings->outx, pSettings->outy,
455        pSettings->colorOp, pSettings->alphaOp, 
456        pSettings->constAlphaAlphaOp, pSettings->constAlphaColorOp));
457
458    /* Validate parameters & settings for fill */
459    if(!pSettings->srcsurface) { return BERR_TRACE(NEXUS_INVALID_PARAMETER); }
460    NEXUS_Surface_GetCreateSettings(pSettings->srcsurface, &sSrcCreateSettings);
461    if(!B_SoftGfx_IsSupportedBlitPixelFormat(sSrcCreateSettings.pixelFormat))
462        return BERR_TRACE(NEXUS_INVALID_PARAMETER);
463
464    if(!pSettings->outsurface) { return BERR_TRACE(NEXUS_INVALID_PARAMETER); }
465    NEXUS_Surface_GetCreateSettings(pSettings->srcsurface, &sOutCreateSettings);
466    if(!B_SoftGfx_IsSupportedBlitPixelFormat(sOutCreateSettings.pixelFormat))
467        return BERR_TRACE(NEXUS_INVALID_PARAMETER);
468
469    if(pSettings->dstsurface) /* Dst surface is optional */
470    {
471        NEXUS_Surface_GetCreateSettings(pSettings->srcsurface, &sDstCreateSettings);
472        if(!B_SoftGfx_IsSupportedBlitPixelFormat(sDstCreateSettings.pixelFormat))
473            return BERR_TRACE(NEXUS_INVALID_PARAMETER);
474    }
475
476    if(pSettings->srcrect.x < 0 || pSettings->srcrect.y < 0 || 
477       pSettings->dstx < 0 || pSettings->dsty < 0 || 
478       pSettings->outx < 0 || pSettings->outy < 0)
479    {
480        BDBG_ERR(("Negative coordinates src[x,y]=[%d,%d] dst[x,y]=[%d,%d]"
481            " out[x,y]=[%d,%d] are not supported!",
482            pSettings->srcrect.x,pSettings->srcrect.y, pSettings->dstx, 
483            pSettings->dsty, pSettings->outx, pSettings->outy));
484        return BERR_TRACE(NEXUS_INVALID_PARAMETER);
485    }
486
487    if((pSettings->srcrect.width == 0 && pSettings->srcrect.height != 0) ||
488       (pSettings->srcrect.width != 0 && pSettings->srcrect.height == 0) ||
489       (pSettings->srcrect.width == 0 && pSettings->srcrect.height == 0)) 
490    {
491        BDBG_ERR(("Height[%d] and/or width[%d] is 0",
492            pSettings->srcrect.width,pSettings->srcrect.height));
493        return BERR_TRACE(NEXUS_INVALID_PARAMETER);       
494    } 
495
496    if(pSettings->colorOp == B_SoftGfx_BlitColorOp_eMax || 
497       pSettings->alphaOp == B_SoftGfx_BlitAlphaOp_eMax)   
498    {
499        BDBG_ERR(("colorOp[%d] and/or alphaOp[%d] is invalid",
500            pSettings->colorOp, pSettings->alphaOp));
501        return BERR_TRACE(NEXUS_INVALID_PARAMETER);       
502    }
503
504    /* All sanity checks done by now */
505   
506    /* Map to corresponding soft graphics operations */
507    if(pSettings->colorOp == B_SoftGfx_BlitColorOp_eCopySource && 
508       pSettings->alphaOp == B_SoftGfx_BlitAlphaOp_eCopySource)
509    {
510        /* Simple BLT operation */
511        if(sSrcCreateSettings.pixelFormat != sOutCreateSettings.pixelFormat)
512        {
513            BDBG_ERR(("srcsurface pixel format(%d) != out surface pixel format(%d)",
514                sSrcCreateSettings.pixelFormat, sOutCreateSettings.pixelFormat));
515            return BERR_TRACE(NEXUS_INVALID_PARAMETER);       
516        }
517       
518        /* create soft surfaces */
519        bsoftgfx_create_surface(&src, pSettings->srcsurface);   
520        bsoftgfx_create_surface(&out, pSettings->outsurface);   
521
522        /* blit rect */
523#if PROFILE_SOFTGFX
524        gettimeofday(&tv1,NULL);
525#endif /* PROFILE_SOFTGFX */
526
527        sColorMatrix.shift = pSettings->conversionMatrix.shift;
528        for(i = 0 ; i < B_SOFTGFX_COLOR_MATRIX_COEFF_COUNT ; i++)
529        {
530            sColorMatrix.coeffMatrix[i] = pSettings->conversionMatrix.coeffMatrix[i];
531        }
532       
533        err = bgfx_blit_rect(&src, &out, 
534                    pSettings->srcrect.x, pSettings->srcrect.y, 
535                    pSettings->outx, pSettings->outy, 
536                    pSettings->srcrect.width, pSettings->srcrect.height, 
537                    pSettings->conversionMatrixEnabled, 
538                    &(sColorMatrix));
539        if(err) {BERR_TRACE(err); /* fall through */}
540
541#if PROFILE_SOFTGFX
542        gettimeofday(&tv2,NULL);       
543        BDBG_ERR(("bgfx_blit_rect BLT = %d ms",(int)((tv2.tv_sec-tv1.tv_sec)*1000+(tv2.tv_usec-tv1.tv_usec)/1000)));
544#endif /* PROFILE_SOFTGFX */       
545
546
547        if(pSettings->bApplyAntiFlutterFiler)
548        {
549            #if 1 /* DEPRECATED */
550            err = bgfx_anti_flutter_filter(&out, &out, 
551                    pSettings->outx, pSettings->outy, 
552                    pSettings->outx, pSettings->outy, 
553                    pSettings->srcrect.width, pSettings->srcrect.height);
554            if(err) {BERR_TRACE(err); /* fall through */}
555            #else
556            BDBG_WRN(("\n\n***********************************************************\n"
557                      "Anti-flutter support has been deprecated from softgfx.\n"
558                      "Please use anti-flutter from GFD block.\n"
559                      "***********************************************************\n"));   
560            #endif
561        }
562
563        /* destroy soft_surface */
564        bsoftgfx_destroy_surface(&src);
565        bsoftgfx_destroy_surface(&out);
566    }
567    else
568    {
569        /* Blend operation */
570        unsigned int operation;
571       
572        /* Requires dst surface, check it! */
573        if(!pSettings->dstsurface) { return BERR_TRACE(NEXUS_INVALID_PARAMETER); }       
574
575        /* All three surfaces should be of the same pixel fornat */
576        if(sSrcCreateSettings.pixelFormat != sOutCreateSettings.pixelFormat ||
577           sSrcCreateSettings.pixelFormat != sDstCreateSettings.pixelFormat )
578        {
579            BDBG_ERR(("src pixel format(%d) != out pixel format(%d) != dst pixel format(%d)",
580                sSrcCreateSettings.pixelFormat, sOutCreateSettings.pixelFormat, sDstCreateSettings.pixelFormat));
581            return BERR_TRACE(NEXUS_INVALID_PARAMETER);       
582        }
583        /* create soft surfaces */
584        bsoftgfx_create_surface(&src, pSettings->srcsurface);   
585        bsoftgfx_create_surface(&dst, pSettings->dstsurface);   
586        bsoftgfx_create_surface(&out, pSettings->outsurface);   
587
588        operation = B_SoftGfx_ColorOpMapping[pSettings->colorOp]|
589                    B_SoftGfx_AlphaOpMapping[pSettings->alphaOp];
590
591        BDBG_MSG(("Blend: operation=0x%x",operation));
592#if PROFILE_SOFTGFX
593        gettimeofday(&tv1,NULL);
594#endif /* PROFILE_SOFTGFX */       
595
596        err = bgfx_blit_rect_multisuf_blending(&src, &dst, &out, 
597                    pSettings->srcrect.x, pSettings->srcrect.y, 
598                    pSettings->dstx, pSettings->dsty, 
599                    pSettings->outx, pSettings->outy, 
600                    pSettings->srcrect.width, pSettings->srcrect.height,
601                    operation, pSettings->constAlphaColorOp, pSettings->constAlphaAlphaOp);
602        if(err) {BERR_TRACE(err); /* fall through */}
603#if PROFILE_SOFTGFX
604        gettimeofday(&tv2,NULL);       
605        BDBG_ERR(("bgfx_blit_rect alpha-blend= %d ms",(int)((tv2.tv_sec-tv1.tv_sec)*1000+(tv2.tv_usec-tv1.tv_usec)/1000)));
606#endif /* PROFILE_SOFTGFX */       
607
608        if(pSettings->bApplyAntiFlutterFiler)
609        {
610            #if 0 /* DEPRECATED */
611            err = bgfx_anti_flutter_filter(&out, &out,
612                    pSettings->outx, pSettings->outy,
613                    pSettings->outx, pSettings->outy,
614                    pSettings->srcrect.width, pSettings->srcrect.height);
615            if(err) {BERR_TRACE(err); /* fall through */}
616            #else
617            BDBG_WRN(("\n\n***********************************************************\n"
618                      "Anti-flutter support has been deprecated from softgfx.\n"
619                      "Please use anti-flutter from GFD block.\n"
620                      "***********************************************************\n"));   
621            #endif
622        }
623       
624        /* destroy soft_surface */
625        bsoftgfx_destroy_surface(&src);
626        bsoftgfx_destroy_surface(&dst);           
627        bsoftgfx_destroy_surface(&out);
628    }
629    return err;
630}
631
632/***************************************************************************
633Summary:
634Get default settings for the structure.
635***************************************************************************/
636void B_SoftGfx_GetDefaultScaleSettings(
637    B_SoftGfx_ScaleSettings *pSettings /* [out] */
638    )
639{
640    *pSettings = sDefaultScaleSettings;
641    return;
642}
643
644
645
646/***************************************************************************
647Summary:
648Perform scale-up/down from one surfaces to another.
649
650Description:
651User can choose to enable filtering (slower but better quality) or not
652***************************************************************************/
653NEXUS_Error B_SoftGfx_Scale(
654    B_SoftGfxHandle              handle,
655    B_SoftGfx_ScaleSettings *pSettings
656    )
657{
658    NEXUS_Error err = NEXUS_SUCCESS;   
659    bgfx_surf_t src, out;
660    NEXUS_SurfaceCreateSettings sSrcCreateSettings, sOutCreateSettings;
661#if PROFILE_SOFTGFX
662    struct timeval tv1,tv2;
663#endif /* PROFILE_SOFTGFX */
664       
665    BDBG_OBJECT_ASSERT(handle, B_SoftGfx);
666    if( (0 == pSettings->srcsurface) || (0 == pSettings->outsurface)) { return BERR_TRACE(NEXUS_INVALID_PARAMETER); }
667
668    BDBG_MSG(("B_SoftGfx_Scale: src=%p rect[%d,%d,%d,%d] "
669        " out=%p rect[%d,%d,%d,%d], ApplySclFiltering=%d", 
670        pSettings->srcsurface, pSettings->srcrect.x, pSettings->srcrect.y, pSettings->srcrect.width, pSettings->srcrect.height,
671        pSettings->outsurface, pSettings->outrect.x, pSettings->outrect.y, pSettings->outrect.width, pSettings->outrect.height, 
672        pSettings->bApplySclFiltering));
673
674    NEXUS_Surface_GetCreateSettings(pSettings->srcsurface, &sSrcCreateSettings);
675    if(!B_SoftGfx_IsSupportedBlitPixelFormat(sSrcCreateSettings.pixelFormat))
676        return BERR_TRACE(NEXUS_INVALID_PARAMETER);   
677
678       
679    NEXUS_Surface_GetCreateSettings(pSettings->outsurface, &sOutCreateSettings);
680    if(!B_SoftGfx_IsSupportedBlitPixelFormat(sOutCreateSettings.pixelFormat))
681        return BERR_TRACE(NEXUS_INVALID_PARAMETER);   
682
683    if((sSrcCreateSettings.pixelFormat != NEXUS_PixelFormat_eA8_R8_G8_B8)
684        ||(sOutCreateSettings.pixelFormat != NEXUS_PixelFormat_eA8_R8_G8_B8))
685    {
686        BDBG_ERR(("B_SoftGfx_Scale: Currently this API only support ARGB8888 pixel format"));
687        return BERR_TRACE(NEXUS_INVALID_PARAMETER);       
688    }
689   
690   
691
692    if(pSettings->srcrect.width <= 0 || pSettings->srcrect.height <= 0 ||
693       pSettings->outrect.width <= 0 || pSettings->outrect.height <= 0)
694    {
695        BDBG_ERR(("B_SoftGfx_Scale: Invalid coordinates src_rect[%d,%d, %d, %d] out_rect[%d,%d,%d,%d]",
696            pSettings->srcrect.x, pSettings->srcrect.y, pSettings->srcrect.width, pSettings->srcrect.height, 
697            pSettings->outrect.x, pSettings->outrect.y, pSettings->outrect.width, pSettings->outrect.height));
698        return BERR_TRACE(NEXUS_INVALID_PARAMETER);
699    }
700
701    if(pSettings->srcrect.x < 0 || pSettings->srcrect.y < 0 || 
702        pSettings->outrect.x < 0 || pSettings->outrect.y < 0)
703    {
704        BDBG_ERR(("Negative coordinates src[x,y]=[%d,%d] dst[x,y]=[%d,%d]"
705            " are not supported!",
706            pSettings->srcrect.x,pSettings->srcrect.y, 
707            pSettings->outrect.x,pSettings->outrect.y));
708        return BERR_TRACE(NEXUS_INVALID_PARAMETER);
709    }   
710
711    /* create soft surfaces */
712    bsoftgfx_create_surface(&src, pSettings->srcsurface);   
713    bsoftgfx_create_surface(&out, pSettings->outsurface);
714
715        /* blit rect */
716#if PROFILE_SOFTGFX
717    gettimeofday(&tv1,NULL);
718#endif /* PROFILE_SOFTGFX */
719    {
720            uint32_t  x_scl_ratio, y_scl_ratio;
721            x_scl_ratio = (pSettings->outrect.width << 3) / pSettings->srcrect.width;
722            y_scl_ratio = (pSettings->outrect.height << 3) / pSettings->srcrect.height;
723            if ( (pSettings->outrect.width == pSettings->srcrect.width) && (pSettings->outrect.height == pSettings->srcrect.height) )
724            {
725                err = bgfx_blit_rect(&src, &out, 
726                    pSettings->srcrect.x, pSettings->srcrect.y, 
727                    pSettings->outrect.x, pSettings->outrect.y, 
728                    pSettings->srcrect.width, pSettings->srcrect.height, 0, NULL);
729                if(err) {BERR_TRACE(err); /* fall through */}
730            }
731            else if ( (x_scl_ratio >= 16) && (y_scl_ratio >= 16) && pSettings->bApplySclFiltering )
732            {
733                err = bgfx_blit_rect_scale_v_up_h_up(&src, &out, 
734                    pSettings->srcrect.x, pSettings->srcrect.y, 
735                    pSettings->outrect.x, pSettings->outrect.y, 
736                    pSettings->srcrect.width, pSettings->srcrect.height,
737                    pSettings->outrect.width, pSettings->outrect.height);
738                if(err) {BERR_TRACE(err); /* fall through */}
739            }
740            else if (x_scl_ratio <= 4 && y_scl_ratio <= 4 && pSettings->bApplySclFiltering )
741            {
742                err = bgfx_blit_rect_scale_v_down_h_down(&src, &out, 
743                    pSettings->srcrect.x, pSettings->srcrect.y, 
744                    pSettings->outrect.x, pSettings->outrect.y, 
745                    pSettings->srcrect.width, pSettings->srcrect.height,
746                    pSettings->outrect.width, pSettings->outrect.height);
747                if(err) {BERR_TRACE(err); /* fall through */}
748            }
749            else
750            {
751                err = bgfx_blit_rect_scale(&src, &out, 
752                pSettings->srcrect.x, pSettings->srcrect.y, 
753                pSettings->outrect.x, pSettings->outrect.y, 
754                pSettings->srcrect.width, pSettings->srcrect.height,
755                pSettings->outrect.width, pSettings->outrect.height);
756                if(err) {BERR_TRACE(err); /* fall through */}
757            }
758    }
759#if PROFILE_SOFTGFX
760    gettimeofday(&tv2,NULL);   
761    BDBG_ERR(("B_SoftGfx_Scale BLT = %d ms",(int)((tv2.tv_sec-tv1.tv_sec)*1000+(tv2.tv_usec-tv1.tv_usec)/1000)));
762#endif /* PROFILE_SOFTGFX */     
763
764    /* destroy soft_surface */
765    bsoftgfx_destroy_surface(&src);
766    bsoftgfx_destroy_surface(&out);
767
768    return err;
769}
770
771
772#ifdef GRAPHICS_DESTRIPE
773typedef char (*NEXUS_StillDecoder_P_read_char_func)(const void *address);
774
775static char NEXUS_StillDecoder_P_read_char_host(const void *address)
776{
777    return *(char *)address;
778}
779
780/*
781Destripe logic from Jeff Christensen's (christj) DestripeSample.c
782
783The source format 4:2:0. Each src row of chroma is 2 rows of dest chroma.
784AVD outputs in host endianness. Byte order on LE system is:
785    luma: Y3 Y2 Y1 Y0 Y4 etc.
786    chroma: Cr1 Cb1 Cr0 Cb0 Cr2 etc.
787
788The dest format is Y0CbY1Cr 4:2:2, 2 bytes per pixel, in host endianess.
789Byte order on LE system is:
790    Cr0 Y1 Cb0 Y0 Cr1 Y3 Cb1 Y2
791*/
792static int DestripeImage (const char *from, char *to,
793                          int image_wid, int image_hgt,
794                          int stripe_wid, int stripe_hgt, bool is_luma,
795                          NEXUS_StillDecoder_P_read_char_func read_func)
796{
797    int stripe_size = stripe_wid * stripe_hgt;
798    int pixels      = image_wid  * image_hgt;
799
800    int i;
801    int scol;
802    int icol;
803    const char *ptr;
804
805#if BSTD_CPU_ENDIAN==BSTD_ENDIAN_LITTLE
806    if (is_luma) to++; /* For luma pixels, offset by one in order to interleave */
807#else
808    if (!is_luma) to++; /* For luma pixels, offset by one in order to interleave */
809#endif
810
811    scol = 0;
812    icol = 0;
813    ptr  = from;
814
815    for (i = 0; i < pixels; i++) {
816        /* calc swap */
817#if BSTD_CPU_ENDIAN==BSTD_ENDIAN_LITTLE
818        int swapinc = (scol % 4 < 2) ? 2 : -2;
819
820        *to = read_func(ptr+scol+swapinc);
821#else
822        BSTD_UNUSED(read_func);
823        *to = ptr[scol];
824#endif
825        if (!is_luma) {
826            /* for 4:2:0 -> 4:2:2 conversion, each chroma value applies to 2 rows */
827#if BSTD_CPU_ENDIAN==BSTD_ENDIAN_LITTLE
828            *(to+(image_wid*2)) = read_func(ptr+scol+swapinc);
829#else
830            *(to+(image_wid*2)) = ptr[scol];
831#endif
832        }
833
834        to += 2; /* skip to next luma or chroma byte */
835
836        /* If we reach the end of a stripe, move down to the
837        * next strip to continue this row.
838        */
839        if (++scol == stripe_wid) {
840            scol = 0;
841            ptr += stripe_size;
842        }
843
844        /* If we reach the end of a row, go back to the 1st
845        * stripe, but move down a row.  Reset everything.
846        */
847        if (++icol == image_wid) {
848            from += stripe_wid;
849            ptr   = from;
850            /* for 4:2:0 -> 4:2:2 conversion, we've already written 2 rows, so skip */
851            if (!is_luma) to += (image_wid*2);
852            icol  = 0;
853            scol  = 0;
854        }
855    }
856    return 0;
857}
858
859
860/***************************************************************************
861Summary:
862Create a new surface by copying from a striped surface
863
864Description:
865A striped surface is the output of NEXUS_StillDecoder_GetStripedSurface.
866***************************************************************************/
867
868NEXUS_SurfaceHandle B_SoftGfx_Destripe( NEXUS_StripedSurfaceHandle stripedSurface)
869{
870    NEXUS_SurfaceCreateSettings surfaceCreateSettings;
871    NEXUS_SurfaceHandle surface;
872    NEXUS_SurfaceMemory mem;
873    NEXUS_StillDecoder_P_read_char_func func=NEXUS_StillDecoder_P_read_char_host;
874    NEXUS_StripedSurfaceCreateSettings sStripedSurfaceSettings;
875
876    NEXUS_StripedSurface_GetCreateSettings(stripedSurface,&sStripedSurfaceSettings);
877
878   
879    if (sStripedSurfaceSettings.imageHeight== 0 || sStripedSurfaceSettings.imageWidth== 0) {
880        return NULL;
881    }   
882       
883    /* create a bsurface_t which wraps the BSUR_Handle used by VDC */
884    NEXUS_Surface_GetDefaultCreateSettings(&surfaceCreateSettings);
885    surfaceCreateSettings.height = sStripedSurfaceSettings.imageHeight;
886    surfaceCreateSettings.width = sStripedSurfaceSettings.imageWidth;
887    surfaceCreateSettings.pixelFormat = NEXUS_PixelFormat_eY08_Cb8_Y18_Cr8;
888    surface = NEXUS_Surface_Create(&surfaceCreateSettings);
889    if (!surface) {return NULL;}       
890
891    /* now destripe and do pixel conversion into the new buffer with a two pass algorithm */
892        NEXUS_Surface_GetMemory(surface, &mem);
893    DestripeImage(sStripedSurfaceSettings.pLumaBuffer, mem.buffer, sStripedSurfaceSettings.imageWidth, sStripedSurfaceSettings.imageHeight,
894                  sStripedSurfaceSettings.stripedWidth, sStripedSurfaceSettings.lumaStripedHeight, true, func);
895    DestripeImage(sStripedSurfaceSettings.pChromaBuffer, mem.buffer, sStripedSurfaceSettings.imageWidth, sStripedSurfaceSettings.imageHeight/2,
896                  sStripedSurfaceSettings.stripedWidth, sStripedSurfaceSettings.chromaStripedHeight, false, func);
897        NEXUS_Surface_Flush(surface);   
898
899        return surface;
900}
901
902#endif/*Graphics Destripe support*/
903
Note: See TracBrowser for help on using the repository browser.