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.
This commit is contained in:
Eric Anholt 2006-04-26 18:27:40 +00:00
parent 26fa45b642
commit 3d4ca57b69
3 changed files with 80 additions and 13 deletions

View File

@ -1,3 +1,15 @@
2006-04-26 Eric Anholt <anholt@FreeBSD.org>
* exa/exa_render.c: (exaTryComponentAlphaHelper), (exaComposite),
(exaGlyphs):
* hw/kdrive/ephyr/ephyr_draw.c: (ephyrCheckComposite):
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.
2006-04-26 Dave Airlie <airlied@linux.ie> 2006-04-26 Dave Airlie <airlied@linux.ie>
* hw/xfree86/os-support/bus/Pci.c: (pciSetOSBIOSPtr), * hw/xfree86/os-support/bus/Pci.c: (pciSetOSBIOSPtr),

View File

@ -448,6 +448,47 @@ exaTryDriverComposite(CARD8 op,
return 1; 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 void
exaComposite(CARD8 op, exaComposite(CARD8 op,
@ -495,7 +536,7 @@ exaComposite(CARD8 op,
ret = exaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst, ret = exaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst,
width, height); width, height);
if (ret == 1) if (ret == 1)
goto bail; goto done;
} }
else if (!pSrc->repeat && !pSrc->transform && else if (!pSrc->repeat && !pSrc->transform &&
pSrc->format == pDst->format) pSrc->format == pDst->format)
@ -510,7 +551,7 @@ exaComposite(CARD8 op,
if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst, if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask, xDst, xSrc, ySrc, xMask, yMask, xDst,
yDst, width, height)) yDst, width, height))
goto bail; goto done;
exaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, NULL, exaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, NULL,
@ -518,7 +559,7 @@ exaComposite(CARD8 op,
xSrc - xDst, ySrc - yDst, xSrc - xDst, ySrc - yDst,
FALSE, FALSE, 0, NULL); FALSE, FALSE, 0, NULL);
REGION_UNINIT(pDst->pDrawable->pScreen, &region); REGION_UNINIT(pDst->pDrawable->pScreen, &region);
goto bail; goto done;
} }
} }
} }
@ -529,14 +570,25 @@ exaComposite(CARD8 op,
(yMask + height) <= pMask->pDrawable->height) (yMask + height) <= pMask->pDrawable->height)
pMask->repeat = 0; pMask->repeat = 0;
if (pExaScr->info->PrepareComposite && if (pExaScr->info->PrepareComposite &&
!pSrc->alphaMap && (!pMask || !pMask->alphaMap) && !pDst->alphaMap) !pSrc->alphaMap && (!pMask || !pMask->alphaMap) && !pDst->alphaMap)
{ {
ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask,
yMask, xDst, yDst, width, height); yMask, xDst, yDst, width, height);
if (ret == 1) 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) { if (ret != 0) {
@ -567,7 +619,7 @@ exaComposite(CARD8 op,
ExaCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc, ExaCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height); xMask, yMask, xDst, yDst, width, height);
bail: done:
pSrc->repeat = saveSrcRepeat; pSrc->repeat = saveSrcRepeat;
if (pMask) if (pMask)
pMask->repeat = saveMaskRepeat; pMask->repeat = saveMaskRepeat;
@ -745,13 +797,10 @@ exaGlyphs (CARD8 op,
} }
/* If the driver doesn't support accelerated composite, there's no point in /* 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 * going to this extra work. Assume that any driver that supports Composite
* component-alpha, which is likely accurate (at least until we make a CA * will be able to support component alpha using the two-pass helper.
* helper).
*/ */
if (!pExaScr->info->PrepareComposite || if (!pExaScr->info->PrepareComposite)
(maskFormat && NeedsComponent(maskFormat->format)) ||
(!maskFormat && nlist > 0 && NeedsComponent(list[0].format->format)))
{ {
miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs); miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
return; return;

View File

@ -226,6 +226,12 @@ static Bool
ephyrCheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, ephyrCheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
PicturePtr pDstPicture) PicturePtr pDstPicture)
{ {
/* Exercise the component alpha helper, so fail on this case like a normal
* driver
*/
if (pMaskPicture && pMaskPicture->componentAlpha && op == PictOpOver)
return FALSE;
return TRUE; return TRUE;
} }