[PATCH 4/4] EXA/evergreen/ni: accelerate PictOpOver with component alpha

Michel Dänzer michel at daenzer.net
Tue Jul 30 08:26:39 PDT 2013


On Mon, 2013-07-22 at 06:06 +0200, Grigori Goronzy wrote:
> Subpixel text rendering is typically done with a solid src and a
> pixmap mask. Traditionally, this cannot be accelerated in a single
> pass and requires two passes [1]. However, we can cheat a little
> with a constant blend color.
> 
> We can use:
> 
> const.A = src.A / src.A
> const.R = src.R / src.A
> const.G = src.G / src.A
> const.B = src.B / src.A
> 
> dst.A = const.A * (src.A * mask.A) + (1 - (src.A * mask.A)) * dst.A
> dst.R = const.R * (src.A * mask.R) + (1 - (src.A * mask.R)) * dst.R
> dst.G = const.G * (src.A * mask.G) + (1 - (src.A * mask.G)) * dst.G
> dst.B = const.B * (src.A * mask.B) + (1 - (src.A * mask.B)) * dst.B
> 
> This only needs a single source value. src.A is cancelled down in
> the right places.
> 
> [1] http://anholt.livejournal.com/32058.html

Like Roland, I wonder if this trick couldn't be done in EXA instead of
in the driver?


> diff --git a/src/evergreen_exa.c b/src/evergreen_exa.c
> index 5b8a631..ee5b06b 100644
> --- a/src/evergreen_exa.c
> +++ b/src/evergreen_exa.c
> @@ -704,6 +704,14 @@ static uint32_t EVERGREENGetBlendCntl(int op, PicturePtr pMask, uint32_t dst_for
>  	} else if (dblend == (BLEND_ONE_MINUS_SRC_ALPHA << COLOR_DESTBLEND_shift)) {
>  	    dblend = (BLEND_ONE_MINUS_SRC_COLOR << COLOR_DESTBLEND_shift);
>  	}
> +
> +	/* With some tricks, we can still accelerate PictOpOver with solid src.
> +	 * This is commonly used for text rendering, so it's worth the extra
> +	 * effort.
> +	 */
> +	if (sblend == (BLEND_ONE << COLOR_SRCBLEND_shift)) {
> +	    sblend = (BLEND_CONSTANT_COLOR << COLOR_SRCBLEND_shift);
> +	}

Is this correct for all cases where (sblend == (BLEND_ONE <<
COLOR_SRCBLEND_shift))?


>  		if (EVERGREENBlendOp[op].src_alpha &&
>  		    (EVERGREENBlendOp[op].blend_cntl & COLOR_SRCBLEND_mask) !=
>  		    (BLEND_ZERO << COLOR_SRCBLEND_shift)) {
> -		    RADEON_FALLBACK(("Component alpha not supported with source "
> -				     "alpha and source value blending.\n"));
> +		    if (pSrcPicture->pDrawable || op != 3)
> +			RADEON_FALLBACK(("Component alpha not supported with source "
> +					 "alpha and source value blending.\n"));
>  		}
>  	    }

Please use PictOpOver instead of the magic number 3.


-- 
Earthling Michel Dänzer           |                   http://www.amd.com
Libre software enthusiast         |          Debian, X and DRI developer


More information about the xorg-driver-ati mailing list