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