From 3d4ca57b69c40d27fe191170d0819013f8cc4947 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 26 Apr 2006 18:27:40 +0000 Subject: [PATCH] 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. --- ChangeLog | 12 ++++++ exa/exa_render.c | 75 +++++++++++++++++++++++++++++------- hw/kdrive/ephyr/ephyr_draw.c | 6 +++ 3 files changed, 80 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 51b9c5224..79062bdaf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2006-04-26 Eric Anholt + + * 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 * hw/xfree86/os-support/bus/Pci.c: (pciSetOSBIOSPtr), 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 (®ion, 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, ®ion); - 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; diff --git a/hw/kdrive/ephyr/ephyr_draw.c b/hw/kdrive/ephyr/ephyr_draw.c index 0c1a5d0d3..84faecc00 100644 --- a/hw/kdrive/ephyr/ephyr_draw.c +++ b/hw/kdrive/ephyr/ephyr_draw.c @@ -226,6 +226,12 @@ static Bool ephyrCheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, 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; }