summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <anholt@freebsd.org>2004-08-14 20:29:28 +0000
committerEric Anholt <anholt@freebsd.org>2004-08-14 20:29:28 +0000
commited425d1d88a72586d5d7a4aad9d0be0b06637070 (patch)
tree3b665e0782a61190809aa5225f34c63dd2a711ad
parentcc3ad0ed4302f54318e190a2b10646337f242d40 (diff)
Bug #1077: Fix source copy performance problem exposed by Composite.
-rw-r--r--hw/xfree86/xaa/xaaPict.c77
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 (&region, pSrc, NULL, pDst,
+ xSrc, ySrc, 0, 0, xDst, yDst,
+ width, height))
+ return;
+
+ nbox = REGION_NUM_RECTS(&region);
+ pbox = REGION_RECTS(&region);
+
+ if(!nbox) {
+ REGION_UNINIT(pScreen, &region);
+ return;
+ }
+ pptSrc = ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
+ if (!pptSrc) {
+ REGION_UNINIT(pScreen, &region);
+ 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, &region,
+ pptSrc);
+
+ DEALLOCATE_LOCAL(pptSrc);
+ REGION_UNINIT(pScreen, &region);
+ 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))