summaryrefslogtreecommitdiff
path: root/exa
diff options
context:
space:
mode:
authorEric Anholt <anholt@freebsd.org>2006-04-26 18:27:40 +0000
committerEric Anholt <anholt@freebsd.org>2006-04-26 18:27:40 +0000
commit3d4ca57b69c40d27fe191170d0819013f8cc4947 (patch)
tree80443294e0bbbabb093daa5fc5f349028cc55340 /exa
parent26fa45b64258894201496f921eccb0cb7028c28c (diff)
Add a helper for the Component Alpha Over case, which breaks the operation
down into an OutReverse and an Add. Turn off the fallback to software glyphs when component alpha, now that we expect all (new) drivers to be able to support it. Also, make Xephyr fall back in the CA Over case to exercise this code. This speeds up my rgb24text and ls -lR in gnome-terminal by a factor of 5.
Diffstat (limited to 'exa')
-rw-r--r--exa/exa_render.c75
1 files changed, 62 insertions, 13 deletions
diff --git a/exa/exa_render.c b/exa/exa_render.c
index cdf323a76..0cf5176bf 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -1,4 +1,4 @@
- /*
+/*
* Copyright © 2001 Keith Packard
*
* Partly based on code that is Copyright © The XFree86 Project Inc.
@@ -448,6 +448,47 @@ exaTryDriverComposite(CARD8 op,
return 1;
}
+static int
+exaTryComponentAlphaHelper(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ ExaScreenPriv (pDst->pDrawable->pScreen);
+
+ assert(op == PictOpOver);
+ assert(pMask->componentAlpha == TRUE);
+
+ if (pExaScr->info->CheckComposite &&
+ (!(*pExaScr->info->CheckComposite)(PictOpOutReverse, pSrc, pMask,
+ pDst) ||
+ !(*pExaScr->info->CheckComposite)(PictOpAdd, pSrc, pMask, pDst)))
+ {
+ return -1;
+ }
+
+ /* Now, we think we should be able to accelerate this operation. First,
+ * composite the destination to be the destination times the source alpha
+ * factors.
+ */
+ exaComposite(PictOpOutReverse, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
+ xDst, yDst, width, height);
+
+ /* Then, add in the source value times the destination alpha factors (1.0).
+ */
+ exaComposite(PictOpAdd, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
+ xDst, yDst, width, height);
+
+ return 1;
+}
void
exaComposite(CARD8 op,
@@ -495,7 +536,7 @@ exaComposite(CARD8 op,
ret = exaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst,
width, height);
if (ret == 1)
- goto bail;
+ goto done;
}
else if (!pSrc->repeat && !pSrc->transform &&
pSrc->format == pDst->format)
@@ -510,7 +551,7 @@ exaComposite(CARD8 op,
if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask, xDst,
yDst, width, height))
- goto bail;
+ goto done;
exaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, NULL,
@@ -518,7 +559,7 @@ exaComposite(CARD8 op,
xSrc - xDst, ySrc - yDst,
FALSE, FALSE, 0, NULL);
REGION_UNINIT(pDst->pDrawable->pScreen, &region);
- goto bail;
+ goto done;
}
}
}
@@ -529,14 +570,25 @@ exaComposite(CARD8 op,
(yMask + height) <= pMask->pDrawable->height)
pMask->repeat = 0;
-
if (pExaScr->info->PrepareComposite &&
!pSrc->alphaMap && (!pMask || !pMask->alphaMap) && !pDst->alphaMap)
{
ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask,
yMask, xDst, yDst, width, height);
if (ret == 1)
- goto bail;
+ goto done;
+
+ /* If we couldn't do the Composite in a single pass, and it was a
+ * component-alpha Over, see if we can do it in two passes with
+ * an OutReverse and then an Add.
+ */
+ if (ret == -1 && pMask && pMask->componentAlpha && op == PictOpOver) {
+ ret = exaTryComponentAlphaHelper(op, pSrc, pMask, pDst, xSrc, ySrc,
+ xMask, yMask, xDst, yDst,
+ width, height);
+ if (ret == 1)
+ goto done;
+ }
}
if (ret != 0) {
@@ -567,7 +619,7 @@ exaComposite(CARD8 op,
ExaCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height);
- bail:
+done:
pSrc->repeat = saveSrcRepeat;
if (pMask)
pMask->repeat = saveMaskRepeat;
@@ -745,13 +797,10 @@ exaGlyphs (CARD8 op,
}
/* If the driver doesn't support accelerated composite, there's no point in
- * going to this extra work. Assume that no driver will be able to do
- * component-alpha, which is likely accurate (at least until we make a CA
- * helper).
+ * going to this extra work. Assume that any driver that supports Composite
+ * will be able to support component alpha using the two-pass helper.
*/
- if (!pExaScr->info->PrepareComposite ||
- (maskFormat && NeedsComponent(maskFormat->format)) ||
- (!maskFormat && nlist > 0 && NeedsComponent(list[0].format->format)))
+ if (!pExaScr->info->PrepareComposite)
{
miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
return;