This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Alpha blending using GC320

This is a query regarding overlay blending functionality in GC320 driver using Vivante 2D APIs.

 

Our requirement is to overlay an ARGB surface(src) on top of another ARGB surface (dst) with blending.

When the src surface pixel alpha value is 0x00, a completely transparent src surface, with no components of src contributing to final output is required.

Also when src surface alpha is 0xff, a completely opaque src surface, with no components of dst in the overlapping area in the final output is required.

 

We are able to implement blending using two methods:

1)      Pixel level alpha value adjustment, with global alpha disabled

2)      Global alpha value adjustment, with pixel alpha values set to 0xff for both src and dst surfaces.

 

Our observation is that when blending is done using pixel level alpha with global alpha disabled(method 1), src surface components were not completely transparent when src pixel alpha values were 0x00. Please note in this case the dst pixel alpha value is always 0xFF.

 

When we were adjusting global alpha value, with individual pixel alpha values set to 0xff(method 2), we were able to achieve the desired result.

Can the same be achieved using individual pixel level alpha value?

 

Sample code snippet used for both modes, and the respective outputs are attached in this mail.

 

Gal2DAlphaBlending_pixelAlpha.c has the code which implements the blending using pixel level alpha values with global alpha disabled.

Corresponding  output is gal2DAlphaBlending_PixelAlpha.bmp

Gal2DAlphaBlending_globalAlpha.c has the global alpha mode enabled and pixel level alpha for both src and dst are set to 0xff.

Corresponding output is gal2DAlphaBlendingGlobalAlpha.bmp

 

In the above code snippet, desiredSrcAlpha is the alpha value needed for src surface overlay.

 

The desired output in our use case is gal2DAlphaBlendingGlobalAlpha.bmp (method 2).

Is it possible to achieve the same result with pixel level alpha blending(method 1) as it is in  global alpha blending(method 2).

 

Note:

The code snippet is modified version of AlphaBlending /001 sample from ti_dra7x_gc320-unified-driver example.

  • Hi,

    In the example code, some of the factors are set differently leading up to different blend equations.

    In the case of global alpha the final blend equation is getting evaluated to `Cb = Cd` hence you see the solid red rectangle, where as for the pixel alpha case its getting evaluated to `Cb = Cs + Cd` hence the red + pink rectangle.

    Try changing the following in pixel alpha example

    ```

               gcmONERROR(gco2D_EnableAlphaBlendAdvanced(egn2D,

                                 gcvSURF_PIXEL_ALPHA_INVERSED, gcvSURF_PIXEL_ALPHA_STRAIGHT,

                                 gcvSURF_GLOBAL_ALPHA_OFF, gcvSURF_GLOBAL_ALPHA_OFF,

                                 gcvSURF_BLEND_STRAIGHT, gcvSURF_BLEND_STRAIGHT));

    ```

    to the following to get to the same result as of global alpha

    ```

               gcmONERROR(gco2D_EnableAlphaBlendAdvanced(egn2D,

                                 gcvSURF_PIXEL_ALPHA_INVERSED, gcvSURF_PIXEL_ALPHA_INVERSED,

                                 gcvSURF_GLOBAL_ALPHA_OFF, gcvSURF_GLOBAL_ALPHA_OFF,

                                 gcvSURF_BLEND_STRAIGHT, gcvSURF_BLEND_STRAIGHT));

    ```

    As to why, its easier to consider the blending ops by its genarlized equation and set the parameters accordingly to get to your final desired output

    ```

    Cb = Fs * Cs' + Fd * Cd'

    Ad = Fs * As'' + Fd * Ad''

    Fs:   source factor

    Fd:   dest factor

    Cs':  source color

    Cd':  dest color

    As'': source alpha

    Ad'': dest alpha

    ```

    `gco2D_EnableAlphaBlendAdvanced()` takes in blend mode variables that determine how `As''` and `Fs` values are calculated. Below are the scenarios for different config options

    ```

    As'   = As        if gcvSURF_PIXEL_ALPHA_STRAIGHT

         = (1-As)    if gcvSURF_PIXEL_ALPHA_INVERSED

    As'' = As'       if gcvSURF_GLOBAL_ALPHA_OFF

         = Ags       if gcvSURF_GLOBAL_ALPHA_ON

         = As' * Ags if gcvSURF_GLOBAL_ALPHA_SCALE

    ```

    similarly for `Ad''`

    ```

    Fs    = 0         if gcvSURF_BLEND_ZERO

         = 1         if gcvSURF_BLEND_ONE

         = Ad''      if gcvSURF_BLEND_STRAIGHT (notice that its dest for Fs and src for Fd)

         = (1-Ad'')  if gcvSURF_BLEND_INVERSED

    ```

    similarly for `Fd`

    `gco2DSetPixelMultiplyModeAdvanced()` determines how the `Cs'` values are calculated based on the options given to it

    ```

    Cs'   = Cs * As         if gcv2D_COLOR_MULTIPLY_ENABLE (for pixel level alpha)

         = Cs * Ags        if gcv2D_COLOR_MULTIPLY_ENABLE (for global alpha)

         = Cs * As * Ags   if gcv2D_COLOR_MULTIPLY_ENABLE (for both pixel and global alpha)

    ```

    you can also specify if you want the destination color to be pre-multiplied or not.

    Considering above in the global alpha example, the following are set as pixel and global alphas

    ```

               gcmONERROR(gco2D_EnableAlphaBlendAdvanced(egn2D,

                                 gcvSURF_PIXEL_ALPHA_STRAIGHT, gcvSURF_PIXEL_ALPHA_STRAIGHT,

                                 gcvSURF_GLOBAL_ALPHA_ON, gcvSURF_GLOBAL_ALPHA_ON,

                                 gcvSURF_BLEND_STRAIGHT, gcvSURF_BLEND_STRAIGHT));

    ```

    ```

    As = 1

    Ad = 1

    Ags = 1

    Agd = 0

    As' = As

    Ad' = Ad

    As'' = Ags * As' = 1

    Ad'' = Agd * Ad' = 0

    Cs' = Cs

    Cd' = Cd

    Cb = Ad'' * Cs' + As'' * Cd' = Cd (red rectangle)

    ```

    In the case of per pixel alpha

    ```

               gcmONERROR(gco2D_EnableAlphaBlendAdvanced(egn2D,

                                 gcvSURF_PIXEL_ALPHA_INVERSED, gcvSURF_PIXEL_ALPHA_STRAIGHT,

                                 gcvSURF_GLOBAL_ALPHA_OFF, gcvSURF_GLOBAL_ALPHA_OFF,

                                 gcvSURF_BLEND_STRAIGHT, gcvSURF_BLEND_STRAIGHT));

    As = 0

    Ad = 1

    Ags = 0

    Agd = 0

    As' = 1 - As = 1

    Ad' = Ad = 1

    As'' = As'

    Ad'' = Ad'

    Cs' = Cs

    Cd' = Cd

    Cb = Ad'' * Cs' + As'' * Cd' = Cs + Cd

    ```

    Hope this helps.

     

    Thanks,

    Gowtham

  • Hi Gowtham,

     

    Thanks for the details.

    I have a doubt whether the said modes for pixel level alpha blending will help in achieving the desired results in all scenarios.

     

    Consider the case with alpha modes set to gcvSURF_PIXEL_ALPHA_INVERSED for both src and dst , as  you  mentioned :

     

    gcmONERROR(gco2D_EnableAlphaBlendAdvanced(egn2D,

                                  gcvSURF_PIXEL_ALPHA_INVERSED, gcvSURF_PIXEL_ALPHA_INVERSED,

                                  gcvSURF_GLOBAL_ALPHA_OFF, gcvSURF_GLOBAL_ALPHA_OFF,

                                  gcvSURF_BLEND_STRAIGHT, gcvSURF_BLEND_STRAIGHT));

     

     

    Consider the blending equation:

    Cb = Fs * Cs' + Fd * Cd'

    Ad = Fs * As'' + Fd * Ad''

     

     

    Scenario 1: Src alpha is 0 (Expected output: Only dst surface components should be present in the overlapping output regions)

    Values for the above parameters would be:

     

    Fs = (1 - 1)

    Fd = (1 - 0)

     

    Cb =  0 * Cs + 1 * Cd = (Cd)          

    Ad = 0 * 1 + 1 * 0 = 0

     

    The output will not have any src components as expected.

     

    Scenario 2: src alpha is 0.5 (Expected output: 50 % of the src components should be present in the overlapping output regions)

    Values for the above parameters would be:

     

    Fs = ( 1 - 1)

    Fd = (1 - 0.5)

     

    Cb =  0 * Cs + 0.5 * Cd = (0.5 *Cd)             

    Ad = 0 * 0.5 + 0.5 * 0 = 0  

     

    The output will have 50 % of dst components with no src components present.

     

    Scenario 3:Src alpha is 1(Expected output is only src components should be present in the overlapping output regions)

    Values for the above parameters would be:

    Fs = (1 – 1)

    Fd = (1 - 1)

     

    Cb = 0 * Cs  + 0 * Cd = 0

    Ad = 0 * 0 + 0 * 0  = 0

    In this case, the output will be a blank screen.

     

     

    Note:

    In all the above cases dst surface alpha is always set as 1.

     

     

    --Regards

    Thushara Jayakumar

  • Hi Thushara,

    The suggestion was to make the blend equation the same for both the examples.

    It would be easier to determine the right blend modes used if a blend equation can be derived for the required scenario. For instance most commonly used blend srccopy/srcover where src is overlayed on destination (which I think you are looking into) the blend equation would be

    C = Cs + (1 – As’’)Cd
    A = As’’ + (1 – As’’)Ad’’

    For this you would set following for `gco2D_EnabledAlphaBlendAdvanced()`

    - `gcvSURF_PIXEL_ALPHA_STRAIGHT` for src and pixel alpha mode (assuming 0x0 for transparency and 0xff for opacity)
    - `gcvSURF_GLOBAL_ALPHA_OFF` for global alpha
    - `gcvSURF_BLEND_ONE` for source blend factor
    - `gcvSURF_BLEND_INVERSED` for destination blend factor

    and `gcv2D_COLOR_MULTIPLY_DISABLE` for alpha multiply options in `gco2D_SetPixelMultiplyModesAdvanced()` call.

    Thanks,
    Gowtham
  • Hi Gowtham,

    Thanks for the response.

    I was able to achieve my use case by using gco2D_EnableAlphaBlendAdvanced and gco2D_SetPixelMultiplyModeAdvanced API's.

    For gco2D_EnableAlphaBlendAdvanced the following configuration are used:

    - 'gcvSURF_PIXEL_ALPHA_INVERSED' for src alpha
    - 'gcvSURF_PIXEL_ALPHA_STRAIGHT' for dst alpha
    - 'gcvSURF_GLOBAL_ALPHA_OFF' for both src and dst
    - 'gcvSURF_BLEND_ONE' for srcFactorMode
    - 'gcvSURF_BLEND_STRAIGHT' for dstFactorMode

    For gco2D_SetPixelMultiplyModeAdvanced following configuration was used:
    -'gcv2D_COLOR_MULTIPLY_ENABLE' for SrcPremultiplySrcAlpha
    - 'gcv2D_COLOR_MULTIPLY_DISABLE' for DstPremulitplyDstAlpha and DstDemulitplyDstAlpha
    - 'gcv2D_GLOBAL_COLOR_MULTIPLY_DISABLE' for SrcPremulitplyGlobalMode



    A small correction:

    There is typo for the API gco2D_SetPixelMultiplyModeAdvanced() in the ' Vivante.2D.API_v2.70-20150109.pdf' as well as in the mail you sent. It is given as gco2D_SetPixelMultiplyModesAdvanced in the API, hence I was getting an undefined error while compiling.


    --Thanks and Best Regards
    Thushara Jayakumar
  • Hi Thushara,

    Glad to hear that you got it resolved. Yes, you are correct in the API part, a typo from my end. As this is resolved, I will close this entry.

    Thanks,
    Gowtham