source: svn/branches/kctv/newcon3bcm2_21bu/magnum/syslib/grclib/7552/bgrclib.c

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

1.phkim

  1. revision copy newcon3sk r27
  • Property svn:executable set to *
File size: 70.9 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2003-2012, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: bgrclib.c $
11 * $brcm_Revision: Hydra_Software_Devel/22 $
12 * $brcm_Date: 2/16/12 3:54p $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/syslib/grclib/7405/bgrclib.c $
19 *
20 * Hydra_Software_Devel/22   2/16/12 3:54p nissen
21 * SW7405-5427: Adding flags for output mirroring when blitting
22 *
23 * Hydra_Software_Devel/21   7/19/11 12:09p erickson
24 * SW3548-2564: restore fix from /main/Hydra_Software_Devel/17
25 *
26 * Hydra_Software_Devel/20   9/21/10 11:52a nissen
27 * SW7405-4755: Fixed KeyMatrixScale order in GRC.
28 *
29 * Hydra_Software_Devel/19   11/4/09 9:48a erickson
30 * SW7405-3328: add BGRClib_PorterDuffFill
31 *
32 * Hydra_Software_Devel/DirectFB_1_4_Port/1   10/30/09 2:07p robertwm
33 * SW7405-3328: Support Porter-Duff Fill Compositions.
34 *
35 * Hydra_Software_Devel/16   9/29/09 2:52p erickson
36 * SW7405-3021: add BGRClib_BlitParams.srcAlphaPremult
37 *
38 * Hydra_Software_Devel/15   8/3/09 3:30p dkaufman
39 * PR57260: No longer call BGRC_ResetState; No longer calling GRC routines
40 * if params not changed from previous call; Added BGRClib_ResetState
41 *
42 * Hydra_Software_Devel/14   4/23/09 9:04a dkaufman
43 * PR53701: Add _eAntiFlutter and _eAntiFlutterSharp to list of filters
44 * that will enable filtering for non-scaled blits
45 *
46 * Hydra_Software_Devel/13   4/17/09 1:37p dkaufman
47 * PR53701: Added source and destination mirroring
48 *
49 * Hydra_Software_Devel/12   4/3/09 2:37p dkaufman
50 * PR53701: Add scaling control in BGRClib_Blit with new
51 * BGRClib_BlitScalingControlParams param block
52 *
53 * Hydra_Software_Devel/11   4/3/09 7:48a dkaufman
54 * PR53701: Add colorkey selection params for colorkeying
55 *
56 * Hydra_Software_Devel/10   3/18/09 2:37p dkaufman
57 * PR47134: Changed BGRClib_Blend to BGRClib_BlendEquation; Removed
58 * deprecated brightness, contrast, etc from BGRClib_BlitParams; Factored
59 * BGRClib_BlitColorMatrixParams and BGRClib_BlitColorKeyParams out of
60 * BGRClib_BlitParams; Added BGRClib_BlitPatternParams; Changed
61 * BGRClib_Blit params to match new param blocks; Fixed
62 * _eUseCombinedAlpha: Pa = Sa + Da*(1-Sa) instead of Sa * Sa + Da*(1-Sa)
63 *
64 * Hydra_Software_Devel/9   9/14/08 11:18a dkaufman
65 * PR44067: Expose GRC blending equations; fix hang caused by enabling
66 * filtering for unscaled blits
67 *
68 * Hydra_Software_Devel/8   7/16/08 12:26p dkaufman
69 * PR44839:Fixed call to set destination rect; PR43659: use 'static const'
70 * for all globals
71 *
72 * Hydra_Software_Devel/7   5/16/08 12:58p dkaufman
73 * PR42727: Resolve coverity issues
74 *
75 * Hydra_Software_Devel/6   2/27/08 11:27a dkaufman
76 * PR38886: Set the defaults for the constant color params to match the
77 * default GRC values (0xFF000000)
78 *
79 * Hydra_Software_Devel/5   2/27/08 11:23a dkaufman
80 * PR38886: Added destConstColor to blit param block
81 *
82 * Hydra_Software_Devel/4   2/11/08 1:04p dkaufman
83 * PR38886: Improved comments; added BGRClib_GetDefaultPaletteBlitParams;
84 * corrected blend equations; added dest color keying to BGRClib_Blit;
85 * added color matrix to BGRClib_Blit
86 *
87 * Hydra_Software_Devel/3   12/19/07 2:23p dkaufman
88 * PR36190: Added alpha blend
89 *
90 * Hydra_Software_Devel/2   11/5/07 12:18p dkaufman
91 * PR36190: Removed comment warning; replaced "BBS" with "B_BBS" as short
92 * form of "BGRC_Blend_Source"
93 *
94 * Hydra_Software_Devel/1   10/18/07 12:49p vobadm
95 * PR36190:  Adding directories and files
96 *
97 *
98 ***************************************************************************/
99#include "bgrclib.h"
100#include "bstd.h"
101#include "berr.h"
102#include "berr_ids.h"
103#include "bdbg.h"
104#include "bkni.h"
105
106BDBG_MODULE(BGRClib);
107
108/***************************************************************************
109* Forward declarations of static (private) functions
110***************************************************************************/
111
112#define GRCLIB_CHECK(grclibh) BDBG_ASSERT(grclibh != NULL && grclibh->hGRC != NULL)
113
114/* This macro allows a concise representation of the BGRC_Blend_Source enum */
115#define B_BBS(x) (BGRC_Blend_Source_e ## x)
116
117static BERR_Code BGRClib_p_Go(
118    BGRClib_Handle          grclibHandle,
119    BGRClib_PendType        pendtype
120);
121
122static BERR_Code BGRClib_p_ConvertColorToStdColor(
123    BSUR_Surface_Handle     surface,
124    uint32_t                constantcolor,
125    BGRClib_ColorFmtType    fmtType,
126    uint32_t*               pColor
127);
128
129static BERR_Code BGRClib_p_GetValidPositionInfo(
130    const BRect*            pRect,
131    BSUR_Surface_Handle     surface,
132    uint32_t*               pX,
133    uint32_t*               pY,
134    uint32_t*               pWidth,
135    uint32_t*               pHeight);
136
137#define PBRECT_WIDTH(r)  (r->right - r->left)
138#define PBRECT_HEIGHT(r) (r->bottom - r->top)
139
140/***************************************************************************
141* Implementation of "BGRClib_" API functions
142***************************************************************************/
143
144typedef struct BGRClib_P_Data_tag
145{
146    BGRC_Handle     hGRC;
147    BGRC_Callback   callback_isr;
148    void*           callback_data;
149
150    /* Data to optimize calls in to GRC */
151    uint32_t srcColor;
152    uint32_t dstColor;
153    uint32_t bldColor;
154
155    uint32_t srcX, srcY, srcWidth, srcHeight;
156    uint32_t dstX, dstY, dstWidth, dstHeight;
157    uint32_t outX, outY, outWidth, outHeight;
158
159    BGRC_Output_ColorKeySelection selA;
160    BGRC_Output_ColorKeySelection selB;
161    BGRC_Output_ColorKeySelection selC;
162    BGRC_Output_ColorKeySelection selD;
163
164
165} BGRClib_P_Data;
166
167/***************************************************************************/
168
169static void BGRClib_p_ClearOptimized(BGRClib_Handle  grclibH)
170{
171    /* Reset all values for optimizing calls into GRC */
172    grclibH->selA = -1;
173    grclibH->selB = -1;
174    grclibH->selC = -1;
175    grclibH->selD = -1;
176    grclibH->srcColor = 0xdeadbeef;
177    grclibH->dstColor = 0xdeadbeef;
178    grclibH->bldColor = 0xdeadbeef;
179    grclibH->outX = grclibH->outY = grclibH->outWidth = grclibH->outHeight = 0xdeadbeef;
180    grclibH->srcX = grclibH->srcY = grclibH->srcWidth = grclibH->srcHeight = 0xdeadbeef;
181    grclibH->dstX = grclibH->dstY = grclibH->dstWidth = grclibH->dstHeight = 0xdeadbeef;
182
183}
184
185/***************************************************************************/
186
187BERR_Code BGRClib_Open( 
188    BGRClib_Handle*  pgrclibHandle,
189    BGRC_Handle      grcHandle
190)
191{
192    BGRClib_Handle grclibH;
193
194    BDBG_ENTER(BGRClib_Open);
195
196    if (!pgrclibHandle || !grcHandle)
197    {
198        BDBG_ERR(("Invalid parameter\n"));
199        BDBG_LEAVE(BGRClib_Open);
200        return BERR_TRACE(BERR_INVALID_PARAMETER);
201    }
202
203    /* Alloc the main GRC context. */
204    grclibH = (BGRClib_Handle)(BKNI_Malloc(sizeof(BGRClib_P_Data)));
205
206    if (!grclibH)
207    {
208        return BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
209    }
210
211    /* Clear out the context and set defaults. */
212    BKNI_Memset(grclibH, 0x0, sizeof(BGRClib_P_Data));
213    BGRClib_p_ClearOptimized(grclibH);
214
215    /* Store the GRC handle */
216    grclibH->hGRC = grcHandle;
217
218    /* All done. now return the new fresh context to user. */
219    *pgrclibHandle = grclibH;
220
221    BDBG_LEAVE(BGRClib_Open);
222    return BERR_SUCCESS;
223}
224
225
226/***************************************************************************/
227void BGRClib_Close( 
228    BGRClib_Handle grclibHandle
229)
230{
231    BDBG_ENTER(BGRClib_Close);
232    GRCLIB_CHECK(grclibHandle);
233
234    /* Release context in system memory */
235    BKNI_Free((void*)grclibHandle);
236
237    BDBG_LEAVE(BGRClib_Close);
238}
239
240/***************************************************************************/
241BERR_Code BGRClib_ResetState( 
242    BGRClib_Handle grclibHandle /* [in] A valid BGRClib_Handle object */
243)
244{
245    BERR_Code err;
246
247    BDBG_ENTER(BGRClib_ResetGRCState);
248    GRCLIB_CHECK(grclibHandle);
249
250    /* Reset the GRC */
251    err = BGRC_ResetState(grclibHandle->hGRC);
252
253    /* Clear all internal state info */
254    BGRClib_p_ClearOptimized(grclibHandle);
255
256    BDBG_LEAVE(BGRClib_ResetGRCState);
257
258    return BERR_TRACE(err);
259}
260
261/***************************************************************************/
262void BGRClib_SetCallback( 
263    BGRClib_Handle grclibHandle,
264    BGRC_Callback  callback_isr,
265    void*          callback_data
266)
267{
268    BDBG_ENTER(BGRClib_SetCallback);
269    GRCLIB_CHECK(grclibHandle);
270
271    grclibHandle->callback_isr  = callback_isr;
272    grclibHandle->callback_data = callback_data;
273
274    BDBG_LEAVE(BGRClib_SetCallback);
275}
276
277
278/*****************************************************************************/
279BERR_Code BGRClib_Fill(
280    BGRClib_Handle          grclibHandle,
281    BSUR_Surface_Handle     surface,
282    uint32_t                constantColor,
283    BGRClib_ColorFmtType    fmtType,
284    const BRect*            pRect,
285    BGRClib_PendType        pendtype
286)
287{
288    BERR_Code   err = BERR_SUCCESS;
289    BGRC_Handle grc;
290    uint32_t    color;
291    uint32_t    x, y, width, height;
292
293    BDBG_ENTER(BGRClib_Fill);
294    GRCLIB_CHECK(grclibHandle);
295    BDBG_ASSERT(surface);
296
297    grc = grclibHandle->hGRC;
298
299    /* Get the rectangle (x, y, width, height) for the surface. */
300    /* This routine handles the case where the rect is NULL */
301    if (err == BERR_SUCCESS)
302        err = BGRClib_p_GetValidPositionInfo(pRect, surface, &x, &y, &width, &height);
303
304    /* Convert the color (if necessary) from the user format (which matches the */
305    /* surface format) to the standard color format (A, C2, C2, C1) which is */
306    /* required by the GRC module and M2MC core */
307    if (err == BERR_SUCCESS)
308        err = BGRClib_p_ConvertColorToStdColor(surface, constantColor, fmtType, &color);
309
310    /* Clear the input (source and destination) surfaces */
311    if (err == BERR_SUCCESS)
312    {
313        err = BGRC_Destination_SetSurface(grc, NULL);
314    }
315
316    if (err == BERR_SUCCESS)
317        {
318        err = BGRC_Source_SetSurface(grc, NULL);
319    }
320
321    /* Set the color in the source. Since the surface is NULl (above) the */
322    /* M2MC will pull the color and alpha data from the value instead */
323    if (err == BERR_SUCCESS && grclibHandle->srcColor != color)
324    {
325        err = BGRC_Source_SetColor(grc, color);
326        grclibHandle->srcColor = color;
327    }
328
329    /* Set the output rectangle and surface */
330    if (err == BERR_SUCCESS &&
331        (grclibHandle->outX != x || grclibHandle->outY != y ||
332         grclibHandle->outWidth != width || grclibHandle->outHeight != height))
333    {
334        err = BGRC_Output_SetRectangle(grc, x, y, width, height);
335        grclibHandle->outX = x;
336        grclibHandle->outY = y;
337        grclibHandle->outWidth  = width;
338        grclibHandle->outHeight = height;
339    }
340
341    if (err == BERR_SUCCESS)
342    {
343        err = BGRC_Output_SetSurface(grc, surface);
344    }
345
346    /* Specify that only the source is desired (the second param) */
347    if (err == BERR_SUCCESS &&
348        (grclibHandle->selA != BGRC_Output_ColorKeySelection_eTakeSource      || 
349         grclibHandle->selB != BGRC_Output_ColorKeySelection_eTakeSource      ||
350         grclibHandle->selC != BGRC_Output_ColorKeySelection_eTakeDestination || 
351         grclibHandle->selD != BGRC_Output_ColorKeySelection_eTakeDestination))
352    {
353        err = BGRC_Output_SetColorKeySelection(grc,
354            BGRC_Output_ColorKeySelection_eTakeSource,
355            BGRC_Output_ColorKeySelection_eTakeSource,
356            BGRC_Output_ColorKeySelection_eTakeDestination,
357            BGRC_Output_ColorKeySelection_eTakeDestination);
358
359        grclibHandle->selA = BGRC_Output_ColorKeySelection_eTakeSource;
360        grclibHandle->selB = BGRC_Output_ColorKeySelection_eTakeSource;
361        grclibHandle->selC = BGRC_Output_ColorKeySelection_eTakeDestination;
362        grclibHandle->selD = BGRC_Output_ColorKeySelection_eTakeDestination;
363    }
364
365    /* Get it going */
366    if (err == BERR_SUCCESS)
367        err = BGRClib_p_Go(grclibHandle, pendtype);
368
369    BDBG_LEAVE(BGRClib_Fill);
370    return BERR_TRACE(err);
371}
372
373
374/*****************************************************************************/
375BERR_Code BGRClib_Copy(
376    BGRClib_Handle          grclibHandle,
377    BSUR_Surface_Handle     srcSurface,
378    const BRect*            pSrcRect,
379    BSUR_Surface_Handle     outSurface,
380    const BRect*            pOutRect,
381    BGRClib_PendType        pendtype
382
383)
384{
385    BERR_Code   err = BERR_SUCCESS;
386    BGRC_Handle grc;
387    uint32_t    xSrc, ySrc, widthSrc, heightSrc;
388    uint32_t    xOut, yOut, widthOut, heightOut;
389    BPXL_Format outFormat;
390    uint32_t    paletteToggled = false;
391
392    BDBG_ENTER(BGRClib_Copy);
393    GRCLIB_CHECK(grclibHandle);
394    BDBG_ASSERT(srcSurface && outSurface);
395
396    grc = grclibHandle->hGRC;
397
398    /* Get the rectangle (x, y, width, height) for the source and output surfaces. */
399    /* This routine handles the case where the rect is NULL */
400    if (err == BERR_SUCCESS)
401        err = BGRClib_p_GetValidPositionInfo(pSrcRect, srcSurface, &xSrc, &ySrc, &widthSrc, &heightSrc);
402
403    if (err == BERR_SUCCESS)
404        err = BGRClib_p_GetValidPositionInfo(pOutRect, outSurface, &xOut, &yOut, &widthOut, &heightOut);
405
406    /* Set the source surface and rectangle */
407    if (err == BERR_SUCCESS)
408    {
409        err = BGRC_Source_SetSurface(grc, srcSurface);
410    }
411
412    if (err == BERR_SUCCESS &&
413       ((grclibHandle->srcX != xSrc || grclibHandle->srcY != ySrc || 
414         grclibHandle->srcWidth != widthSrc || grclibHandle->srcHeight != heightSrc)))
415    {
416        err = BGRC_Source_SetRectangle(grc, xSrc, ySrc, widthSrc, heightSrc);
417        grclibHandle->srcX = xSrc;
418        grclibHandle->srcY = ySrc;
419        grclibHandle->srcWidth  = widthSrc;
420        grclibHandle->srcHeight = heightSrc;
421    }
422
423    /* Clear the destination surface */
424    if (err == BERR_SUCCESS)
425    {
426        err = BGRC_Destination_SetSurface(grc, NULL);
427    }
428
429    /* Set the output surface and rectangle */
430    if (err == BERR_SUCCESS)
431    {
432        err = BGRC_Output_SetSurface(grc, outSurface);
433    }
434
435    if (err == BERR_SUCCESS &&
436        (grclibHandle->outX != xOut || grclibHandle->outY != yOut ||
437         grclibHandle->outWidth != widthOut || grclibHandle->outHeight != heightOut))
438    {
439        err = BGRC_Output_SetRectangle(grc, xOut, yOut, widthOut, heightOut);
440        grclibHandle->outX = xOut;
441        grclibHandle->outY = yOut;
442        grclibHandle->outWidth  = widthOut;
443        grclibHandle->outHeight = heightOut;
444    }
445
446    /* Specify that this is a copy by using _eTakeSource for the second param */
447    if (err == BERR_SUCCESS &&
448        (grclibHandle->selA != BGRC_Output_ColorKeySelection_eTakeSource      || 
449         grclibHandle->selB != BGRC_Output_ColorKeySelection_eTakeSource      ||
450         grclibHandle->selC != BGRC_Output_ColorKeySelection_eTakeDestination || 
451         grclibHandle->selD != BGRC_Output_ColorKeySelection_eTakeDestination))
452    {
453        err = BGRC_Output_SetColorKeySelection(grc,
454            BGRC_Output_ColorKeySelection_eTakeSource,
455            BGRC_Output_ColorKeySelection_eTakeSource,
456            BGRC_Output_ColorKeySelection_eTakeDestination,
457            BGRC_Output_ColorKeySelection_eTakeDestination);
458
459        grclibHandle->selA = BGRC_Output_ColorKeySelection_eTakeSource; 
460        grclibHandle->selB = BGRC_Output_ColorKeySelection_eTakeSource;
461        grclibHandle->selC = BGRC_Output_ColorKeySelection_eTakeDestination;
462        grclibHandle->selD = BGRC_Output_ColorKeySelection_eTakeDestination;
463    }
464
465    /* If the destination a palette surface, then bypass the look-up so we can */
466    /* get the source palette values into the destination. */
467    if (err == BERR_SUCCESS)
468        err = BSUR_Surface_GetFormat(outSurface, &outFormat);
469
470    if (err == BERR_SUCCESS && BPXL_IS_PALETTE_FORMAT(outFormat))
471    {
472        paletteToggled = true;
473        err = BGRC_Source_TogglePaletteBypass(grc, true);
474    }
475
476    if (err == BERR_SUCCESS && BPXL_IS_PALETTE_FORMAT(outFormat))
477        err = BGRC_Destination_TogglePaletteBypass(grc, true);
478
479    /* Start the operation */
480    if (err == BERR_SUCCESS)
481        err = BGRClib_p_Go(grclibHandle, pendtype);
482
483    if (err == BERR_SUCCESS && paletteToggled)
484        err = BGRC_Source_TogglePaletteBypass(grc, false);
485
486    if (err == BERR_SUCCESS && paletteToggled)
487        err = BGRC_Destination_TogglePaletteBypass(grc, false);
488
489    BDBG_LEAVE(BGRClib_Copy);
490    return BERR_TRACE(err);
491} 
492
493
494/*****************************************************************************/
495
496
497static const struct
498{
499    BGRClib_BlendEquation c;
500    BGRClib_BlendEquation a;
501} PDFills[] =
502{
503    {   /* Porter-Duff: Clear           */
504        /* Pc = 0                       */
505        /* Pa = 0                       */
506        { B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) },
507        { B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) }
508    },
509    {   /* Porter-Duff: Src             */
510        /* Pc = Sc                      */
511        /* Pa = Sa                      */
512        { B_BBS(ConstantColor), B_BBS(One), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) },
513        { B_BBS(ConstantAlpha), B_BBS(One), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) }
514    },
515    {   /* Porter-Duff: Dst             */
516        /* Pc = Dc                      */
517        /* Pa = Da                      */
518        { B_BBS(SourceColor), B_BBS(One), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) },
519        { B_BBS(SourceAlpha), B_BBS(One), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) }
520    },
521    {   /* Porter-Duff: SrcOver         */
522        /* Pc = Sc + Dc * (1 - Sa)      */
523        /* Pa = Sa + Da * (1 - Sa)      */
524        { B_BBS(ConstantColor), B_BBS(One), false, B_BBS(SourceColor), B_BBS(InverseConstantAlpha), false, B_BBS(Zero) },
525        { B_BBS(ConstantAlpha), B_BBS(One), false, B_BBS(SourceAlpha), B_BBS(InverseConstantAlpha), false, B_BBS(Zero) }
526    },
527    {   /* Porter-Duff: DstOver         */
528        /* Pc = Sc * (1 - Da) + Dc      */
529        /* Pa = Sa * (1 - Da) + Da      */
530        { B_BBS(ConstantColor), B_BBS(InverseSourceAlpha), false, B_BBS(SourceColor), B_BBS(One), false, B_BBS(Zero) },
531        { B_BBS(ConstantAlpha), B_BBS(InverseSourceAlpha), false, B_BBS(SourceAlpha), B_BBS(One), false, B_BBS(Zero) }
532    },
533    {   /* Porter-Duff: SrcIn           */
534        /* Pc = Sc * Da                 */
535        /* Pa = Sa * Da                 */
536        { B_BBS(ConstantColor), B_BBS(SourceAlpha), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) },
537        { B_BBS(ConstantAlpha), B_BBS(SourceAlpha), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) }
538    },
539    {   /* Porter-Duff: DstIn            */
540        /* Pc = Dc * Sa                  */
541        /* Pa = Da * Sa                  */
542        { B_BBS(SourceColor), B_BBS(ConstantAlpha), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) },
543        { B_BBS(SourceAlpha), B_BBS(ConstantAlpha), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) }
544    },
545    {   /* Porter-Duff: SrcOut           */
546        /* Pc = Sc * (1 - Da)            */
547        /* Pa = Sa * (1 - Da)            */
548        { B_BBS(ConstantColor), B_BBS(InverseSourceAlpha), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) },
549        { B_BBS(ConstantAlpha), B_BBS(InverseSourceAlpha), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) }
550    },
551    {   /* Porter-Duff: DstOut            */
552        /* Pc = Dc * (1 - Sa)             */
553        /* Pa = Da * (1 - Sa)             */
554        { B_BBS(SourceColor), B_BBS(InverseConstantAlpha), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) },
555        { B_BBS(SourceAlpha), B_BBS(InverseConstantAlpha), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) }
556    },
557    {   /* Porter-Duff: SrcAtop           */
558        /* Pc = Sc * Da + Dc * (1 - Sa)   */
559        /* Pa = Da                        */
560        { B_BBS(ConstantColor), B_BBS(SourceAlpha), false, B_BBS(SourceColor), B_BBS(InverseConstantAlpha), false, B_BBS(Zero) },
561        { B_BBS(SourceAlpha),   B_BBS(One),         false, B_BBS(Zero),        B_BBS(Zero),                 false, B_BBS(Zero) }
562    },
563    {   /* Porter-Duff: DstAtop           */
564        /* Pc = Sc * (1 - Da) + Dc * Sa   */
565        /* Pa = Sa                        */
566        { B_BBS(ConstantColor), B_BBS(InverseSourceAlpha), false, B_BBS(SourceColor), B_BBS(ConstantAlpha), false, B_BBS(Zero) },
567        { B_BBS(ConstantAlpha), B_BBS(One),                false, B_BBS(Zero),        B_BBS(Zero),          false, B_BBS(Zero) }
568    },
569    {   /* Porter-Duff: Xor                   */
570        /* Pc = Sc * (1 - Da) + Dc * (1 - Sa) */
571        /* Pa = Sa * (1 - Da) + Da * (1 - Sa) */
572        { B_BBS(ConstantColor), B_BBS(InverseSourceAlpha), false, B_BBS(SourceColor), B_BBS(InverseConstantAlpha), false, B_BBS(Zero) },
573        { B_BBS(ConstantAlpha), B_BBS(InverseSourceAlpha), false, B_BBS(SourceAlpha), B_BBS(InverseConstantAlpha), false, B_BBS(Zero) }
574    }
575};
576
577
578/*****************************************************************************/
579static BERR_Code BGRClib_p_Blended_Fill(
580    BGRClib_Handle          grclibHandle,
581    BSUR_Surface_Handle     surface,
582    uint32_t                constantColor,
583    BGRClib_ColorFmtType    fmtType,
584    const BRect*            pRect
585)
586{
587    BERR_Code   err = BERR_SUCCESS;
588    BGRC_Handle grc;
589    uint32_t    color;
590    uint32_t    x, y, width, height;
591
592    grc = grclibHandle->hGRC;
593
594    /* Get the rectangle (x, y, width, height) for the surface. */
595    /* This routine handles the case where the rect is NULL */
596    if (err == BERR_SUCCESS)
597        err = BGRClib_p_GetValidPositionInfo(pRect, surface, &x, &y, &width, &height);
598
599    /* Convert the color (if necessary) from the user format (which matches the */
600    /* surface format) to the standard color format (A, C2, C2, C1) which is */
601    /* required by the GRC module and M2MC core */
602    if (err == BERR_SUCCESS)
603        err = BGRClib_p_ConvertColorToStdColor(surface, constantColor, fmtType, &color);
604
605    /* Clear the destination surface */
606    if (err == BERR_SUCCESS)
607    {
608        err = BGRC_Destination_SetSurface(grc, NULL);
609    }
610
611    /* Set the Source info. Note that we are setting the surface */
612    if (err == BERR_SUCCESS)
613    {
614        err = BGRC_Source_SetSurface(grc, surface);
615    }
616
617    if (err == BERR_SUCCESS && grclibHandle->srcColor != color) 
618    {
619        err = BGRC_Source_SetColor(grc, color);
620        grclibHandle->srcColor = color;
621    }
622
623    if (err == BERR_SUCCESS &&
624        (grclibHandle->srcX != x || grclibHandle->srcY != y || 
625         grclibHandle->srcWidth != width || grclibHandle->srcHeight != height))
626    {
627        err = BGRC_Source_SetRectangle(grc, x, y, width, height);
628        grclibHandle->srcX = x;
629        grclibHandle->srcY = y;
630        grclibHandle->srcWidth  = width;
631        grclibHandle->srcHeight = height;
632    }
633       
634    /* Set the Blend color */
635    if (err == BERR_SUCCESS && grclibHandle->bldColor != color)
636    {
637        err = BGRC_Blend_SetColor(grc, color);
638        grclibHandle->bldColor = color;
639    }
640
641    /* Set the output */
642    if (err == BERR_SUCCESS &&
643        (grclibHandle->outX != x || grclibHandle->outY != y ||
644         grclibHandle->outWidth != width || grclibHandle->outHeight != height))
645    {
646        err = BGRC_Output_SetRectangle(grc, x, y, width, height);
647        grclibHandle->outX = x;
648        grclibHandle->outY = y;
649        grclibHandle->outWidth  = width;
650        grclibHandle->outHeight = height;
651    }
652
653    if (err == BERR_SUCCESS)
654    {
655        err = BGRC_Output_SetSurface(grc, surface);
656    }
657
658    /* Specify that only the source is desired (the second param) */
659    if (err == BERR_SUCCESS &&
660        (grclibHandle->selA != BGRC_Output_ColorKeySelection_eTakeBlend       ||
661         grclibHandle->selB != BGRC_Output_ColorKeySelection_eTakeSource      ||
662         grclibHandle->selC != BGRC_Output_ColorKeySelection_eTakeDestination || 
663         grclibHandle->selD != BGRC_Output_ColorKeySelection_eTakeDestination))
664    {
665        err = BGRC_Output_SetColorKeySelection(grc,
666            BGRC_Output_ColorKeySelection_eTakeBlend, /* <--- Takes color from blend block */
667            BGRC_Output_ColorKeySelection_eTakeSource,
668            BGRC_Output_ColorKeySelection_eTakeDestination,
669            BGRC_Output_ColorKeySelection_eTakeDestination);
670
671        grclibHandle->selA = BGRC_Output_ColorKeySelection_eTakeBlend;
672        grclibHandle->selB = BGRC_Output_ColorKeySelection_eTakeSource;
673        grclibHandle->selC = BGRC_Output_ColorKeySelection_eTakeDestination;
674        grclibHandle->selD = BGRC_Output_ColorKeySelection_eTakeDestination;
675    }
676
677    return BERR_TRACE(err);
678}
679
680/*****************************************************************************/
681BERR_Code BGRClib_Blended_Fill(
682    BGRClib_Handle          grclibHandle,
683    BSUR_Surface_Handle     surface,
684    uint32_t                constantColor,
685    BGRClib_ColorFmtType    fmtType,
686    const BRect*            pRect,
687    BGRCLib_FillOp          colorOp,
688    BGRCLib_FillOp          alphaOp,
689    BGRClib_PendType        pendtype
690)
691{
692    BERR_Code   err;
693    BGRC_Handle grc;
694
695    BDBG_ENTER(BGRClib_Blended_Fill);
696    GRCLIB_CHECK(grclibHandle);
697    BDBG_ASSERT(surface);
698
699    err = BGRClib_p_Blended_Fill(grclibHandle, surface, constantColor, fmtType, pRect);
700    grc = grclibHandle->hGRC;
701
702    /* Set the COLOR blend equation depending on the operation requested */
703    if (err != BERR_SUCCESS)
704        ;
705    else if (colorOp == BGRCLib_FillOp_eIgnore)
706    {
707        err = BGRC_Blend_SetColorBlend(grc,
708                   BGRC_Blend_Source_eSourceColor, BGRC_Blend_Source_eOne,
709                   false, BGRC_Blend_Source_eZero, BGRC_Blend_Source_eZero,
710                   false, BGRC_Blend_Source_eZero);
711    }
712    else if (colorOp == BGRCLib_FillOp_eCopy)
713    {
714        err = BGRC_Blend_SetColorBlend(grc,
715                   BGRC_Blend_Source_eConstantColor, BGRC_Blend_Source_eOne,
716                   false, BGRC_Blend_Source_eZero, BGRC_Blend_Source_eZero,
717                   false, BGRC_Blend_Source_eZero);
718    }
719    else if (colorOp == BGRCLib_FillOp_eBlend)
720    {
721        err = BGRC_Blend_SetColorBlend(grc,
722                   BGRC_Blend_Source_eConstantColor, BGRC_Blend_Source_eConstantAlpha,
723                   false, BGRC_Blend_Source_eSourceColor, BGRC_Blend_Source_eInverseConstantAlpha,
724                   false, BGRC_Blend_Source_eZero);
725    }
726    else
727    {
728        BDBG_ASSERT(false);
729        err = BERR_INVALID_PARAMETER;
730    }
731
732    /* Set the ALPHA blend equation depending on the operation requested */
733    if (err != BERR_SUCCESS)
734        ;
735    else if (alphaOp == BGRCLib_FillOp_eIgnore)
736    {
737        err = BGRC_Blend_SetAlphaBlend(grc,
738                   BGRC_Blend_Source_eSourceAlpha, BGRC_Blend_Source_eOne,
739                   false, BGRC_Blend_Source_eZero, BGRC_Blend_Source_eZero,
740                   false, BGRC_Blend_Source_eZero);
741    }
742    else if (alphaOp == BGRCLib_FillOp_eCopy)
743    {
744        err = BGRC_Blend_SetAlphaBlend(grc,
745                   BGRC_Blend_Source_eConstantAlpha, BGRC_Blend_Source_eOne,
746                   false,  BGRC_Blend_Source_eZero,  BGRC_Blend_Source_eZero,
747                   false,  BGRC_Blend_Source_eZero);
748    }
749    else if (alphaOp == BGRCLib_FillOp_eBlend)
750    {
751        err = BGRC_Blend_SetAlphaBlend(grc,
752                   BGRC_Blend_Source_eSourceAlpha, BGRC_Blend_Source_eInverseConstantAlpha,
753                   false, BGRC_Blend_Source_eConstantAlpha, BGRC_Blend_Source_eOne,
754                   false, BGRC_Blend_Source_eZero);
755    }
756    else
757    {
758        BDBG_ASSERT(false);
759        err = BERR_INVALID_PARAMETER;
760    }
761
762    /* Start the operation */
763    if (err == BERR_SUCCESS)
764        err = BGRClib_p_Go(grclibHandle, pendtype);
765
766    BDBG_LEAVE(BGRClib_Blended_Fill);
767    return BERR_TRACE(err);
768}
769
770/*****************************************************************************/
771BERR_Code BGRClib_PorterDuffFill(
772    BGRClib_Handle          grclibHandle,
773    BGRCLib_PorterDuffOp    pdOp,
774    BSUR_Surface_Handle     surface,
775    uint32_t                constantColor,
776    BGRClib_ColorFmtType    fmtType,
777    const BRect*            pRect,
778    BGRClib_PendType        pendtype
779)
780{
781    BERR_Code   err;
782    BGRC_Handle grc;
783
784    BDBG_ENTER(BGRClib_PorterDuffFill);
785    GRCLIB_CHECK(grclibHandle);
786    BDBG_ASSERT(surface);
787
788    err = BGRClib_p_Blended_Fill(grclibHandle, surface, constantColor, fmtType, pRect);
789    grc = grclibHandle->hGRC;
790
791    /* Set the COLOR blend equation depending on the operation requested */
792    /* See the table above with the equations */
793    if (err == BERR_SUCCESS)
794        err = BGRC_Blend_SetColorBlend(grc,
795           PDFills[pdOp].c.a, 
796           PDFills[pdOp].c.b, 
797           PDFills[pdOp].c.subcd, 
798           PDFills[pdOp].c.c, 
799           PDFills[pdOp].c.d, 
800           PDFills[pdOp].c.sube, 
801           PDFills[pdOp].c.e);
802
803    if (err == BERR_SUCCESS)
804        err = BGRC_Blend_SetAlphaBlend(grc,
805           PDFills[pdOp].a.a, 
806           PDFills[pdOp].a.b, 
807           PDFills[pdOp].a.subcd, 
808           PDFills[pdOp].a.c, 
809           PDFills[pdOp].a.d, 
810           PDFills[pdOp].a.sube, 
811           PDFills[pdOp].a.e);
812
813    /* Start the operation */
814    if (err == BERR_SUCCESS)
815        err = BGRClib_p_Go(grclibHandle, pendtype);
816
817    BDBG_LEAVE(BGRClib_PorterDuffFill);
818    return BERR_TRACE(err);
819}
820
821
822/*****************************************************************************/
823
824
825static const struct
826{
827    BGRClib_BlendEquation c;
828    BGRClib_BlendEquation a;
829} PDBlends[] =
830{
831    {   /* Porter-Duff: Clear           */
832        /* Pc = 0                       */
833        /* Pa = 0                       */
834        { B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) },
835        { B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) }
836    },
837    {   /* Porter-Duff: Src             */
838        /* Pc = Sc                      */
839        /* Pa = Sa                      */
840        { B_BBS(SourceColor), B_BBS(One), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) },
841        { B_BBS(SourceAlpha), B_BBS(One), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) }
842    },
843    {   /* Porter-Duff: Dst             */
844        /* Pc = Dc                      */
845        /* Pa = Da                      */
846        { B_BBS(DestinationColor), B_BBS(One), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) },
847        { B_BBS(DestinationAlpha), B_BBS(One), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) }
848    },
849    {   /* Porter-Duff: SrcOver         */
850        /* Pc = Sc + Dc * (1 - Sa)      */
851        /* Pa = Sa + Da * (1 - Sa)      */
852        { B_BBS(SourceColor), B_BBS(One), false, B_BBS(DestinationColor), B_BBS(InverseSourceAlpha), false, B_BBS(Zero) },
853        { B_BBS(SourceAlpha), B_BBS(One), false, B_BBS(DestinationAlpha), B_BBS(InverseSourceAlpha), false, B_BBS(Zero) }
854    },
855    {   /* Porter-Duff: DstOver         */
856        /* Pc = Sc * (1 - Da) + Dc      */
857        /* Pa = Sa * (1 - Da) + Da      */
858        { B_BBS(SourceColor), B_BBS(InverseDestinationAlpha), false, B_BBS(DestinationColor), B_BBS(One), false, B_BBS(Zero) },
859        { B_BBS(SourceAlpha), B_BBS(InverseDestinationAlpha), false, B_BBS(DestinationAlpha), B_BBS(One), false, B_BBS(Zero) }
860    },
861    {   /* Porter-Duff: SrcIn           */
862        /* Pc = Sc * Da                 */
863        /* Pa = Sa * Da                 */
864        { B_BBS(SourceColor), B_BBS(DestinationAlpha), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) },
865        { B_BBS(SourceAlpha), B_BBS(DestinationAlpha), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) }
866    },
867    {   /* Porter-Duff: DstIn            */
868        /* Pc = Dc * Sa                  */
869        /* Pa = Da * Sa                  */
870        { B_BBS(DestinationColor), B_BBS(SourceAlpha), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) },
871        { B_BBS(DestinationAlpha), B_BBS(SourceAlpha), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) }
872    },
873    {   /* Porter-Duff: SrcOut           */
874        /* Pc = Sc * (1 - Da)            */
875        /* Pa = Sa * (1 - Da)            */
876        { B_BBS(SourceColor), B_BBS(InverseDestinationAlpha), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) },
877        { B_BBS(SourceAlpha), B_BBS(InverseDestinationAlpha), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) }
878    },
879    {   /* Porter-Duff: DstOut            */
880        /* Pc = Dc * (1 - Sa)             */
881        /* Pa = Da * (1 - Sa)             */
882        { B_BBS(DestinationColor), B_BBS(InverseSourceAlpha), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) },
883        { B_BBS(DestinationAlpha), B_BBS(InverseSourceAlpha), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) }
884    },
885    {   /* Porter-Duff: SrcAtop           */
886        /* Pc = Sc * Da + Dc * (1 - Sa)   */
887        /* Pa = Da                        */
888        { B_BBS(SourceColor), B_BBS(DestinationAlpha), false, B_BBS(DestinationColor), B_BBS(InverseSourceAlpha), false, B_BBS(Zero) },
889        { B_BBS(DestinationAlpha), B_BBS(One), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) }
890    },
891    {   /* Porter-Duff: DstAtop           */
892        /* Pc = Sc * (1 - Da) + Dc * Sa   */
893        /* Pa = Sa                        */
894        { B_BBS(SourceColor), B_BBS(InverseDestinationAlpha), false, B_BBS(DestinationColor), B_BBS(SourceAlpha), false, B_BBS(Zero) },
895        { B_BBS(SourceAlpha), B_BBS(One), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero) }
896    },
897    {   /* Porter-Duff: Xor                   */
898        /* Pc = Sc * (1 - Da) + Dc * (1 - Sa) */
899        /* Pa = Sa * (1 - Da) + Da * (1 - Sa) */
900        { B_BBS(SourceColor), B_BBS(InverseDestinationAlpha), false, B_BBS(DestinationColor), B_BBS(InverseSourceAlpha), false, B_BBS(Zero) },
901        { B_BBS(SourceAlpha), B_BBS(InverseDestinationAlpha), false, B_BBS(DestinationAlpha), B_BBS(InverseSourceAlpha), false, B_BBS(Zero) }
902    }
903};
904
905
906
907/***************************************************************************/
908BERR_Code BGRClib_PorterDuffBlit(
909    BGRClib_Handle          grclibHandle,
910    BGRCLib_PorterDuffOp    pdOp,
911    BSUR_Surface_Handle     srcSurface,
912    const BRect*            pSrcRect,
913    BSUR_Surface_Handle     dstSurface,
914    const BRect*            pDstRect,
915    BSUR_Surface_Handle     outSurface,
916    const BRect*            pOutRect,
917    BGRClib_PendType        pendtype
918
919)
920{
921    BERR_Code   err = BERR_SUCCESS;
922    BGRC_Handle grc;
923    uint32_t    xSrc, ySrc, widthSrc, heightSrc;
924    uint32_t    xDst, yDst, widthDst, heightDst;
925    uint32_t    xOut, yOut, widthOut, heightOut;
926    BPXL_Format outFormat;
927    uint32_t    paletteToggled = false;
928
929    BDBG_ENTER(BGRClib_PorterDuffBlit);
930    GRCLIB_CHECK(grclibHandle);
931    BDBG_ASSERT(pdOp < BGRCLib_PorterDuffOp_Count);
932    grc = grclibHandle->hGRC;
933
934    /* This is caught in debug build by assert, so catch error in release build */
935    if (pdOp >= BGRCLib_PorterDuffOp_Count)
936        err = BERR_INVALID_PARAMETER;
937
938    /* Get the rectangle (x, y, width, height) for the source and output surfaces. */
939    /* This routine handles the case where the rect is NULL */
940    if (err == BERR_SUCCESS)
941        err = BGRClib_p_GetValidPositionInfo(pSrcRect, srcSurface, &xSrc, &ySrc, &widthSrc, &heightSrc);
942
943    if (err == BERR_SUCCESS)
944        err = BGRClib_p_GetValidPositionInfo(pDstRect, dstSurface, &xDst, &yDst, &widthDst, &heightDst);
945
946    if (err == BERR_SUCCESS)
947        err = BGRClib_p_GetValidPositionInfo(pOutRect, outSurface, &xOut, &yOut, &widthOut, &heightOut);
948
949    /* Set the source surface and rectangle */
950    if (err == BERR_SUCCESS)
951    {
952        err = BGRC_Source_SetSurface(grc, srcSurface);
953    }
954
955    if (err == BERR_SUCCESS &&
956        (grclibHandle->srcX != xSrc || grclibHandle->srcY != ySrc || 
957         grclibHandle->srcWidth != widthSrc || grclibHandle->srcHeight != heightSrc))
958    {
959        err = BGRC_Source_SetRectangle(grc, xSrc, ySrc, widthSrc, heightSrc);
960        grclibHandle->srcX = xSrc;
961        grclibHandle->srcY = ySrc;
962        grclibHandle->srcWidth  = widthSrc;
963        grclibHandle->srcHeight = heightSrc;
964    }
965
966    /* Set the destination surface and rectangle */
967    if (err == BERR_SUCCESS)
968    {
969        err = BGRC_Destination_SetSurface(grc, dstSurface);
970    }
971
972    if (err == BERR_SUCCESS &&
973        (grclibHandle->dstX != xDst || grclibHandle->dstY != yDst || 
974         grclibHandle->dstWidth != widthDst || grclibHandle->dstHeight != heightDst))
975    {
976        err = BGRC_Destination_SetRectangle(grc, xDst, yDst, widthDst, heightDst);
977        grclibHandle->dstX = xDst;
978        grclibHandle->dstY = yDst;
979        grclibHandle->dstWidth  = widthDst;
980        grclibHandle->dstHeight = heightDst;
981    }
982
983    /* Set the output surface and rectangle */
984    if (err == BERR_SUCCESS)
985    {
986        err = BGRC_Output_SetSurface(grc, outSurface);
987    }
988
989    if (err == BERR_SUCCESS &&
990        (grclibHandle->outX != xOut || grclibHandle->outY != yOut || 
991         grclibHandle->outWidth != widthOut || grclibHandle->outHeight != heightOut))
992    {
993        err = BGRC_Output_SetRectangle(grc, xOut, yOut, widthOut, heightOut);
994        grclibHandle->outX = xOut;
995        grclibHandle->outY = yOut;
996        grclibHandle->outWidth  = widthOut;
997        grclibHandle->outHeight = heightOut;
998    }
999
1000    /* If the output a palette surface, then bypass the look-up so we can */
1001    /* get the source palette values into the output. */
1002    if (err == BERR_SUCCESS)
1003        err = BSUR_Surface_GetFormat(outSurface, &outFormat);
1004
1005    if (err == BERR_SUCCESS && BPXL_IS_PALETTE_FORMAT(outFormat))
1006    {
1007        err = BGRC_Source_TogglePaletteBypass(grc, true);
1008        paletteToggled = true;
1009    }
1010
1011    if (err == BERR_SUCCESS && BPXL_IS_PALETTE_FORMAT(outFormat))
1012        err = BGRC_Destination_TogglePaletteBypass(grc, true);
1013
1014    /* Specify that this is a blend by using _eTakeBlend for the second param */
1015    if (err == BERR_SUCCESS &&
1016        (grclibHandle->selA != BGRC_Output_ColorKeySelection_eTakeBlend       || 
1017         grclibHandle->selB != BGRC_Output_ColorKeySelection_eTakeSource      ||
1018         grclibHandle->selC != BGRC_Output_ColorKeySelection_eTakeDestination || 
1019         grclibHandle->selD != BGRC_Output_ColorKeySelection_eTakeDestination))
1020    {
1021        err = BGRC_Output_SetColorKeySelection(grc,
1022            BGRC_Output_ColorKeySelection_eTakeBlend,
1023            BGRC_Output_ColorKeySelection_eTakeSource,
1024            BGRC_Output_ColorKeySelection_eTakeDestination,
1025            BGRC_Output_ColorKeySelection_eTakeDestination);
1026
1027        grclibHandle->selA = BGRC_Output_ColorKeySelection_eTakeBlend;
1028        grclibHandle->selB = BGRC_Output_ColorKeySelection_eTakeSource;
1029        grclibHandle->selC = BGRC_Output_ColorKeySelection_eTakeDestination;
1030        grclibHandle->selD = BGRC_Output_ColorKeySelection_eTakeDestination;
1031    }
1032
1033    /* Set the COLOR blend equation depending on the operation requested */
1034    /* See the table above with the equations */
1035    if (err == BERR_SUCCESS)
1036        err = BGRC_Blend_SetColorBlend(grc,
1037           PDBlends[pdOp].c.a, 
1038           PDBlends[pdOp].c.b, 
1039           PDBlends[pdOp].c.subcd, 
1040           PDBlends[pdOp].c.c, 
1041           PDBlends[pdOp].c.d, 
1042           PDBlends[pdOp].c.sube, 
1043           PDBlends[pdOp].c.e);
1044
1045    if (err == BERR_SUCCESS)
1046        err = BGRC_Blend_SetAlphaBlend(grc,
1047           PDBlends[pdOp].a.a, 
1048           PDBlends[pdOp].a.b, 
1049           PDBlends[pdOp].a.subcd, 
1050           PDBlends[pdOp].a.c, 
1051           PDBlends[pdOp].a.d, 
1052           PDBlends[pdOp].a.sube, 
1053           PDBlends[pdOp].a.e);
1054
1055    /* Start the operation */
1056    if (err == BERR_SUCCESS)
1057        err = BGRClib_p_Go(grclibHandle, pendtype);
1058
1059    if (err == BERR_SUCCESS && paletteToggled)
1060        err = BGRC_Source_TogglePaletteBypass(grc, false);
1061
1062    if (err == BERR_SUCCESS && paletteToggled)
1063        err = BGRC_Destination_TogglePaletteBypass(grc, false);
1064
1065    BDBG_LEAVE(BGRClib_PorterDuffBlit);
1066    return BERR_TRACE(err);;
1067} 
1068
1069
1070/*****************************************************************************/
1071void BGRClib_GetDefaultBlitParams(
1072    BGRClib_BlitParams *params
1073)
1074{
1075    BDBG_ENTER(BGRClib_GetDefaultBlitParams);
1076    BDBG_ASSERT(params);
1077
1078    BKNI_Memset(params, 0, sizeof(BGRClib_BlitParams));
1079
1080    params->colorOp = BGRCLib_BlitColorOp_eCopySource;
1081    params->alphaOp = BGRCLib_BlitAlphaOp_eCopySource;
1082
1083
1084    params->horzFilter = BGRC_FilterCoeffs_eAnisotropic;
1085    params->vertFilter = BGRC_FilterCoeffs_eAnisotropic;
1086
1087    params->colorKeySelect = BGRC_Output_ColorKeySelection_eTakeBlend;
1088
1089    /* Use the same defaults at the GRC module */
1090    params->constantColor = 0xFF000000;
1091    params->destContColor = 0xFF000000;
1092
1093    BDBG_LEAVE(BGRClib_GetDefaultBlitParams);
1094}
1095
1096/*****************************************************************************/
1097void BGRClib_GetDefaultPaletteBlitParams(
1098    BGRClib_BlitParams *params
1099)
1100{
1101    BDBG_ENTER(BGRClib_GetDefaultPaletteBlitParams);
1102
1103    /* First, use the overall defaults */
1104    BGRClib_GetDefaultBlitParams(params);
1105
1106    /* Use the Point Sample filter */
1107    params->horzFilter = BGRC_FilterCoeffs_ePointSample;
1108    params->vertFilter = BGRC_FilterCoeffs_ePointSample;
1109
1110    /* Use the source surface */
1111    params->colorKeySelect = BGRC_Output_ColorKeySelection_eTakeSource;
1112
1113    BDBG_LEAVE(BGRClib_GetDefaultBlitParams);
1114}
1115
1116/*****************************************************************************/
1117void BGRClib_GetDefaultColorKeyParams(
1118    BGRClib_BlitColorKeyParams *colorkeyparams
1119)
1120{
1121    BDBG_ENTER(BGRClib_GetDefaultColorKeyParams);
1122    BDBG_ASSERT(colorkeyparams);
1123
1124    BKNI_Memset(colorkeyparams, 0, sizeof(BGRClib_BlitColorKeyParams));
1125
1126    colorkeyparams->cksOnlySrcColorKeyed    = BGRC_Output_ColorKeySelection_eTakeDestination;
1127    colorkeyparams->cksOnlyDstColorKeyed    = BGRC_Output_ColorKeySelection_eTakeSource;
1128    colorkeyparams->cksBothSrcDstColorKeyed = BGRC_Output_ColorKeySelection_eTakeDestination;
1129
1130    BDBG_LEAVE(BGRClib_GetDefaultColorKeyParams);
1131}
1132
1133
1134/*****************************************************************************/
1135void BGRClib_GetDefaultScalingControlParams(
1136    BGRClib_BlitScalingControlParams *scalingparams
1137)
1138{
1139    BDBG_ENTER(BGRClib_GetDefaultScalingControlParams);
1140    BDBG_ASSERT(scalingparams);
1141
1142    BKNI_Memset(scalingparams, 0, sizeof(BGRClib_BlitScalingControlParams));
1143
1144    scalingparams->setFilterPhaseAdj = false;
1145
1146    scalingparams->setFixedScaleFactor = false;
1147    scalingparams->ulHorizontalNumerator = 1;
1148    scalingparams->ulHorizontalDenominator = 1;
1149    scalingparams->ulVerticalNumerator = 1;
1150    scalingparams->ulVerticalDenominator = 1;
1151
1152    BDBG_LEAVE(BGRClib_GetDefaultScalingControlParams);
1153}
1154
1155/*****************************************************************************/
1156
1157
1158static const BGRClib_BlendEquation BlitColorBlends[] =
1159{
1160    {   /* _eCopySource: Pc = Sc */
1161        B_BBS(SourceColor), B_BBS(One), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero)
1162    },
1163    {   /* _eUseConstantAlpha: Pc = Sc * Ca + Dc * (1 - Ca) */
1164        B_BBS(SourceColor), B_BBS(ConstantAlpha), false, B_BBS(DestinationColor), B_BBS(InverseConstantAlpha), false, B_BBS(Zero)
1165    },
1166    {   /* _eUseSourceAlpha: Pc = Sc * Sa + Dc * (1 - Sa) */
1167        B_BBS(SourceColor), B_BBS(SourceAlpha), false, B_BBS(DestinationColor), B_BBS(InverseSourceAlpha), false, B_BBS(Zero)
1168    },
1169    {   /* _eUseDestAlpha: Pc = Sc * Da + Dc * (1 - Da) */
1170        B_BBS(SourceColor), B_BBS(DestinationAlpha), false, B_BBS(DestinationColor), B_BBS(InverseDestinationAlpha), false, B_BBS(Zero)
1171    },
1172    {   /* _eSelectPaletteWithColorkey: Pc = Sc */
1173        B_BBS(SourceColor), B_BBS(One), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero)
1174    },
1175    {   /* _eModulate:  (Deprecated) */
1176        B_BBS(SourceColor), B_BBS(SourceAlpha), false, B_BBS(DestinationColor), B_BBS(InverseSourceAlpha), false, B_BBS(Zero)
1177    },
1178    {   /* _eAdd:  Pc = Sc + Dc */
1179        B_BBS(SourceColor), B_BBS(One), false, B_BBS(DestinationColor), B_BBS(One), false, B_BBS(Zero)
1180    },
1181    {   /* _eUseBlendFactors: Never used. This entry exists so that the enum list matches the size of this array */
1182        B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero)
1183    }
1184};
1185
1186
1187
1188static const BGRClib_BlendEquation BlitAlphaBlends[] =
1189{
1190    {   /* _eCopySource: Pa = Sa */
1191        B_BBS(SourceAlpha), B_BBS(One), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero)
1192    },
1193    {   /* _eUseConstAlpha: Pa = Ca */
1194        B_BBS(ConstantAlpha), B_BBS(One), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero)
1195    },
1196    {   /* _eUseSourceAlpha: Pa = Sa */
1197        B_BBS(SourceAlpha), B_BBS(One), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero)
1198    },
1199    {   /* _eUseDestAlpha: Pa = Da */
1200        B_BBS(DestinationAlpha), B_BBS(One), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero)
1201    },
1202    {   /* _eUseCombinedAlpha: Pa = Sa + Da*(1-Sa) */
1203        B_BBS(SourceAlpha), B_BBS(One), false, B_BBS(InverseSourceAlpha), B_BBS(DestinationAlpha), false, B_BBS(Zero)
1204    },
1205    {   /* _eEmulateTransparentVideo: */
1206        B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero)
1207    },
1208    {   /* _eModulate: (Deprecated) */
1209        B_BBS(SourceAlpha), B_BBS(One), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero)
1210    },
1211    {   /* _eAdd: Pa = Sa + Da */
1212        B_BBS(SourceAlpha), B_BBS(One), false, B_BBS(DestinationAlpha), B_BBS(One), false, B_BBS(Zero)
1213    },
1214    {   /* _eUseBlendFactors: Never used. This entry exists so that the enum list matches the size of this array */
1215        B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero), B_BBS(Zero), false, B_BBS(Zero)
1216    }
1217};
1218
1219/*****************************************************************************/
1220BERR_Code BGRClib_GetColorBlendFactors(
1221    BGRCLib_BlitColorOp colorOp, 
1222    BGRClib_BlendEquation* factors)
1223{
1224    BERR_Code err = BERR_SUCCESS;
1225
1226    BDBG_ASSERT(factors != NULL);
1227    BDBG_ASSERT(colorOp < BGRCLib_BlitColorOp_Count);
1228
1229    if (colorOp < BGRCLib_BlitColorOp_Count && colorOp != BGRCLib_BlitColorOp_eUseBlendFactors && factors != NULL)
1230        *factors = BlitColorBlends[colorOp];
1231    else
1232        err = BERR_INVALID_PARAMETER;
1233
1234    return err;
1235}
1236
1237
1238/*****************************************************************************/
1239BERR_Code BGRClib_GetAlphaBlendFactors(
1240    BGRCLib_BlitAlphaOp alphaOp, 
1241    BGRClib_BlendEquation* factors)
1242{
1243    BERR_Code err = BERR_SUCCESS;
1244
1245    BDBG_ASSERT(factors != NULL);
1246    BDBG_ASSERT(alphaOp < BGRCLib_BlitAlphaOp_Count);
1247
1248    if (alphaOp < BGRCLib_BlitAlphaOp_Count && alphaOp != BGRCLib_BlitAlphaOp_eUseBlendFactors && factors != NULL)
1249        *factors = BlitAlphaBlends[alphaOp];
1250    else
1251        err = BERR_INVALID_PARAMETER;
1252
1253    return err;
1254}
1255
1256/*****************************************************************************/
1257BERR_Code BGRClib_GetPorterDuffBlendFactors(
1258    BGRCLib_PorterDuffOp pdOp, 
1259    BGRClib_BlendEquation* colorFactors, 
1260    BGRClib_BlendEquation* alphaFactors)
1261{
1262    BERR_Code err = BERR_SUCCESS;
1263
1264    BDBG_ASSERT(colorFactors != NULL && alphaFactors != NULL);
1265    BDBG_ASSERT(pdOp < BGRCLib_PorterDuffOp_Count);
1266
1267    if (pdOp < BGRCLib_PorterDuffOp_Count && colorFactors != NULL && alphaFactors != NULL)
1268    {
1269        *colorFactors = PDBlends[pdOp].c;
1270        *alphaFactors = PDBlends[pdOp].a;
1271    }
1272    else
1273        err = BERR_INVALID_PARAMETER;
1274
1275    return err;
1276}
1277
1278/***************************************************************************/
1279#define BMAX(a, b) ((a<b)?b:a)
1280#define BGRCLIB_IS_BLURRY_FILTER(_f_)               \
1281    (_f_ == BGRC_FilterCoeffs_eBlurry            || \
1282     _f_ == BGRC_FilterCoeffs_eAntiFlutterBlurry || \
1283     _f_ == BGRC_FilterCoeffs_eAntiFlutter       || \
1284     _f_ == BGRC_FilterCoeffs_eAntiFlutterSharp)
1285     
1286/***************************************************************************/
1287BERR_Code BGRClib_Blit(
1288    BGRClib_Handle                    grclibHandle,
1289    const BGRClib_BlitParams*         params,
1290    const BGRClib_BlitColorKeyParams* colorkeyParams,
1291    const BGRClib_BlitMatrixParams*   matrixParams,
1292    const BGRClib_BlitPatternParams*  patternParams,
1293    const BGRClib_BlitScalingControlParams* scalingParams,
1294    BGRClib_PendType                  pendtype
1295)
1296{
1297    BERR_Code   err = BERR_SUCCESS;
1298    BGRC_Handle grc;
1299    uint32_t    xSrc, ySrc, widthSrc, heightSrc;
1300    uint32_t    xDst, yDst, widthDst, heightDst;
1301    uint32_t    xOut, yOut, widthOut, heightOut;
1302    BPXL_Format outFormat;
1303    uint32_t    maxCnt, index;
1304    uint32_t    x, y, w, h;
1305    uint32_t    count;
1306    uint32_t    matrixToggled   = false;
1307    uint32_t    colorkeyToggled = false;
1308    uint32_t    paletteToggled  = false;
1309    uint32_t    filterToggled   = false;
1310    uint32_t    scalingToggled  = false;
1311    uint32_t    patternToggled  = false;
1312
1313    const BRect*        pRect;
1314    BSUR_Surface_Handle surf;
1315    BSUR_Surface_Handle srcSurf, dstSurf,  outSurf;
1316    BGRClib_BlendEquation       colorBlend;
1317    BGRClib_BlendEquation       alphaBlend;
1318
1319    BGRC_Output_ColorKeySelection cksNotSrcNotDst;
1320    BGRC_Output_ColorKeySelection cksDstNotSrc;
1321        BGRC_Output_ColorKeySelection cksSrcNotDst;
1322        BGRC_Output_ColorKeySelection cksSrcDst;
1323
1324    BDBG_ENTER(BGRClib_Blit);
1325    GRCLIB_CHECK(grclibHandle);
1326    BDBG_ASSERT(sizeof(BlitColorBlends)/sizeof(*BlitColorBlends) == BGRCLib_BlitColorOp_Count);
1327    BDBG_ASSERT(sizeof(BlitAlphaBlends)/sizeof(*BlitAlphaBlends) == BGRCLib_BlitAlphaOp_Count);
1328    BDBG_ASSERT(params->colorOp < BGRCLib_BlitColorOp_Count && params->alphaOp < BGRCLib_BlitAlphaOp_Count);
1329    BDBG_ASSERT(params->outSurfaceList && params->outSurfaceCnt);
1330
1331
1332    /* ---------------------------------------- */
1333    /* Set-up local variables                   */
1334    /* ---------------------------------------- */
1335    grc = grclibHandle->hGRC;
1336
1337    /* Clamp input values (for coverity and release builds) */
1338    /* Add support for user-specified blend equation */
1339    if (params->colorOp == BGRCLib_BlitColorOp_eUseBlendFactors)
1340        colorBlend = params->colorBlend;
1341    else if (params->colorOp < BGRCLib_BlitColorOp_Count)
1342        colorBlend = BlitColorBlends[params->colorOp];
1343    else
1344        colorBlend = BlitColorBlends[BGRCLib_BlitColorOp_eCopySource];
1345
1346    if (params->alphaOp == BGRCLib_BlitAlphaOp_eUseBlendFactors)
1347        alphaBlend = params->alphaBlend;
1348    else if (params->colorOp < BGRCLib_BlitAlphaOp_Count)
1349        alphaBlend = BlitAlphaBlends[params->alphaOp];
1350    else
1351        alphaBlend = BlitAlphaBlends[BGRCLib_BlitAlphaOp_eCopySource];
1352
1353    /* Determine the maximum list length */
1354    maxCnt = BMAX(params->srcRectCnt, params->dstRectCnt);
1355    maxCnt = BMAX(maxCnt, params->outRectCnt);
1356    maxCnt = BMAX(maxCnt, params->dstSurfaceCnt);
1357    maxCnt = BMAX(maxCnt, params->srcSurfaceCnt);
1358    maxCnt = BMAX(maxCnt, params->outSurfaceCnt);
1359
1360    /* Keep track of changes to minimize calls to GRC */
1361    xSrc = ySrc = widthSrc = heightSrc = 0xffffff;
1362    xDst = yDst = widthDst = heightDst = 0xffffff;
1363    xOut = yOut = widthOut = heightOut = 0xffffff;
1364    srcSurf = dstSurf = outSurf = (BSUR_Surface_Handle)0xffffff;
1365
1366    /* Initialization to resolve coverity */
1367    x = 0;
1368    y = 0;
1369    w = 0;
1370    h = 0;
1371 
1372    /* Must have at least one output surface */
1373    if ((params->outSurfaceCnt == 0 || params->outSurfaceList == NULL || *params->outSurfaceList == NULL) && err == BERR_SUCCESS)
1374        err = BERR_TRACE(BERR_INVALID_PARAMETER);
1375
1376
1377    /* ---------------------------------------- */
1378    /* Set-up the common parts of the operation */
1379    /* ---------------------------------------- */
1380
1381    /* If the output a palette surface, then bypass the look-up so we can */
1382    /* get the source palette values into the destination. */
1383    /* Note that it is expected that the source surface is also a palette. */
1384    if (err == BERR_SUCCESS)
1385    {
1386        surf = *params->outSurfaceList;
1387
1388        if (err == BERR_SUCCESS)
1389            err = BSUR_Surface_GetFormat(surf, &outFormat);
1390   
1391        if (err == BERR_SUCCESS && BPXL_IS_PALETTE_FORMAT(outFormat))
1392        {
1393            paletteToggled = true;
1394            err = BGRC_Source_TogglePaletteBypass(grc, true);
1395        }
1396   
1397        if (err == BERR_SUCCESS && BPXL_IS_PALETTE_FORMAT(outFormat))
1398            err = BGRC_Destination_TogglePaletteBypass(grc, true);
1399    }
1400
1401    /* Specify which pixels are used: source, destination or blend block */
1402    /* The blend block should be used for any operation that computes new pixels */
1403    /* The source block should be used when the output is a palette surface */
1404    /* If color key selection is activated for the Destination surface, then the */
1405    /* destination block should be used.  */
1406    /* Note: If colorkeying is enabled with the params parameter and if the individual */
1407    /*        source pixel is colorkeyed that the destination color is used.  */
1408    if (err == BERR_SUCCESS)
1409    {
1410        /* Set-up the color key selection values */
1411        cksNotSrcNotDst = params->colorKeySelect;
1412
1413        /* Selection when source is color keyed, but destination is not  */
1414        if (colorkeyParams != NULL && colorkeyParams->enableColorKey)
1415            cksSrcNotDst = colorkeyParams->cksOnlySrcColorKeyed;
1416        else
1417            cksSrcNotDst = BGRC_Output_ColorKeySelection_eTakeDestination;
1418
1419        /* Selection when destination is color keyed, but source is not */
1420        if (colorkeyParams != NULL && colorkeyParams->enableDstColorKey)
1421            cksDstNotSrc = colorkeyParams->cksOnlyDstColorKeyed;
1422        else
1423            cksDstNotSrc = BGRC_Output_ColorKeySelection_eTakeSource;
1424
1425        /* Selection when both source and destination surfaces are colorkeyed */
1426        if (colorkeyParams != NULL && colorkeyParams->enableColorKey && colorkeyParams->enableDstColorKey)
1427            cksSrcDst = colorkeyParams->cksBothSrcDstColorKeyed;
1428        else
1429            cksSrcDst = BGRC_Output_ColorKeySelection_eTakeDestination;
1430
1431        /* Set-up the GRC */
1432        if (grclibHandle->selA != cksNotSrcNotDst || 
1433            grclibHandle->selB != cksDstNotSrc    ||
1434            grclibHandle->selC != cksSrcNotDst    || 
1435            grclibHandle->selD != cksSrcDst)
1436        {
1437            err = BGRC_Output_SetColorKeySelection(grc,
1438                cksNotSrcNotDst, /* No color keying */
1439                cksDstNotSrc,    /* Src is color keyed, dest is not */
1440                cksSrcNotDst,    /* Dst is color keyed, src is not */
1441                cksSrcDst);      /* Both src and dst color keyed */
1442
1443            grclibHandle->selA = cksNotSrcNotDst;
1444            grclibHandle->selB = cksDstNotSrc;
1445            grclibHandle->selC = cksSrcNotDst;
1446            grclibHandle->selD = cksSrcDst;
1447        }
1448    }
1449
1450    /* Set the COLOR blend equation depending on the operation requested */
1451    if (err == BERR_SUCCESS)
1452        err = BGRC_Blend_SetColorBlend(grc, colorBlend.a, colorBlend.b, colorBlend.subcd, colorBlend.c,colorBlend.d, colorBlend.sube, colorBlend.e);
1453
1454    /* Set the ALPHA blend equation depending on the operation requested */
1455    if (err == BERR_SUCCESS)
1456        err = BGRC_Blend_SetAlphaBlend(grc, alphaBlend.a, alphaBlend.b, alphaBlend.subcd, alphaBlend.c, alphaBlend.d, alphaBlend.sube, alphaBlend.e);
1457
1458
1459    /* Filter Coefficients */
1460    /* 2008.09.09: Updated logic to enable filtering only for a blurry filter. For scaled blits, the GRC */
1461    /* will always enable filtering. For unscaled blits, enabling the filter can affect performance, so it */
1462    /* is only enabled when the filter specified is blurry. */
1463    /* 2009.04.22: Set the horizontal and vertical flags as necessary. Also, use a macro for readability and consistency. */
1464    if ((BGRCLIB_IS_BLURRY_FILTER(params->horzFilter) || BGRCLIB_IS_BLURRY_FILTER(params->vertFilter)) 
1465        && err == BERR_SUCCESS)
1466    {
1467        err = BGRC_Source_ToggleFilter(grc, BGRCLIB_IS_BLURRY_FILTER(params->horzFilter), BGRCLIB_IS_BLURRY_FILTER(params->vertFilter));
1468        filterToggled = true;
1469    }
1470
1471    if (err == BERR_SUCCESS)
1472        err = BGRC_Source_SetFilterCoeffs(grc, params->horzFilter, params->vertFilter);
1473
1474    /* Set-up the Constant color in the Blend block */
1475    /* This is the value used any "Constant Alpha" or "Constant Color" operations. */
1476    if (err == BERR_SUCCESS && grclibHandle->bldColor != params->constantColor)
1477    {
1478        err = BGRC_Blend_SetColor(grc, params->constantColor);
1479        grclibHandle->bldColor = params->constantColor;
1480    }
1481
1482    /* Populate the 'default' colors in the Source and Destination */
1483    /* These values will be used if the corresponding channel is missing from from the format or if the */
1484    /* source or destination surface is NULL. */
1485    if (err == BERR_SUCCESS && grclibHandle->srcColor != params->constantColor)
1486    {
1487        err = BGRC_Source_SetColor(grc, params->constantColor);
1488        grclibHandle->srcColor = params->constantColor;
1489    }
1490
1491    if (err == BERR_SUCCESS && grclibHandle->dstColor != params->destContColor)
1492    {
1493        err = BGRC_Destination_SetColor(grc, params->destContColor);
1494        grclibHandle->dstColor = params->destContColor;
1495    }
1496
1497
1498    /* If a color conversion matrix was provided, then use it */
1499    if (matrixParams != NULL && matrixParams->conversionMatrix != NULL)
1500    {
1501        if (err == BERR_SUCCESS)
1502            err = BGRC_Source_ToggleColorMatrix(grc, true);
1503
1504        if (err == BERR_SUCCESS)
1505            err = BGRC_Source_SetColorMatrix5x4(grc, matrixParams->conversionMatrix, matrixParams->matrixShift);
1506
1507        matrixToggled = true;
1508    }
1509
1510    /* Set-up colorkey parameters, if param block passed */
1511    if (colorkeyParams)
1512    {
1513        /* Set-up colorkey for source, if requested */
1514        if (colorkeyParams->enableColorKey)
1515        {
1516            /* Note that if the pixel is colorkeyed, then, according to the blend equation above, */
1517            /* the color selected will be the pixel from destination surface/block. */
1518            if (err == BERR_SUCCESS)
1519                err = BGRC_Source_SetColorKey(grc,
1520                    colorkeyParams->colorKeyLower,
1521                    colorkeyParams->colorKeyUpper,
1522                    colorkeyParams->colorKeyMask,
1523                    colorkeyParams->colorKeyReplace,
1524                    colorkeyParams->colorKeyRplMask,
1525                    false);
1526       
1527            if (err == BERR_SUCCESS)
1528                err = BGRC_Source_ToggleColorKey(grc, true);
1529       
1530            if (err == BERR_SUCCESS)
1531                err = BGRC_Source_SetKeyMatrixScaleOrder(grc, BGRC_KeyMatrixScaleOrder_eKeyThenScaleThenMatrix);
1532        }
1533       
1534        /* Set-up colorkey for destination, if requested */
1535        if (colorkeyParams->enableDstColorKey)
1536        {
1537            /* Note that if the pixel is colorkeyed, then, according to the blend equation above, */
1538            /* the color selected will be the pixel from source surface/block. */
1539            /* Also note that the params->colorKeySelect should be set to BGRC_Output_ColorKeySelection_eTakeDestination */
1540            if (err == BERR_SUCCESS)
1541                err = BGRC_Destination_SetColorKey(grc,
1542                    colorkeyParams->dstColorKeyLower,
1543                    colorkeyParams->dstColorKeyUpper,
1544                    colorkeyParams->dstColorKeyMask,
1545                    colorkeyParams->dstColorKeyReplace,
1546                    colorkeyParams->dstColorKeyRplMask,
1547                    false);
1548       
1549            if (err == BERR_SUCCESS)
1550                err = BGRC_Destination_ToggleColorKey(grc, true);
1551       
1552        }
1553
1554        colorkeyToggled = true;
1555    }
1556
1557    /* Set-up patterns, if param block passed */
1558    if (patternParams != NULL)
1559    {
1560        if (err == BERR_SUCCESS)
1561            err = BGRC_Pattern_Set(grc, patternParams->ropVector, patternParams->pattern, 
1562                                   patternParams->backColor, patternParams->foreColor);
1563
1564        patternToggled = true;
1565    }
1566
1567    /* Set-up scaling control, if param block passed */
1568    if (scalingParams != NULL)
1569    {
1570        if (scalingParams->setFilterPhaseAdj && err == BERR_SUCCESS)
1571            err = BGRC_Source_SetFilterPhaseAdjustment(grc, scalingParams->iHorizontalPhase, scalingParams->iVerticalPhase, 
1572                                                       scalingParams->ulPhaseFixedPointShift);
1573
1574        if (scalingParams->setFixedScaleFactor && err == BERR_SUCCESS)
1575            err = BGRC_Source_SetFixedScaleFactor(grc, scalingParams->ulHorizontalNumerator, scalingParams->ulHorizontalDenominator, 
1576                                                  scalingParams->ulVerticalNumerator, scalingParams->ulVerticalDenominator);
1577
1578        scalingToggled = true;
1579    }
1580
1581    /* Configure mirroring, as specified */
1582    if (err == BERR_SUCCESS)
1583        err = BGRC_Source_SetDirection(grc, params->mirrorSrcHorizontally, params->mirrorSrcVertically);
1584
1585    if (err == BERR_SUCCESS)
1586        err = BGRC_Destination_SetDirection(grc, params->mirrorDstHorizontally, params->mirrorDstVertically);
1587
1588    if (err == BERR_SUCCESS)
1589        err = BGRC_Output_SetDirection(grc, params->mirrorOutHorizontally, params->mirrorOutVertically);
1590
1591    /* Configure Source Alpha Premultiplication */
1592    if (err == BERR_SUCCESS)
1593        err = BGRC_Source_SetAlphaPreMultiply(grc, params->srcAlphaPremult);
1594
1595    /* Set-up vars for optimizing GRC calls */
1596    xSrc      = grclibHandle->srcX;
1597    ySrc      = grclibHandle->srcY;
1598    widthSrc  = grclibHandle->srcWidth;
1599    heightSrc = grclibHandle->srcHeight;
1600
1601    xDst      = grclibHandle->dstX;
1602    yDst      = grclibHandle->dstY;
1603    widthDst  = grclibHandle->dstWidth;
1604    heightDst = grclibHandle->dstHeight;
1605
1606    xOut      = grclibHandle->outX;
1607    yOut      = grclibHandle->outY;
1608    widthOut  = grclibHandle->outWidth;
1609    heightOut = grclibHandle->outHeight;
1610
1611    /* ---------------------------------------- */
1612    /* Loop over the lists                      */
1613    /* ---------------------------------------- */
1614    for (index = 0; index < maxCnt && err == BERR_SUCCESS; index++)
1615    {
1616        /* --------------------------- */
1617        /* Source                      */
1618        /* --------------------------- */
1619        /* Get the Source Surface and Rectangle according to the index */
1620        count = params->srcSurfaceCnt;
1621        surf = NULL;
1622        if (count > 0)
1623            surf = params->srcSurfaceList[index % count];
1624
1625        count = params->srcRectCnt;
1626        pRect = NULL;
1627        if (count > 0)
1628            pRect = &params->srcRectList[index % count];
1629
1630        /* Update the Source Surface, if it changed */
1631        if (srcSurf != surf)
1632        {
1633            err = BGRC_Source_SetSurface(grc, surf);
1634            srcSurf = surf;
1635        }
1636
1637        /* Update the Source Rectangle, if it changed */
1638        if (surf != NULL && err == BERR_SUCCESS)
1639            err = BGRClib_p_GetValidPositionInfo(pRect, surf, &x, &y, &w, &h);
1640
1641        if ((x != xSrc || y != ySrc || w != widthSrc || h != heightSrc)  && err == BERR_SUCCESS)
1642        {
1643            err = BGRC_Source_SetRectangle(grc, x, y, w, h);
1644            xSrc = x; ySrc = y; widthSrc = w; heightSrc = h;
1645        }
1646   
1647        /* --------------------------- */
1648        /* Destination                 */
1649        /* --------------------------- */
1650        /* Get the Destination Surface and Rectangle according to the index */
1651        count = params->dstSurfaceCnt;
1652        surf = NULL;
1653        if (count > 0)
1654            surf = params->dstSurfaceList[index % count];
1655
1656        count = params->dstRectCnt;
1657        pRect = NULL;
1658        if (count > 0)
1659            pRect = &params->dstRectList[index % count];
1660
1661        /* Update the Destination Surface, if it changed */
1662        if (dstSurf != surf && err == BERR_SUCCESS)
1663        {
1664            err = BGRC_Destination_SetSurface(grc, surf);
1665            dstSurf = surf;
1666        }
1667
1668        /* Update the Destination Rectangle, if it changed */
1669        if (surf != NULL && err == BERR_SUCCESS)
1670            err = BGRClib_p_GetValidPositionInfo(pRect, surf, &x, &y, &w, &h);
1671
1672        if ((x != xDst || y != yDst || w != widthDst || h != heightDst) && err == BERR_SUCCESS)
1673        {
1674            err = BGRC_Destination_SetRectangle(grc, x, y, w, h);
1675            xDst = x; yDst = y; widthDst = w; heightDst = h;
1676        }
1677   
1678        /* --------------------------- */
1679        /* Output                      */
1680        /* --------------------------- */
1681        /* Get the Output Surface and Rectangle according to the index */
1682        count = params->outSurfaceCnt;
1683        surf = NULL;
1684        if (count > 0)
1685            surf = params->outSurfaceList[index % count];
1686
1687        count = params->outRectCnt;
1688        pRect = NULL;
1689        if (count > 0)
1690            pRect = &params->outRectList[index % count];
1691
1692        /* Update the Output Surface, if it changed */
1693        if (outSurf != surf && err == BERR_SUCCESS)
1694        {
1695            err = BGRC_Output_SetSurface(grc, surf);
1696            outSurf = surf;
1697        }
1698
1699        /* Update the Output Rectangle, if it changed */
1700        if (surf != NULL && err == BERR_SUCCESS)
1701            err = BGRClib_p_GetValidPositionInfo(pRect, surf, &x, &y, &w, &h);
1702
1703        if ((x != xOut || y != yOut || w != widthOut || h != heightOut) && err == BERR_SUCCESS)
1704        {
1705            err = BGRC_Output_SetRectangle(grc, x, y, w, h);
1706            xOut = x; yOut = y; widthOut = w; heightOut = h;
1707        }
1708   
1709   
1710        /* --------------------------- */
1711        /* Go!                         */
1712        /* --------------------------- */
1713        /* Start the operations, all non-block no callback, except the last, which honors the pendtype */
1714        if (err == BERR_SUCCESS)
1715        {
1716            if (index < maxCnt - 1)
1717                err = BGRClib_p_Go(grclibHandle, BGRClib_PendType_eNoBlockNoCB);
1718            else
1719                err = BGRClib_p_Go(grclibHandle, pendtype);
1720        }
1721    }
1722
1723    grclibHandle->srcX      = xSrc;
1724    grclibHandle->srcY      = ySrc;
1725    grclibHandle->srcWidth  = widthSrc;
1726    grclibHandle->srcHeight = heightSrc;
1727
1728    grclibHandle->dstX      = xDst;
1729    grclibHandle->dstY      = yDst;
1730    grclibHandle->dstWidth  = widthDst;
1731    grclibHandle->dstHeight = heightDst;
1732
1733    grclibHandle->outX      = xOut;
1734    grclibHandle->outY      = yOut;
1735    grclibHandle->outWidth  = widthOut;
1736    grclibHandle->outHeight = heightOut;
1737
1738    /* Undo any 'toggled' changes */
1739    /* Colorkey */
1740    if (err == BERR_SUCCESS && colorkeyToggled)
1741        err = BGRC_Source_ToggleColorKey(grc, false);
1742
1743    if (err == BERR_SUCCESS && colorkeyToggled)
1744        err = BGRC_Destination_ToggleColorKey(grc, false);
1745
1746    /* Color Matrix */
1747    if (err == BERR_SUCCESS && matrixToggled)
1748        err = BGRC_Source_ToggleColorMatrix(grc, false);
1749
1750    /* Filter */
1751    if (err == BERR_SUCCESS && filterToggled)
1752        err = BGRC_Source_ToggleFilter(grc, false, false);
1753
1754    /* Palette */
1755    if (err == BERR_SUCCESS && paletteToggled)
1756        err = BGRC_Source_TogglePaletteBypass(grc, false);
1757
1758    if (err == BERR_SUCCESS && paletteToggled)
1759        err = BGRC_Destination_TogglePaletteBypass(grc, false);
1760
1761    /* Scaling */
1762    if (err == BERR_SUCCESS && scalingToggled)
1763        err = BGRC_Source_SetFilterPhaseAdjustment(grc, 0, 0, 0);
1764
1765    if (err == BERR_SUCCESS && scalingToggled)
1766        err = BGRC_Source_SetFixedScaleFactor(grc, 0, 0, 0, 0);
1767
1768    /* Patterns */
1769    if (err == BERR_SUCCESS && patternToggled)
1770        err = BGRC_Pattern_ResetState(grc);
1771
1772    /* Clear anything unconditionally set but not tracked */
1773    if (err == BERR_SUCCESS)
1774        err = BGRC_Source_SetDirection(grc, false, false);
1775
1776    if (err == BERR_SUCCESS)
1777        err = BGRC_Destination_SetDirection(grc, false, false);
1778
1779    if (err == BERR_SUCCESS)
1780        err = BGRC_Output_SetDirection(grc, false, false);
1781
1782    if (err == BERR_SUCCESS)
1783        err = BGRC_Source_SetAlphaPreMultiply(grc, false);
1784
1785    if (err == BERR_SUCCESS)
1786        err = BGRC_Source_SetFilterCoeffs(grc, BGRC_FilterCoeffs_eSharp, BGRC_FilterCoeffs_eSharp);
1787
1788    if (err == BERR_SUCCESS)
1789        err = BGRC_Source_SetKeyMatrixScaleOrder(grc, BGRC_KeyMatrixScaleOrder_eScaleThenKeyThenMatrix);
1790
1791    BDBG_LEAVE(BGRClib_Blit);
1792    return BERR_TRACE(err);;
1793}
1794
1795
1796/*****************************************************************************
1797  Summary:
1798    Start the GRC operation according to the pendtype param
1799
1800  Description:
1801    This routine calls either BGRC_IssueState or BGRC_IssueStateAndWait
1802    according to pendtype parameter.   
1803
1804 *****************************************************************************/
1805BERR_Code BGRClib_p_Go(
1806    BGRClib_Handle          grclibHandle,
1807    BGRClib_PendType        pendtype
1808)
1809{
1810    BERR_Code err;
1811
1812    if (pendtype == BGRClib_PendType_eBlock)
1813        err = BGRC_IssueStateAndWait(grclibHandle->hGRC);
1814
1815    else if (pendtype == BGRClib_PendType_eNoBlockNoCB)
1816        err = BGRC_IssueState(grclibHandle->hGRC, NULL, NULL);
1817
1818    else if (pendtype == BGRClib_PendType_eNoBlockUseCB)
1819        err = BGRC_IssueState(grclibHandle->hGRC, grclibHandle->callback_isr, grclibHandle->callback_data);
1820
1821    else
1822    {
1823        BDBG_ASSERT(false);
1824        err = BERR_INVALID_PARAMETER;
1825    }
1826
1827    return BERR_TRACE(err);
1828}
1829
1830
1831/*****************************************************************************
1832  Summary:
1833    Converts color according to the ColorFmtType param
1834
1835  Description:
1836
1837    .   
1838    switch (surface->create_settings.pixel_format) {
1839    case bgraphics_pixel_format_palette2:
1840        pixel = (pixel & 0x3) << 6;
1841        break;
1842    case bgraphics_pixel_format_palette4:
1843        pixel = (pixel & 0xF) << 4;
1844        break;
1845    case bgraphics_pixel_format_a8_palette8:
1846        pixel = ((pixel & 0xFF00) << 16) | (pixel & 0xFF);
1847        break;
1848    case bgraphics_pixel_format_a8:
1849        pixel = (pixel & 0xFF) << 24;
1850        break;
1851    case bgraphics_pixel_format_y08_cb8_y18_cr8:
1852        {
1853        unsigned int aycrcb_pixel;
1854        BPXL_ConvertPixel_RGBtoYCbCr(BPXL_eA8_Y8_Cb8_Cr8, BPXL_eA8_R8_G8_B8, pixel, &aycrcb_pixel);
1855        BDBG_MSG(("convert pixel on fill %08x => %08x", pixel, aycrcb_pixel));
1856        pixel = aycrcb_pixel;
1857        }
1858        break;
1859    default:
1860        break;
1861
1862 *****************************************************************************/
1863BERR_Code BGRClib_p_ConvertColorToStdColor(
1864    BSUR_Surface_Handle     surface,
1865    uint32_t                constantColor,
1866    BGRClib_ColorFmtType    fmtType,
1867    uint32_t*               pColor
1868)
1869{
1870    BERR_Code   err = BERR_SUCCESS;
1871    BPXL_Format srcformat;
1872    BPXL_Format dstformat;
1873
1874    if (fmtType == BGRClib_ColorFmtType_eStdFormat)
1875    {
1876        /* The color provided was in the format needed by the GRC/M2MC */
1877        /* so no conversion needed */
1878        *pColor = constantColor;
1879    }
1880    else if (fmtType == BGRClib_ColorFmtType_eSameAsSurf)
1881    {
1882        if (err == BERR_SUCCESS)
1883            err = BSUR_Surface_GetFormat(surface, &srcformat);
1884
1885        if (err == BERR_SUCCESS)
1886        {
1887            dstformat = (BPXL_IS_RGB_FORMAT(srcformat)) ? BPXL_eA8_R8_G8_B8 : BPXL_eA8_Y8_Cb8_Cr8;
1888            err = BPXL_ConvertPixel(dstformat, srcformat, constantColor, (unsigned int*)pColor);
1889        }
1890    }
1891    else
1892    {
1893        BDBG_ASSERT(false);
1894        err = BERR_INVALID_PARAMETER;
1895    }
1896
1897    return BERR_TRACE(err);
1898}
1899
1900
1901/*****************************************************************************
1902  Summary:
1903    Get position (x, y, width, height) from either a rect or from the surface
1904    if the rect is NULL
1905
1906  Description:
1907    This routine handles the work of testing whether a rect pointer is NULL
1908    or not. If the rect is NULL, then set the x and y to zero and use the
1909    width and height from the surface.   
1910
1911 *****************************************************************************/
1912BERR_Code BGRClib_p_GetValidPositionInfo(
1913    const BRect*            pRect,
1914    BSUR_Surface_Handle     surface,
1915    uint32_t*               pX,
1916    uint32_t*               pY,
1917    uint32_t*               pWidth,
1918    uint32_t*               pHeight)
1919{
1920    BERR_Code err = BERR_SUCCESS;
1921
1922    if (pRect != NULL)
1923    {
1924        *pX = pRect->left;
1925        *pY = pRect->top;
1926        *pWidth = PBRECT_WIDTH(pRect);
1927        *pHeight = PBRECT_HEIGHT(pRect);
1928    }
1929    else
1930    {
1931        *pX = 0;
1932        *pY = 0;
1933
1934        err = BSUR_Surface_GetDimensions(surface, pWidth, pHeight);
1935    }
1936
1937    return err;
1938}
1939/* End of File */
Note: See TracBrowser for help on using the repository browser.