From 34d0b9228f46c2f87be74dddc9c7d97aab091d03 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sun, 12 Feb 2006 20:53:35 +0000 Subject: [PATCH] Simplify ops that would use the alpha channel when an alpha channel is always 1.0, and short circuit PictOpDst for good measure. --- ChangeLog | 8 +++++ render/picture.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) diff --git a/ChangeLog b/ChangeLog index 8b176052e..dd30630fe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2006-02-12 Eric Anholt + + reviewed by: keithp (in principle) + + * render/picture.c: (ReduceCompositeOp), (CompositePicture): + Simplify ops that would use the alpha channel when an alpha channel is + always 1.0, and short circuit PictOpDst for good measure. + 2006-02-12 Eric Anholt * hw/kdrive/linux/Makefile.am: diff --git a/render/picture.c b/render/picture.c index 70b049b0b..5b7b44b44 100644 --- a/render/picture.c +++ b/render/picture.c @@ -1657,6 +1657,90 @@ FreePictFormat (pointer pPictFormat, return Success; } +/** + * ReduceCompositeOp is used to choose simpler ops for cases where alpha + * channels are always one and so math on the alpha channel per pixel becomes + * unnecessary. It may also avoid destination reads sometimes if apps aren't + * being careful to avoid these cases. + */ +static Bool +ReduceCompositeOp (CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst) +{ + /* Deal with simplifications where the source alpha is always 1. */ + if (PICT_FORMAT_COLOR(pSrc->format) && + PICT_FORMAT_A(pSrc->format) == 0 && pSrc->alphaMap == NULL && + pMask == NULL) + { + switch (op) { + case PictOpOver: + op = PictOpSrc; + break; + case PictOpInReverse: + op = PictOpDst; + break; + case PictOpOutReverse: + op = PictOpClear; + break; + case PictOpAtop: + op = PictOpIn; + break; + case PictOpAtopReverse: + op = PictOpOverReverse; + break; + case PictOpXor: + op = PictOpOut; + break; + default: + break; + } + } + + /* Deal with simplifications when the destination alpha is always 1 */ + if (PICT_FORMAT_COLOR(pDst->format) && + PICT_FORMAT_A(pDst->format) == 0 && pDst->alphaMap == NULL) + { + switch (op) { + case PictOpOverReverse: + op = PictOpDst; + break; + case PictOpIn: + op = PictOpSrc; + break; + case PictOpOut: + op = PictOpClear; + break; + case PictOpAtop: + op = PictOpOver; + break; + case PictOpXor: + op = PictOpOutReverse; + break; + default: + break; + } + } + + /* Reduce some con/disjoint ops to the basic names. */ + switch (op) { + case PictOpDisjointClear: + case PictOpConjointClear: + op = PictOpClear; + break; + case PictOpDisjointSrc: + case PictOpConjointSrc: + op = PictOpSrc; + break; + case PictOpDisjointDst: + case PictOpConjointDst: + op = PictOpDst; + break; + default: + break; + } + + return op; +} + void CompositePicture (CARD8 op, PicturePtr pSrc, @@ -1677,6 +1761,11 @@ CompositePicture (CARD8 op, if (pMask) ValidatePicture (pMask); ValidatePicture (pDst); + + op = ReduceCompositeOp (op, pSrc, pMask, pDst); + if (op == PictOpDst) + return; + (*ps->Composite) (op, pSrc, pMask,