aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nx-X11/programs/Xserver/hw/nxagent/NXpicture.c98
-rw-r--r--nx-X11/programs/Xserver/render/picture.c98
2 files changed, 196 insertions, 0 deletions
diff --git a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
index 67cd5d6ed..5087fa493 100644
--- a/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
+++ b/nx-X11/programs/Xserver/hw/nxagent/NXpicture.c
@@ -1800,6 +1800,99 @@ FreePictFormat (void * 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 CARD8
+ReduceCompositeOp (CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst)
+{
+ Bool no_src_alpha, no_dst_alpha;
+
+ no_src_alpha = PICT_FORMAT_COLOR(pSrc->format) &&
+ PICT_FORMAT_A(pSrc->format) == 0 &&
+ pSrc->alphaMap == NULL &&
+ pMask == NULL;
+ no_dst_alpha = PICT_FORMAT_COLOR(pDst->format) &&
+ PICT_FORMAT_A(pDst->format) == 0 &&
+ pDst->alphaMap == NULL;
+
+ /* TODO, maybe: Conjoint and Disjoint op reductions? */
+
+ /* Deal with simplifications where the source alpha is always 1. */
+ if (no_src_alpha)
+ {
+ 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 (no_dst_alpha)
+ {
+ 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,
@@ -1820,6 +1913,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,
diff --git a/nx-X11/programs/Xserver/render/picture.c b/nx-X11/programs/Xserver/render/picture.c
index 5d8496610..ddb21a07c 100644
--- a/nx-X11/programs/Xserver/render/picture.c
+++ b/nx-X11/programs/Xserver/render/picture.c
@@ -1649,6 +1649,99 @@ FreePictFormat (void * 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 CARD8
+ReduceCompositeOp (CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst)
+{
+ Bool no_src_alpha, no_dst_alpha;
+
+ no_src_alpha = PICT_FORMAT_COLOR(pSrc->format) &&
+ PICT_FORMAT_A(pSrc->format) == 0 &&
+ pSrc->alphaMap == NULL &&
+ pMask == NULL;
+ no_dst_alpha = PICT_FORMAT_COLOR(pDst->format) &&
+ PICT_FORMAT_A(pDst->format) == 0 &&
+ pDst->alphaMap == NULL;
+
+ /* TODO, maybe: Conjoint and Disjoint op reductions? */
+
+ /* Deal with simplifications where the source alpha is always 1. */
+ if (no_src_alpha)
+ {
+ 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 (no_dst_alpha)
+ {
+ 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,
@@ -1669,6 +1762,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,