Loop more

 Dears,
>      We are now trying to provide HW acceleration for DFB blit operations
> in our chipset for embeded media system. Our HW designer  is confused about
> how to provide HW acceleration for DFB sourcemask functionality: At which
> stage should we modulate the src alpha/color with source mask?
>          The attached text is our currently used reference code which comes
> from DFB source. The reference code doesn't support sourcemask yet.  If we
> put src mask modulation into the different stage of the blit pipe, the final
> result will be different, at least the precision . So we need an offical
> document to define details.
>       Could anyone kindly give us you specifiation about sourcemask
> support? Thanks a lot in advance!!
>
> Thanks and best regards,
> tommy
>
static DFBColor
blit_pixel( CardState *state, DFBColor src, DFBColor dst )
{
     /* Scratch for blending stage. */
     DFBColor x;

     /*
      * Input => short circuit to Output? (simple blits)
      */

     /* Without any flag the source is simply copied. */
     if (!state->blittingflags)
          return src;

     /* Source color keying is the 2nd simplest operation. */
     if (state->blittingflags & DSBLIT_SRC_COLORKEY) {
          /* If the source matches the color key, keep the destination. */
          if (PIXEL_RGB32(src.r,src.g,src.b) == state->src_colorkey)
               return dst;
     }

     /* Destination color keying already requires reading the destination. */
     if (state->blittingflags & DSBLIT_DST_COLORKEY) {
          /* If the destination does not match the color key, keep the 
destination. */
          if (PIXEL_RGB32(dst.r,dst.g,dst.b) != state->dst_colorkey)
               return dst;
     }

     /*
      * Modulation stage
      */

     /* Modulate source alpha value with global alpha factor? */
     if (state->blittingflags & DSBLIT_BLEND_COLORALPHA) {
          /* Combine with source alpha value... */
          if (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL)
               MODULATE( src.a, state->color.a );
          else
               /* ...or replace it. */
               src.a = state->color.a;
     }

     /* Modulate source colors with global color factors? */
     if (state->blittingflags & DSBLIT_COLORIZE) {
          MODULATE( src.r, state->color.r );
          MODULATE( src.g, state->color.g );
          MODULATE( src.b, state->color.b );
     }

     /*
      * Premultiplication stage
      */

     /* Premultiply source colors with (modulated) source alpha value? */
     if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) {
          MODULATE( src.r, src.a );
          MODULATE( src.g, src.a );
          MODULATE( src.b, src.a );
     }

     /* Premultiply source colors with global alpha factor only? */
     if (state->blittingflags & DSBLIT_SRC_PREMULTCOLOR) {
          MODULATE( src.r, state->color.a );
          MODULATE( src.g, state->color.a );
          MODULATE( src.b, state->color.a );
     }

     /* Premultiply destination colors with destination alpha value? */
     if (state->blittingflags & DSBLIT_DST_PREMULTIPLY) {
          MODULATE( dst.r, dst.a );
          MODULATE( dst.g, dst.a );
          MODULATE( dst.b, dst.a );
     }

     /*
      * XOR comes right before blending, after load, modulate and premultiply.
      */
     if (state->blittingflags & DSBLIT_XOR) {
          src.a ^= dst.a;
          src.r ^= dst.r;
          src.g ^= dst.g;
          src.b ^= dst.b;
     }

     /*
      * Blending stage
      */

     /* Initialize scratch with source values, modify the copy according to the 
source blend function.
        Could be done better by writing to the scratch only once after the 
calculation. */
     x = src;

     /* Blend scratch (source copy) and destination values accordingly. */
     if (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL | 
DSBLIT_BLEND_COLORALPHA)) {
          /* Apply the source blend function to the scratch. */
          switch (state->src_blend) {
               /* Sargb *= 0.0 */
               case DSBF_ZERO:
                    x.a = x.r = x.g = x.b = 0;
                    break;

               /* Sargb *= 1.0 */
               case DSBF_ONE:
                    break;

               /* Sargb *= Sargb */
               case DSBF_SRCCOLOR:
                    MODULATE( x.a, src.a );
                    MODULATE( x.r, src.r );
                    MODULATE( x.g, src.g );
                    MODULATE( x.b, src.b );
                    break;

               /* Sargb *= 1.0 - Sargb */
               case DSBF_INVSRCCOLOR:
                    MODULATE( x.a, src.a ^ 0xff );
                    MODULATE( x.r, src.r ^ 0xff );
                    MODULATE( x.g, src.g ^ 0xff );
                    MODULATE( x.b, src.b ^ 0xff );
                    break;

               /* Sargb *= Saaaa */
               case DSBF_SRCALPHA:
                    MODULATE( x.a, src.a );
                    MODULATE( x.r, src.a );
                    MODULATE( x.g, src.a );
                    MODULATE( x.b, src.a );
                    break;

               /* Sargb *= 1.0 - Saaaa */
               case DSBF_INVSRCALPHA:
                    MODULATE( x.a, src.a ^ 0xff );
                    MODULATE( x.r, src.a ^ 0xff );
                    MODULATE( x.g, src.a ^ 0xff );
                    MODULATE( x.b, src.a ^ 0xff );
                    break;

               /* Sargb *= Daaaa */
               case DSBF_DESTALPHA:
                    MODULATE( x.a, dst.a );
                    MODULATE( x.r, dst.a );
                    MODULATE( x.g, dst.a );
                    MODULATE( x.b, dst.a );
                    break;

               /* Sargb *= 1.0 - Daaaa */
               case DSBF_INVDESTALPHA:
                    MODULATE( x.a, dst.a ^ 0xff );
                    MODULATE( x.r, dst.a ^ 0xff );
                    MODULATE( x.g, dst.a ^ 0xff );
                    MODULATE( x.b, dst.a ^ 0xff );
                    break;

               /* Sargb *= Dargb */
               case DSBF_DESTCOLOR:
                    MODULATE( x.a, dst.a );
                    MODULATE( x.r, dst.r );
                    MODULATE( x.g, dst.g );
                    MODULATE( x.b, dst.b );
                    break;

               /* Sargb *= 1.0 - Dargb */
               case DSBF_INVDESTCOLOR:
                    MODULATE( x.a, dst.a ^ 0xff );
                    MODULATE( x.r, dst.r ^ 0xff );
                    MODULATE( x.g, dst.g ^ 0xff );
                    MODULATE( x.b, dst.b ^ 0xff );
                    break;

               /* ??? */
               case DSBF_SRCALPHASAT:
                    D_UNIMPLEMENTED();
                    break;

               default:
                    D_BUG( "unknown blend function %d", state->src_blend );
          }

          /* Apply the destination blend function. */
          switch (state->dst_blend) {
               /* Dargb *= 0.0 */
               case DSBF_ZERO:
                    dst.a = dst.r = dst.g = dst.b = 0;
                    break;

               /* Dargb *= 1.0 */
               case DSBF_ONE:
                    break;

               /* Dargb *= Sargb */
               case DSBF_SRCCOLOR:
                    MODULATE( dst.a, src.a );
                    MODULATE( dst.r, src.r );
                    MODULATE( dst.g, src.g );
                    MODULATE( dst.b, src.b );
                    break;

               /* Dargb *= 1.0 - Sargb */
               case DSBF_INVSRCCOLOR:
                    MODULATE( dst.a, src.a ^ 0xff );
                    MODULATE( dst.r, src.r ^ 0xff );
                    MODULATE( dst.g, src.g ^ 0xff );
                    MODULATE( dst.b, src.b ^ 0xff );
                    break;

               /* Dargb *= Saaaa */
               case DSBF_SRCALPHA:
                    MODULATE( dst.a, src.a );
                    MODULATE( dst.r, src.a );
                    MODULATE( dst.g, src.a );
                    MODULATE( dst.b, src.a );
                    break;

               /* Dargb *= 1.0 - Saaaa */
               case DSBF_INVSRCALPHA:
                    MODULATE( dst.a, src.a ^ 0xff );
                    MODULATE( dst.r, src.a ^ 0xff );
                    MODULATE( dst.g, src.a ^ 0xff );
                    MODULATE( dst.b, src.a ^ 0xff );
                    break;

               /* Dargb *= Daaaa */
               case DSBF_DESTALPHA:
                    MODULATE( dst.r, dst.a );
                    MODULATE( dst.g, dst.a );
                    MODULATE( dst.b, dst.a );
                    MODULATE( dst.a, dst.a ); //
                    break;

               /* Dargb *= 1.0 - Daaaa */
               case DSBF_INVDESTALPHA:
                    MODULATE( dst.r, dst.a ^ 0xff );
                    MODULATE( dst.g, dst.a ^ 0xff );
                    MODULATE( dst.b, dst.a ^ 0xff );
                    MODULATE( dst.a, dst.a ^ 0xff ); //
                    break;

               /* Dargb *= Dargb */
               case DSBF_DESTCOLOR:
                    MODULATE( dst.r, dst.r );
                    MODULATE( dst.g, dst.g );
                    MODULATE( dst.b, dst.b );
                    MODULATE( dst.a, dst.a ); //
                    break;

               /* Dargb *= 1.0 - Dargb */
               case DSBF_INVDESTCOLOR:
                    MODULATE( dst.r, dst.r ^ 0xff );
                    MODULATE( dst.g, dst.g ^ 0xff );
                    MODULATE( dst.b, dst.b ^ 0xff );
                    MODULATE( dst.a, dst.a ^ 0xff ); //
                    break;

               /* ??? */
               case DSBF_SRCALPHASAT:
                    D_UNIMPLEMENTED();
                    break;

               default:
                    D_BUG( "unknown blend function %d", state->dst_blend );
          }

          /*
           * Add blended destination values to the scratch.
           */
          x.a += dst.a;
          x.r += dst.r;
          x.g += dst.g;
          x.b += dst.b;
     }

     /* Better not use the conversion from premultiplied to non-premultiplied! 
*/
     if (state->blittingflags & DSBLIT_DEMULTIPLY) {
          x.r = ((int)x.r << 8) / ((int)x.a + 1);
          x.g = ((int)x.g << 8) / ((int)x.a + 1);
          x.b = ((int)x.b << 8) / ((int)x.a + 1);
     }

     /*
      * Output
      */
     return x;
}
_______________________________________________
directfb-dev mailing list
directfb-dev@directfb.org
http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-dev

Reply via email to