[PATCH] exa/mixed: avoid unnecessary dest system buffer copy in prepare_access_reg

Karl Tomlinson karlt+ at karlt.net
Thu Aug 26 03:29:35 PDT 2010


A region is only provided to prepare_access_reg for destination pixmaps when
the operator will not read from the destination.  A non-NULL region therefore
indicates that no pixels in the destination gpu buffer need to be copied to
the system buffer.

The provided region still serves a purpose, as it indicates the portion of
the system buffer that will be damaged.
---
 exa/exa_migration_mixed.c |   42 ++++++++++++++++++++++++++++--------------
 1 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/exa/exa_migration_mixed.c b/exa/exa_migration_mixed.c
index fb47151..605235e 100644
--- a/exa/exa_migration_mixed.c
+++ b/exa/exa_migration_mixed.c
@@ -196,6 +196,8 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
     }
 
     if (!success) {
+	BoxRec box;
+	RegionRec region_all;
 	ExaMigrationRec pixmaps[1];
 
 	/* Do we need to allocate our system buffer? */
@@ -207,15 +209,27 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
 			   pExaPixmap->sys_pitch * pPixmap->drawable.height);
 	}
 
+	box.x1 = 0;
+	box.y1 = 0;
+	box.x2 = pPixmap->drawable.width;
+	box.y2 = pPixmap->drawable.height;
+	RegionInit(&region_all, &box, 1);
+
+	pixmaps[0].pPix = pPixmap;
+	pixmaps[0].pReg = pReg;
 	if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) {
+	    /* A pReg for a destination indicates that the operator will not
+	     * read from the destination, and so there is no need to copy any
+	     * pixels.  The valid regions will still be updated.
+	     */
+	    if (pReg)
+		pixmaps[0].pReg = &region_all;
 	    pixmaps[0].as_dst = TRUE;
 	    pixmaps[0].as_src = FALSE;
 	} else {
 	    pixmaps[0].as_dst = FALSE;
 	    pixmaps[0].as_src = TRUE;
 	}
-	pixmaps[0].pPix = pPixmap;
-	pixmaps[0].pReg = pReg;
 
 	if (!pExaPixmap->pDamage &&
 		(has_gpu_copy || !exaPixmapIsPinned(pPixmap))) {
@@ -232,27 +246,27 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
 	    /* This is used by exa to optimize migration. */
 	    DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE);
 
-	    if (has_gpu_copy) {
+	    if (has_gpu_copy)
 		exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width,
 			       pPixmap->drawable.height);
 
-		/* We don't know which region of the destination will be damaged,
-		 * have to assume all of it
-		 */
-		if (as_dst) {
-		    pixmaps[0].as_dst = FALSE;
-		    pixmaps[0].as_src = TRUE;
-		    pixmaps[0].pReg = NULL;
-		}
+	    /* When we don't know which region of the destination will be
+	     * damaged, have to assume all of it
+	     */
+	    if (as_dst)
+		DamageRegionAppend(&pPixmap->drawable,
+				   pReg ? pReg : &region_all);
+
+	    if (has_gpu_copy)
 		exaCopyDirtyToSys(pixmaps);
-	    }
 
 	    if (as_dst)
-		exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width,
-			       pPixmap->drawable.height);
+		DamageRegionProcessPending(&pPixmap->drawable);
 	} else if (has_gpu_copy)
 	    exaCopyDirtyToSys(pixmaps);
 
+	RegionUninit(&region_all);
+
 	pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
 	pPixmap->devKind = pExaPixmap->sys_pitch;
 	pExaPixmap->use_gpu_copy = FALSE;
-- 
1.7.1


--=-=-=--


More information about the xorg-devel mailing list