summaryrefslogtreecommitdiff
path: root/render/picture.c
diff options
context:
space:
mode:
authorEric Anholt <anholt@freebsd.org>2006-02-12 20:53:35 +0000
committerEric Anholt <anholt@freebsd.org>2006-02-12 20:53:35 +0000
commit34d0b9228f46c2f87be74dddc9c7d97aab091d03 (patch)
tree1905bf59772a9f801a83fa711ec7803568312360 /render/picture.c
parent5f45776ef3b9256bea44842d1c50f269422531a1 (diff)
Simplify ops that would use the alpha channel when an alpha channel is
always 1.0, and short circuit PictOpDst for good measure.
Diffstat (limited to 'render/picture.c')
-rw-r--r--render/picture.c89
1 files changed, 89 insertions, 0 deletions
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,