xserver: Branch 'master' - 8 commits

Keith Packard keithp at kemper.freedesktop.org
Tue Dec 29 16:11:56 PST 2009


 exa/exa.c                   |    6 
 exa/exa_accel.c             |   46 +----
 exa/exa_migration_classic.c |    3 
 exa/exa_migration_mixed.c   |   55 +++---
 exa/exa_mixed.c             |   18 ++
 exa/exa_priv.h              |   15 +
 exa/exa_unaccel.c           |  347 +++++++++++++++++++++++++++++++++++---------
 7 files changed, 347 insertions(+), 143 deletions(-)

New commits:
commit db2c6f7c91289b5d49978974093a1002b3b53a56
Author: Michel Dänzer <daenzer at vmware.com>
Date:   Tue Dec 29 15:48:44 2009 +0100

    EXA: Don't use UTS/DFS directly for Put/GetImage when there's a system copy.
    
    We want to save the result in the system memory copy, in case we'll need it
    again for subsequent software fallbacks.
    
    Signed-off-by: Michel Dänzer <daenzer at vmware.com>
    Acked-By: Maarten Maathuis <madman2003 at gmail.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index f34b7a7..4c55a4c 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -157,6 +157,10 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
     if (pExaScr->fallback_counter || pExaPixmap->accel_blocked || !pExaScr->info->UploadToScreen)
 	return FALSE;
 
+    /* If there's a system copy, we want to save the result there */
+    if (pExaPixmap->pDamage)
+	return FALSE;
+
     /* Don't bother with under 8bpp, XYPixmaps. */
     if (format != ZPixmap || bpp < 8)
 	return FALSE;
@@ -168,17 +172,6 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
     if (pExaScr->swappedOut)
 	return FALSE;
 
-    if (pExaScr->do_migration) {
-	ExaMigrationRec pixmaps[1];
-
-	pixmaps[0].as_dst = TRUE;
-	pixmaps[0].as_src = FALSE;
-	pixmaps[0].pPix = pPix;
-	pixmaps[0].pReg = DamagePendingRegion(pExaPixmap->pDamage);
-
-	exaDoMigration (pixmaps, 1, TRUE);
-    }
-
     pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
 
     if (!pPix)
@@ -1261,35 +1254,16 @@ exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
 {
     ExaScreenPriv (pDrawable->pScreen);
     PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
+    ExaPixmapPriv(pPix);
     int xoff, yoff;
     Bool ok;
 
     if (pExaScr->fallback_counter || pExaScr->swappedOut)
 	goto fallback;
 
-    exaGetDrawableDeltas (pDrawable, pPix, &xoff, &yoff);
-
-    if (pExaScr->do_migration) {
-	BoxRec Box;
-	RegionRec Reg;
-	ExaMigrationRec pixmaps[1];
-
-	Box.x1 = pDrawable->x + x + xoff;
-	Box.y1 = pDrawable->y + y + yoff;
-	Box.x2 = Box.x1 + w;
-	Box.y2 = Box.y1 + h;
-
-	REGION_INIT(pScreen, &Reg, &Box, 1);
-
-	pixmaps[0].as_dst = FALSE;
-	pixmaps[0].as_src = TRUE;
-	pixmaps[0].pPix = pPix;
-	pixmaps[0].pReg = &Reg;
-
-	exaDoMigration(pixmaps, 1, FALSE);
-
-	REGION_UNINIT(pScreen, &Reg);
-    }
+    /* If there's a system copy, we want to save the result there */
+    if (pExaPixmap->pDamage)
+	goto fallback;
 
     pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
 
commit f28ca728e90ccbb901e8e7215a842525d8e786d3
Author: Thomas Hellstrom <thellstrom at vmware.com>
Date:   Tue Dec 29 12:51:30 2009 +0100

    EXA: Restrict the regions that need to be migrated for composite fallback for src / mask pictures.
    
    [ Michel: Minor fixups to address compiler warnings ]
    
    Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>
    Signed-off-by: Michel Dänzer <daenzer at vmware.com>
    Acked-by: Maarten Maathuis <madman2003 at gmail.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index c559b9a..21d9646 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -165,6 +165,7 @@ typedef struct {
     BitmapToRegionProcPtr        SavedBitmapToRegion;
     CreateScreenResourcesProcPtr SavedCreateScreenResources;
     ModifyPixmapHeaderProcPtr    SavedModifyPixmapHeader;
+    SourceValidateProcPtr        SavedSourceValidate;
 #ifdef RENDER
     CompositeProcPtr             SavedComposite;
     TrianglesProcPtr		 SavedTriangles;
@@ -201,6 +202,15 @@ typedef struct {
     unsigned int fallback_counter;
 
     ExaGlyphCacheRec             glyphCaches[EXA_NUM_GLYPH_CACHES];
+
+    /**
+     * Regions affected by fallback composite source / mask operations.
+     */
+
+    RegionRec srcReg;
+    RegionRec maskReg;
+    PixmapPtr srcPix;
+
 } ExaScreenPrivRec, *ExaScreenPrivPtr;
 
 /*
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index a97a309..b4ead7f 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -435,6 +435,173 @@ ExaCheckGetSpans (DrawablePtr pDrawable,
     EXA_POST_FALLBACK(pScreen);
 }
 
+static void
+ExaSrcValidate(DrawablePtr pDrawable,
+	       int x,
+	       int y,
+	       int width,
+	       int height)
+{
+    ScreenPtr pScreen = pDrawable->pScreen;
+    ExaScreenPriv(pScreen);
+    PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
+    BoxRec box;
+    RegionRec reg;
+    RegionPtr dst;
+    int xoff, yoff;
+
+    exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
+
+    box.x1 = x + xoff;
+    box.y1 = y + yoff;
+    box.x2 = box.x1 + width;
+    box.y2 = box.y1 + height;
+
+    dst = (pExaScr->srcPix == pPix) ? &pExaScr->srcReg :
+	&pExaScr->maskReg;
+
+    REGION_INIT(pScreen, &reg, &box, 1);
+    REGION_UNION(pScreen, dst, dst, &reg);
+    REGION_UNINIT(pScreen, &reg);
+
+    swap(pExaScr, pScreen, SourceValidate);
+    pScreen->SourceValidate(pDrawable, x, y, width, height);
+    swap(pExaScr, pScreen, SourceValidate);
+}
+
+static Bool
+ExaPrepareCompositeReg(ScreenPtr  pScreen,
+		       CARD8      op,
+		       PicturePtr pSrc,
+		       PicturePtr pMask,
+		       PicturePtr pDst,
+		       INT16      xSrc,
+		       INT16      ySrc,
+		       INT16      xMask,
+		       INT16      yMask,
+		       INT16      xDst,
+		       INT16      yDst,
+		       CARD16     width,
+		       CARD16     height)
+{
+    RegionRec region;
+    RegionPtr dstReg = NULL;
+    RegionPtr srcReg = NULL;
+    RegionPtr maskReg = NULL;
+    PixmapPtr pSrcPix = NULL;
+    PixmapPtr pMaskPix = NULL;
+    PixmapPtr pDstPix;
+    ExaScreenPriv(pScreen);
+    Bool ret;
+
+
+    REGION_NULL(pScreen, &region);
+
+    if (pSrc->pDrawable) {
+	pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
+	REGION_NULL(pScreen, &pExaScr->srcReg);
+	srcReg = &pExaScr->srcReg;
+	pExaScr->srcPix = pSrcPix;
+	if (pSrc != pDst)
+	    REGION_TRANSLATE(pScreen, pSrc->pCompositeClip,
+			     -pSrc->pDrawable->x,
+			     -pSrc->pDrawable->y);
+    }
+
+    if (pMask && pMask->pDrawable) {
+	pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
+	REGION_NULL(pScreen, &pExaScr->maskReg);
+	maskReg = &pExaScr->maskReg;
+	if (pMask != pDst && pMask != pSrc)
+	    REGION_TRANSLATE(pScreen, pMask->pCompositeClip,
+			     -pMask->pDrawable->x,
+			     -pMask->pDrawable->y);
+    }
+
+    REGION_TRANSLATE(pScreen, pDst->pCompositeClip,
+		     -pDst->pDrawable->x,
+		     -pDst->pDrawable->y);
+
+    pExaScr->SavedSourceValidate = ExaSrcValidate;
+    swap(pExaScr, pScreen, SourceValidate);
+    ret = miComputeCompositeRegion (&region, pSrc, pMask, pDst,
+				    xSrc, ySrc, xMask, yMask,
+				    xDst,
+				    yDst,
+				    width, height);
+    swap(pExaScr, pScreen, SourceValidate);
+
+    REGION_TRANSLATE(pScreen, pDst->pCompositeClip,
+		     pDst->pDrawable->x,
+		     pDst->pDrawable->y);
+    if (pSrc->pDrawable && pSrc != pDst)
+	REGION_TRANSLATE(pScreen, pSrc->pCompositeClip,
+			 pSrc->pDrawable->x,
+			 pSrc->pDrawable->y);
+    if (pMask && pMask->pDrawable && pMask != pDst && pMask != pSrc)
+	REGION_TRANSLATE(pScreen, pMask->pCompositeClip,
+			 pMask->pDrawable->x,
+			 pMask->pDrawable->y);
+
+    if (!ret) {
+	if (srcReg)
+	    REGION_UNINIT(pScreen, srcReg);
+	if (maskReg)
+	    REGION_UNINIT(pScreen, maskReg);
+
+	return FALSE;
+    }
+
+    /**
+     * Don't limit alphamaps readbacks for now until we've figured out how that
+     * should be done.
+     */
+
+    if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
+	pExaScr->prepare_access_reg(exaGetDrawablePixmap(pSrc->alphaMap->pDrawable),
+				    EXA_PREPARE_AUX_SRC,
+				    NULL);
+    if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
+	pExaScr->prepare_access_reg(exaGetDrawablePixmap(pMask->alphaMap->pDrawable),
+				    EXA_PREPARE_AUX_MASK,
+				    NULL);
+
+    if (pSrcPix)
+	pExaScr->prepare_access_reg(pSrcPix,
+				    EXA_PREPARE_SRC,
+				    srcReg);
+
+    if (pMaskPix)
+	pExaScr->prepare_access_reg(pMaskPix,
+				    EXA_PREPARE_MASK,
+				    maskReg);
+
+    if (srcReg)
+	REGION_UNINIT(pScreen, srcReg);
+    if (maskReg)
+	REGION_UNINIT(pScreen, maskReg);
+
+    pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
+    if (!exaOpReadsDestination(op)) {
+	int xoff;
+	int yoff;
+
+	exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &xoff, &yoff);
+	REGION_TRANSLATE(pScreen, &region, pDst->pDrawable->x + xoff,
+			 pDst->pDrawable->y + yoff);
+	dstReg = &region;
+    }
+
+    if (pDst->alphaMap && pDst->alphaMap->pDrawable)
+	pExaScr->prepare_access_reg(exaGetDrawablePixmap(pDst->alphaMap->pDrawable),
+				    EXA_PREPARE_AUX_DEST,
+				    dstReg);
+    pExaScr->prepare_access_reg(pDstPix, EXA_PREPARE_DEST, dstReg);
+
+    REGION_UNINIT(pScreen, &region);
+    return TRUE;
+}
+
 void
 ExaCheckComposite (CARD8      op,
                    PicturePtr pSrc,
@@ -453,54 +620,38 @@ ExaCheckComposite (CARD8      op,
 #ifdef RENDER
     PictureScreenPtr	ps = GetPictureScreen(pScreen);
 #endif /* RENDER */
-    RegionRec region;
-    int xoff, yoff;
     EXA_PRE_FALLBACK(pScreen);
 
-    REGION_NULL(pScreen, &region);
-
-    /* We need to prepare access to any separate alpha maps first, in case the
-     * driver doesn't support EXA_PREPARE_AUX*, in which case EXA_PREPARE_SRC
-     * may be used for moving them out.
-     */
-    if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
-	exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
-    if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
-	exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
-
-    if (!exaOpReadsDestination(op) && pExaScr->prepare_access_reg) {
-	PixmapPtr pDstPix;
-
-	if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
-				       xSrc, ySrc, xMask, yMask,
-				       xDst + pDst->pDrawable->x,
-				       yDst + pDst->pDrawable->y,
-				       width, height))
-	    goto skip;
-
-	pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
-	exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &xoff, &yoff);
-	REGION_TRANSLATE(pScreen, &region, xoff, yoff);
+    if (pExaScr->prepare_access_reg) {
+	if (!ExaPrepareCompositeReg(pScreen, op, pSrc, pMask, pDst, xSrc,
+				   ySrc, xMask, yMask, xDst, yDst, width,
+				   height))
+	    goto out_no_clip;
+    } else {
 
-	if (pDst->alphaMap && pDst->alphaMap->pDrawable)
-	    pExaScr->prepare_access_reg(exaGetDrawablePixmap(pDst->alphaMap->pDrawable),
-					EXA_PREPARE_AUX_DEST, &region);
+	/* We need to prepare access to any separate alpha maps first,
+	 * in case the driver doesn't support EXA_PREPARE_AUX*,
+	 * in which case EXA_PREPARE_SRC may be used for moving them out.
+	 */
 
-	pExaScr->prepare_access_reg(pDstPix, EXA_PREPARE_DEST, &region);
-    } else {
+	if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
+	    exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
+	if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
+	    exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
 	if (pDst->alphaMap && pDst->alphaMap->pDrawable)
 	    exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
 
 	exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST);
-    }
 
-    EXA_FALLBACK(("from picts %p/%p to pict %p\n",
-		 pSrc, pMask, pDst));
+	EXA_FALLBACK(("from picts %p/%p to pict %p\n",
+		      pSrc, pMask, pDst));
+
+	if (pSrc->pDrawable != NULL)
+	    exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
+	if (pMask && pMask->pDrawable != NULL)
+	    exaPrepareAccess (pMask->pDrawable, EXA_PREPARE_MASK);
+    }
 
-    if (pSrc->pDrawable != NULL)
-	exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
-    if (pMask && pMask->pDrawable != NULL)
-	exaPrepareAccess (pMask->pDrawable, EXA_PREPARE_MASK);
 #ifdef RENDER
     swap(pExaScr, ps, Composite);
     ps->Composite (op,
@@ -524,14 +675,12 @@ ExaCheckComposite (CARD8      op,
     exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST);
     if (pDst->alphaMap && pDst->alphaMap->pDrawable)
 	exaFinishAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
-
-skip:
     if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
 	exaFinishAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
     if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
 	exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
 
-    REGION_UNINIT(pScreen, &region);
+out_no_clip:
     EXA_POST_FALLBACK(pScreen);
 }
 
commit 0c1f43c0f3e888172f11f62a2f208af70e0183cc
Author: Michel Dänzer <daenzer at vmware.com>
Date:   Tue Dec 29 12:51:29 2009 +0100

    EXA/mixed: Handle results of software fallbacks in DamageReport hook.
    
    This is more elegant and probably also slightly more correct than doing it
    at FinishAccess time.
    
    Signed-off-by: Michel Dänzer <daenzer at vmware.com>
    Acked-by: Maarten Maathuis <madman2003 at gmail.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/exa/exa.c b/exa/exa.c
index b3c5bff..c5ac7de 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -425,9 +425,6 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
     /* We always hide the devPrivate.ptr. */
     pPixmap->devPrivate.ptr = NULL;
 
-    if (pExaScr->finish_access)
-	pExaScr->finish_access(pPixmap, index);
-
     if (!pExaScr->info->FinishAccess || !exaPixmapHasGpuCopy(pPixmap))
 	return;
 
@@ -981,7 +978,6 @@ exaDriverInit (ScreenPtr		pScreen,
 		pExaScr->do_move_in_pixmap = exaMoveInPixmap_mixed;
 		pExaScr->do_move_out_pixmap = NULL;
 		pExaScr->prepare_access_reg = exaPrepareAccessReg_mixed;
-		pExaScr->finish_access = exaFinishAccess_mixed;
 	    } else {
 		wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_driver);
 		wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_driver);
@@ -991,7 +987,6 @@ exaDriverInit (ScreenPtr		pScreen,
 		pExaScr->do_move_in_pixmap = NULL;
 		pExaScr->do_move_out_pixmap = NULL;
 		pExaScr->prepare_access_reg = NULL;
-		pExaScr->finish_access = NULL;
 	    }
 	} else {
 	    wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_classic);
@@ -1002,7 +997,6 @@ exaDriverInit (ScreenPtr		pScreen,
 	    pExaScr->do_move_in_pixmap = exaMoveInPixmap_classic;
 	    pExaScr->do_move_out_pixmap = exaMoveOutPixmap_classic;
 	    pExaScr->prepare_access_reg = exaPrepareAccessReg_classic;
-	    pExaScr->finish_access = NULL;
 	}
 	if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) {
 	    LogMessage(X_INFO, "EXA(%d): Offscreen pixmap area of %lu bytes\n",
diff --git a/exa/exa_migration_mixed.c b/exa/exa_migration_mixed.c
index 14cb5a7..6816e6c 100644
--- a/exa/exa_migration_mixed.c
+++ b/exa/exa_migration_mixed.c
@@ -134,10 +134,32 @@ exaMoveInPixmap_mixed(PixmapPtr pPixmap)
     exaDoMigration(pixmaps, 1, TRUE);
 }
 
+void
+exaDamageReport_mixed(DamagePtr pDamage, RegionPtr pRegion, void *closure)
+{
+    PixmapPtr pPixmap = closure;
+    ExaPixmapPriv(pPixmap);
+
+    /* Move back results of software rendering on system memory copy of mixed driver
+     * pixmap (see exaPrepareAccessReg_mixed).
+     *
+     * Defer moving the destination back into the driver pixmap, to try and save
+     * overhead on multiple subsequent software fallbacks.
+     */
+    if (!pExaPixmap->use_gpu_copy && exaPixmapHasGpuCopy(pPixmap)) {
+	ExaScreenPriv(pPixmap->drawable.pScreen);
+
+	if (pExaScr->deferred_mixed_pixmap &&
+	    pExaScr->deferred_mixed_pixmap != pPixmap)
+	    exaMoveInPixmap_mixed(pExaScr->deferred_mixed_pixmap);
+	pExaScr->deferred_mixed_pixmap = pPixmap;
+    }
+}
+
 /* With mixed pixmaps, if we fail to get direct access to the driver pixmap, we
  * use the DownloadFromScreen hook to retrieve contents to a copy in system
  * memory, perform software rendering on that and move back the results with the
- * UploadToScreen hook (see exaFinishAccess_mixed).
+ * UploadToScreen hook (see exaDamageReport_mixed).
  */
 void
 exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
@@ -172,8 +194,9 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
 	    Bool as_dst = pixmaps[0].as_dst;
 
 	    /* Set up damage tracking */
-	    pExaPixmap->pDamage = DamageCreate(NULL, NULL, DamageReportNone,
-					       TRUE, pPixmap->drawable.pScreen,
+	    pExaPixmap->pDamage = DamageCreate(exaDamageReport_mixed, NULL,
+					       DamageReportNonEmpty, TRUE,
+					       pPixmap->drawable.pScreen,
 					       pPixmap);
 
 	    DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage);
@@ -224,29 +247,3 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
     }
 }
 
-/* Move back results of software rendering on system memory copy of mixed driver
- * pixmap (see exaPrepareAccessReg_mixed).
- *
- * Defer moving the destination back into the driver pixmap, to try and save
- * overhead on multiple consequent software fallbacks.
- */
-void exaFinishAccess_mixed(PixmapPtr pPixmap, int index)
-{
-    ExaPixmapPriv(pPixmap);
-
-    if (pExaPixmap->pDamage && !pExaPixmap->use_gpu_copy &&
-	    exaPixmapHasGpuCopy(pPixmap)) {
-	DamageRegionProcessPending(&pPixmap->drawable);
-
-	if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) {
-	    ExaScreenPriv(pPixmap->drawable.pScreen);
-
-	    if (pExaScr->deferred_mixed_pixmap &&
-		pExaScr->deferred_mixed_pixmap != pPixmap)
-		exaMoveInPixmap_mixed(pExaScr->deferred_mixed_pixmap);
-	    pExaScr->deferred_mixed_pixmap = pPixmap;
-	    pPixmap->devKind = pExaPixmap->fb_pitch;
-	} else
-	    exaMoveInPixmap_mixed(pPixmap);
-    }
-}
diff --git a/exa/exa_mixed.c b/exa/exa_mixed.c
index b262fc7..21cc3bd 100644
--- a/exa/exa_mixed.c
+++ b/exa/exa_mixed.c
@@ -101,7 +101,7 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
 	    pExaPixmap->sys_ptr = malloc((pPixmap->drawable.bitsPerPixel + 7) / 8);
 
 	    /* Set up damage tracking */
-	    pExaPixmap->pDamage = DamageCreate(NULL, NULL,
+	    pExaPixmap->pDamage = DamageCreate(exaDamageReport_mixed, NULL,
 					       DamageReportNonEmpty, TRUE,
 					       pPixmap->drawable.pScreen,
 					       pPixmap);
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 0852355..c559b9a 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -177,7 +177,6 @@ typedef struct {
     void (*do_move_in_pixmap) (PixmapPtr pPixmap);
     void (*do_move_out_pixmap) (PixmapPtr pPixmap);
     void (*prepare_access_reg)(PixmapPtr pPixmap, int index, RegionPtr pReg);
-    void (*finish_access)(PixmapPtr pPixmap, int index);
 
     Bool			 swappedOut;
     enum ExaMigrationHeuristic	 migration;
@@ -620,10 +619,10 @@ void
 exaMoveInPixmap_mixed(PixmapPtr pPixmap);
 
 void
-exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg);
+exaDamageReport_mixed(DamagePtr pDamage, RegionPtr pRegion, void *closure);
 
 void
-exaFinishAccess_mixed(PixmapPtr pPixmap, int index);
+exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg);
 
 /* exa_render.c */
 Bool
commit 08bf26c28fc8147b64f2fe8345b9581e0101571c
Author: Michel Dänzer <daenzer at vmware.com>
Date:   Tue Dec 29 12:51:28 2009 +0100

    EXA: Fix migration avoidance for 1x1 pixmaps.
    
    Signed-off-by: Michel Dänzer <daenzer at vmware.com>
    Acked-by: Maarten Maathuis <madman2003 at gmail.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index c56c6bc..f34b7a7 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -1043,6 +1043,7 @@ exaFillRegionSolid (DrawablePtr	pDrawable, RegionPtr pRegion, Pixel pixel,
 	    pDrawable->width == 1 && pDrawable->height == 1 &&
 	    pDrawable->bitsPerPixel != 24) {
 	    ExaPixmapPriv(pPixmap);
+	    RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
 
 	    switch (pDrawable->bitsPerPixel) {
 	    case 32:
@@ -1057,6 +1058,9 @@ exaFillRegionSolid (DrawablePtr	pDrawable, RegionPtr pRegion, Pixel pixel,
 
 	    REGION_UNION(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys,
 			 pRegion);
+	    REGION_UNION(pScreen, &pExaPixmap->validFB, &pExaPixmap->validFB,
+			 pRegion);
+	    REGION_SUBTRACT(pScreen, pending_damage, pending_damage, pRegion);
 	}
 
 	ret = TRUE;
diff --git a/exa/exa_mixed.c b/exa/exa_mixed.c
index 155ed47..b262fc7 100644
--- a/exa/exa_mixed.c
+++ b/exa/exa_mixed.c
@@ -94,9 +94,25 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
     if (!w || !h) {
 	exaCreateDriverPixmap_mixed(pPixmap);
 	pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
-    } else
+    } else {
 	pExaPixmap->use_gpu_copy = FALSE;
 
+	if (w == 1 && h == 1) {
+	    pExaPixmap->sys_ptr = malloc((pPixmap->drawable.bitsPerPixel + 7) / 8);
+
+	    /* Set up damage tracking */
+	    pExaPixmap->pDamage = DamageCreate(NULL, NULL,
+					       DamageReportNonEmpty, TRUE,
+					       pPixmap->drawable.pScreen,
+					       pPixmap);
+
+	    DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage);
+	    /* This ensures that pending damage reflects the current operation. */
+	    /* This is used by exa to optimize migration. */
+	    DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE);
+	}
+    }
+
     /* During a fallback we must prepare access. */
     if (pExaScr->fallback_counter)
 	exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
commit 0bd8f0cd7f3823ee17ae8c88fd3e004bfff9982d
Author: Michel Dänzer <daenzer at vmware.com>
Date:   Tue Dec 29 12:51:27 2009 +0100

    EXA/classic: Fix crash with migration heuristic "smart".
    
    Signed-off-by: Michel Dänzer <daenzer at vmware.com>
    Acked-by: Maarten Maathuis <madman2003 at gmail.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/exa/exa_migration_classic.c b/exa/exa_migration_classic.c
index 95189be..871679f 100644
--- a/exa/exa_migration_classic.c
+++ b/exa/exa_migration_classic.c
@@ -75,6 +75,9 @@ exaPixmapIsDirty (PixmapPtr pPix)
     if (pExaPixmap == NULL)
 	EXA_FatalErrorDebugWithRet(("EXA bug: exaPixmapIsDirty was called on a non-exa pixmap.\n"), TRUE);
 
+    if (!pExaPixmap->pDamage)
+	return FALSE;
+
     return REGION_NOTEMPTY (pScreen, DamageRegion(pExaPixmap->pDamage)) ||
 	!REGION_EQUAL(pScreen, &pExaPixmap->validSys, &pExaPixmap->validFB);
 }
commit 40453bf7718f1c3d672b87e9d84991032cbef859
Author: Thomas Hellstrom <thellstrom at vmware.com>
Date:   Tue Dec 29 09:34:44 2009 +0100

    EXA: Limit src prepareAccess regions for a number of unaccelerated operations.
    
    When we can trivially calculate the affected source regions,
    do that before calling region bounded prepareAccess.
    
    [ Michel: Minor fixups to address compiler warnings ]
    
    Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>
    Signed-off-by: Michel Dänzer <daenzer at vmware.com>
    Acked-by: Maarten Maathuis <madman2003 at gmail.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index f077fc8..a97a309 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -123,11 +123,36 @@ ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst,  GCPtr pGC,
 	     BoxPtr	pbox, int nbox, int dx, int dy, Bool	reverse, 
 	     Bool upsidedown, Pixel bitplane, void *closure)
 {
+    RegionRec reg;
+    int xoff, yoff;
     EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
 		  exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
-    exaPrepareAccess (pDst, EXA_PREPARE_DEST);
-    exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
+
+    if (pExaScr->prepare_access_reg) {
+	PixmapPtr pPixmap = exaGetDrawablePixmap(pSrc);
+
+	exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff);
+	REGION_INIT(pScreen, &reg, pbox, nbox);
+	REGION_TRANSLATE(pScreen, &reg, xoff + dx, yoff + dy);
+	pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, &reg);
+	REGION_UNINIT(pScreen, &reg);
+    } else
+	exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
+
+    if (pExaScr->prepare_access_reg &&
+	!exaGCReadsDestination(pDst, pGC->planemask, pGC->fillStyle,
+			       pGC->alu, pGC->clientClipType)) {
+	PixmapPtr pPixmap = exaGetDrawablePixmap(pDst);
+
+	exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff);
+	REGION_INIT(pScreen, &reg, pbox, nbox);
+	REGION_TRANSLATE(pScreen, &reg, xoff, yoff);
+	pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, &reg);
+	REGION_UNINIT(pScreen, &reg);
+    } else
+	exaPrepareAccess (pDst, EXA_PREPARE_DEST);
+
     /* This will eventually call fbCopyNtoN, with some calculation overhead. */
     while (nbox--) {
 	pGC->ops->CopyArea (pSrc, pDst, pGC, pbox->x1 - pSrc->x + dx, pbox->y1 - pSrc->y + dy, 
@@ -139,6 +164,40 @@ ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst,  GCPtr pGC,
     EXA_POST_FALLBACK_GC(pGC);
 }
 
+static void
+ExaFallbackPrepareReg(DrawablePtr pDrawable,
+		      GCPtr pGC,
+		      int x, int y, int width, int height,
+		      int index, Bool checkReads)
+{
+    ScreenPtr pScreen = pDrawable->pScreen;
+    ExaScreenPriv(pScreen);
+
+    if (pExaScr->prepare_access_reg &&
+	!(checkReads && exaGCReadsDestination(pDrawable,
+					      pGC->planemask,
+					      pGC->fillStyle,
+					      pGC->alu,
+					      pGC->clientClipType))) {
+	BoxRec box;
+	RegionRec reg;
+	int xoff, yoff;
+	PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+
+	exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
+	box.x1 = pDrawable->x + x + xoff;
+	box.y1 = pDrawable->y + y + yoff;
+	box.x2 = box.x1 + width;
+	box.y2 = box.y1 + height;
+
+	REGION_INIT(pScreen, &reg, &box, 1);
+	pExaScr->prepare_access_reg(pPixmap, index, &reg);
+	REGION_UNINIT(pScreen, &reg);
+    } else
+	exaPrepareAccess(pDrawable, index);
+}
+
+
 RegionPtr
 ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
 		 int srcx, int srcy, int w, int h, int dstx, int dsty)
@@ -148,8 +207,10 @@ ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
     EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
 		  exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
-    exaPrepareAccess (pDst, EXA_PREPARE_DEST);
-    exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
+    ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h,
+			  EXA_PREPARE_SRC, FALSE);
+    ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h,
+			  EXA_PREPARE_DEST, TRUE);
     ret = pGC->ops->CopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
     exaFinishAccess (pSrc, EXA_PREPARE_SRC);
     exaFinishAccess (pDst, EXA_PREPARE_DEST);
@@ -168,8 +229,10 @@ ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
     EXA_PRE_FALLBACK_GC(pGC);
     EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
 		  exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
-    exaPrepareAccess (pDst, EXA_PREPARE_DEST);
-    exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
+    ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h,
+			  EXA_PREPARE_SRC, FALSE);
+    ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h,
+			  EXA_PREPARE_DEST, TRUE);
     ret = pGC->ops->CopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
 		       bitPlane);
     exaFinishAccess (pSrc, EXA_PREPARE_SRC);
@@ -295,8 +358,10 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
     EXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap, pDrawable,
 		  exaDrawableLocation(&pBitmap->drawable),
 		  exaDrawableLocation(pDrawable)));
-    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
-    exaPrepareAccess (&pBitmap->drawable, EXA_PREPARE_SRC);
+    ExaFallbackPrepareReg(pDrawable, pGC, x, y, w, h,
+			  EXA_PREPARE_DEST, TRUE);
+    ExaFallbackPrepareReg(&pBitmap->drawable, pGC, 0, 0, w, h,
+			  EXA_PREPARE_SRC, FALSE);
     exaPrepareAccessGC (pGC);
     pGC->ops->PushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
     exaFinishAccessGC (pGC);
@@ -337,29 +402,12 @@ ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
 		unsigned int format, unsigned long planeMask, char *d)
 {
     ScreenPtr pScreen = pDrawable->pScreen;
-    PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
     EXA_PRE_FALLBACK(pScreen);
     EXA_FALLBACK(("from %p (%c)\n", pDrawable,
 		  exaDrawableLocation(pDrawable)));
 
-    if (pExaScr->prepare_access_reg) {
-	int xoff, yoff;
-	BoxRec Box;
-	RegionRec Reg;
-
-	exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
-
-	Box.x1 = pDrawable->x + x + xoff;
-	Box.y1 = pDrawable->y + y + yoff;
-	Box.x2 = Box.x1 + w;
-	Box.y2 = Box.y1 + h;
-
-	REGION_INIT(pScreen, &Reg, &Box, 1);
-
-	pExaScr->prepare_access_reg(pPix, EXA_PREPARE_SRC, &Reg);
-    } else
-	exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
-
+    ExaFallbackPrepareReg(pDrawable, NULL, x, y, w, h,
+			  EXA_PREPARE_SRC, FALSE);
     swap(pExaScr, pScreen, GetImage);
     pScreen->GetImage (pDrawable, x, y, w, h, format, planeMask, d);
     swap(pExaScr, pScreen, GetImage);
commit aa9ce8ab343d51a67924757c5a43c9572248bb24
Author: Michel Dänzer <daenzer at vmware.com>
Date:   Tue Dec 29 09:34:43 2009 +0100

    EXA: Use relevant source region to minimize migration on CopyWindow fallbacks.
    
    Signed-off-by: Michel Dänzer <daenzer at vmware.com>
    Acked-by: Maarten Maathuis <madman2003 at gmail.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index 0dbcd53..f077fc8 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -313,8 +313,18 @@ ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
     EXA_PRE_FALLBACK(pScreen);
     EXA_FALLBACK(("from %p\n", pWin));
 
-    /* being both src and dest, src is safest. */
-    exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
+    /* Only need the source bits, the destination region will be overwritten */
+    if (pExaScr->prepare_access_reg) {
+	PixmapPtr pPixmap = pScreen->GetWindowPixmap(pWin);
+	int xoff, yoff;
+
+	exaGetDrawableDeltas(&pWin->drawable, pPixmap, &xoff, &yoff);
+	REGION_TRANSLATE(pScreen, prgnSrc, xoff, yoff);
+	pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, prgnSrc);
+	REGION_TRANSLATE(pScreen, prgnSrc, -xoff, -yoff);
+    } else
+	exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
+
     swap(pExaScr, pScreen, CopyWindow);
     pScreen->CopyWindow (pWin, ptOldOrg, prgnSrc);
     swap(pExaScr, pScreen, CopyWindow);
commit 39cc110caa1f6481a7213ae39f82669333ec1645
Author: Thomas Hellstrom <thellstrom at vmware.com>
Date:   Tue Dec 29 09:34:42 2009 +0100

    EXA: Fix bugs in exaGetImage / ExaCheckGetImage migration.
    
    Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>
    Acked-by: Michel Dänzer <michel at daenzer.net>
    Acked-by: Maarten Maathuis <madman2003 at gmail.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 0f6e5f7..c56c6bc 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -1270,7 +1270,7 @@ exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
 	RegionRec Reg;
 	ExaMigrationRec pixmaps[1];
 
-	Box.x1 = pDrawable->y + x + xoff;
+	Box.x1 = pDrawable->x + x + xoff;
 	Box.y1 = pDrawable->y + y + yoff;
 	Box.x2 = Box.x1 + w;
 	Box.y2 = Box.y1 + h;
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index eee14da..0dbcd53 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -339,7 +339,7 @@ ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
 
 	exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
 
-	Box.x1 = pDrawable->y + x + xoff;
+	Box.x1 = pDrawable->x + x + xoff;
 	Box.y1 = pDrawable->y + y + yoff;
 	Box.x2 = Box.x1 + w;
 	Box.y2 = Box.y1 + h;


More information about the xorg-commit mailing list