diff options
author | Eric Anholt <anholt@freebsd.org> | 2004-08-14 20:29:28 +0000 |
---|---|---|
committer | Eric Anholt <anholt@freebsd.org> | 2004-08-14 20:29:28 +0000 |
commit | ed425d1d88a72586d5d7a4aad9d0be0b06637070 (patch) | |
tree | 3b665e0782a61190809aa5225f34c63dd2a711ad /hw | |
parent | cc3ad0ed4302f54318e190a2b10646337f242d40 (diff) |
Bug #1077: Fix source copy performance problem exposed by Composite.
Diffstat (limited to 'hw')
-rw-r--r-- | hw/xfree86/xaa/xaaPict.c | 77 |
1 files changed, 71 insertions, 6 deletions
diff --git a/hw/xfree86/xaa/xaaPict.c b/hw/xfree86/xaa/xaaPict.c index 7df806042..12523e85f 100644 --- a/hw/xfree86/xaa/xaaPict.c +++ b/hw/xfree86/xaa/xaaPict.c @@ -172,6 +172,10 @@ XAA_888_plus_PICT_a8_to_8888 ( } } +#define DRAWABLE_IS_ON_CARD(pDraw) \ + (pDraw->type == DRAWABLE_WINDOW || \ + (pDraw->type == DRAWABLE_PIXMAP && IS_OFFSCREEN_PIXMAP(pDraw))) + Bool XAADoComposite ( CARD8 op, @@ -198,13 +202,10 @@ XAADoComposite ( if(!REGION_NUM_RECTS(pDst->pCompositeClip)) return TRUE; - if(!infoRec->pScrn->vtSema || - ((pDst->pDrawable->type != DRAWABLE_WINDOW) && - !IS_OFFSCREEN_PIXMAP(pDst->pDrawable))) + if(!infoRec->pScrn->vtSema || !DRAWABLE_IS_ON_CARD(pDst->pDrawable)) return FALSE; - if((pSrc->pDrawable->type != DRAWABLE_PIXMAP) || - IS_OFFSCREEN_PIXMAP(pSrc->pDrawable)) + if(DRAWABLE_IS_ON_CARD(pSrc->pDrawable)) return FALSE; if (pSrc->transform || (pMask && pMask->transform)) @@ -425,6 +426,63 @@ XAADoComposite ( return FALSE; } +static void +XAACompositeSrcCopy (PicturePtr pSrc, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height) +{ + ScreenPtr pScreen = pDst->pDrawable->pScreen; + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); + int i, nbox; + int xoff, yoff; + BoxPtr pbox; + DDXPointPtr pptSrc; + RegionRec region; + + xDst += pDst->pDrawable->x; + yDst += pDst->pDrawable->y; + xSrc += pSrc->pDrawable->x; + ySrc += pSrc->pDrawable->y; + + if (!miComputeCompositeRegion (®ion, pSrc, NULL, pDst, + xSrc, ySrc, 0, 0, xDst, yDst, + width, height)) + return; + + nbox = REGION_NUM_RECTS(®ion); + pbox = REGION_RECTS(®ion); + + if(!nbox) { + REGION_UNINIT(pScreen, ®ion); + return; + } + pptSrc = ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox); + if (!pptSrc) { + REGION_UNINIT(pScreen, ®ion); + return; + } + xoff = xSrc - xDst; + yoff = ySrc - yDst; + for (i = 0; i < nbox; i++) { + pptSrc[i].x = pbox[i].x1 + xoff; + pptSrc[i].y = pbox[i].y1 + yoff; + } + + infoRec->ScratchGC.planemask = ~0L; + infoRec->ScratchGC.alu = GXcopy; + + XAADoBitBlt(pSrc->pDrawable, pDst->pDrawable, &infoRec->ScratchGC, ®ion, + pptSrc); + + DEALLOCATE_LOCAL(pptSrc); + REGION_UNINIT(pScreen, ®ion); + return; +} void XAAComposite (CARD8 op, @@ -444,7 +502,14 @@ XAAComposite (CARD8 op, XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); XAA_RENDER_PROLOGUE(pScreen, Composite); - if(!infoRec->Composite || + if((op == PictOpSrc) && !pMask && infoRec->pScrn->vtSema && + infoRec->ScreenToScreenBitBlt && + DRAWABLE_IS_ON_CARD(pSrc->pDrawable) && + DRAWABLE_IS_ON_CARD(pDst->pDrawable) && + !pSrc->transform && !pSrc->repeat && (pSrc->format == pDst->format)) + { + XAACompositeSrcCopy(pSrc, pDst, xSrc, ySrc, xDst, yDst, width, height); + } else if(!infoRec->Composite || !(*infoRec->Composite)(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height)) |