xserver: Branch 'master' - 4 commits

Michel Daenzer daenzer at kemper.freedesktop.org
Sat May 24 11:11:22 PDT 2008


 exa/exa.c                  |   17 ++++++++++
 exa/exa_accel.c            |   72 +++++++++++++++++++++++----------------------
 exa/exa_migration.c        |    8 ++++-
 exa/exa_priv.h             |    1 
 exa/exa_unaccel.c          |    5 ++-
 hw/xfree86/exa/exa.man.pre |    6 ---
 hw/xfree86/exa/examodule.c |    2 -
 7 files changed, 66 insertions(+), 45 deletions(-)

New commits:
commit 29586101dc11d498b212510f8dedbfeca7f8c859
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sat May 24 20:01:41 2008 +0200

    EXA: Only record damage generated by rendering operations.
    
    Recording damage from other operations (e.g. creating a client damage record)
    may confuse the migration code resulting in corruption.
    
    Option "EXAOptimizeMigration" appears safe now, so enable it by default. Also
    remove it from the manpage, as it should only be necessary on request in the
    course of bug report diagnostics anymore.

diff --git a/exa/exa.c b/exa/exa.c
index 809fb4b..fc04748 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -261,6 +261,21 @@ exaSetFbPitch(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap,
                                      pExaScr->info->pixmapPitchAlign);
 }
 
+
+static void
+ExaDamageReport(DamagePtr pDamage, RegionPtr pReg, void *pClosure)
+{
+    PixmapPtr pPixmap = pClosure;
+    ExaPixmapPriv(pPixmap);
+    RegionPtr pDamageReg = DamageRegion(pDamage);
+
+    if (pExaPixmap->pendingDamage) {
+	REGION_UNION(pScreen, pDamageReg, pDamageReg, pReg);
+	pExaPixmap->pendingDamage = FALSE;
+    }
+}
+
+
 /**
  * exaCreatePixmap() creates a new pixmap.
  *
@@ -352,7 +367,7 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth,
     pExaPixmap->area = NULL;
 
     /* Set up damage tracking */
-    pExaPixmap->pDamage = DamageCreate (NULL, NULL, DamageReportNone, TRUE,
+    pExaPixmap->pDamage = DamageCreate (ExaDamageReport, NULL, DamageReportRawRegion, TRUE,
 					pScreen, pPixmap);
 
     if (pExaPixmap->pDamage == NULL) {
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index edaec23..1dbb269 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -262,6 +262,7 @@ exaDoShmPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
     if (format == ZPixmap)
     {
 	PixmapPtr pPixmap;
+	ExaPixmapPriv(exaGetDrawablePixmap(pDrawable));
 
 	pPixmap = GetScratchPixmapHeader(pDrawable->pScreen, w, h, depth,
 		BitsPerPixel(depth), PixmapBytePad(w, depth), (pointer)data);
@@ -272,7 +273,8 @@ exaDoShmPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
 				  pGC->alu))
 	    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
 	else
-	    ExaDoPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+	    exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST,
+				 DamagePendingRegion(pExaPixmap->pDamage));
 	fbCopyArea((DrawablePtr)pPixmap, pDrawable, pGC, sx, sy, sw, sh, dx, dy);
 	exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
 
@@ -316,7 +318,7 @@ exaShmPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, unsigned int format,
 				  pGC->alu))
 	    exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
 	else
-	    ExaDoPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+	    exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, &region);
 	fbShmPutImage(pDrawable, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
 		      data);
 	exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
diff --git a/exa/exa_migration.c b/exa/exa_migration.c
index 5f22474..3c79f68 100644
--- a/exa/exa_migration.c
+++ b/exa/exa_migration.c
@@ -301,6 +301,9 @@ exaDoMoveInPixmap (ExaMigrationPtr migrate)
     ExaScreenPriv (pScreen);
     ExaPixmapPriv (pPixmap);
 
+    if (migrate->as_dst)
+	pExaPixmap->pendingDamage = TRUE;
+
     /* If we're VT-switched away, no touching card memory allowed. */
     if (pExaScr->swappedOut)
 	return;
@@ -369,6 +372,9 @@ exaDoMoveOutPixmap (ExaMigrationPtr migrate)
     PixmapPtr pPixmap = migrate->pPix;
     ExaPixmapPriv (pPixmap);
 
+    if (migrate->as_dst)
+	pExaPixmap->pendingDamage = TRUE;
+
     if (!pExaPixmap->area || exaPixmapIsPinned(pPixmap))
 	return;
 
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index f3b72ae..9ec2a56 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -226,6 +226,7 @@ typedef struct {
      * location.
      */
     DamagePtr	    pDamage;
+    Bool	    pendingDamage;
     /**
      * The valid regions mark the valid bits (at least, as they're derived from
      * damage, which may be overreported) of a pixmap's system and FB copies.
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index c55ef03..5a25764 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -97,12 +97,15 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
 		 int x, int y, int w, int h, int leftPad, int format,
 		 char *bits)
 {
+    ExaPixmapPriv(exaGetDrawablePixmap(pDrawable));
+
     EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
     if (exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle,
 			      pGC->alu))
 	exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
     else
-	ExaDoPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+	exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST,
+			     DamagePendingRegion(pExaPixmap->pDamage));
     fbPutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
     exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
 }
diff --git a/hw/xfree86/exa/exa.man.pre b/hw/xfree86/exa/exa.man.pre
index 14859bc..31e1cfe 100644
--- a/hw/xfree86/exa/exa.man.pre
+++ b/hw/xfree86/exa/exa.man.pre
@@ -31,12 +31,6 @@ Disables acceleration of downloading of pixmap data from the framebuffer.
 Not usable with drivers which rely on DownloadFromScreen succeeding.
 Default: No.
 .TP
-.BI "Option \*qEXAOptimizeMigration\*q \*q" boolean \*q
-Enables an additional optimization for migration of destination pixmaps. This
-may improve performance in some cases (e.g. when switching virtual desktops with
-no compositing manager) but causes corruption in others (e.g. when starting
-compiz). Default: No.
-.TP
 .BI "Option \*qMigrationHeuristic\*q \*q" anystr \*q
 Chooses an alternate pixmap migration heuristic, for debugging purposes.  The
 default is intended to be the best performing one for general use, though others
diff --git a/hw/xfree86/exa/examodule.c b/hw/xfree86/exa/examodule.c
index e18da0a..63ea8c5 100644
--- a/hw/xfree86/exa/examodule.c
+++ b/hw/xfree86/exa/examodule.c
@@ -145,7 +145,7 @@ exaDDXDriverInit(ScreenPtr pScreen)
 	pExaScr->optimize_migration =
 	    xf86ReturnOptValBool(pScreenPriv->options,
 				 EXAOPT_OPTIMIZE_MIGRATION,
-				 FALSE);
+				 TRUE);
     }
 
     if (xf86ReturnOptValBool(pScreenPriv->options,
commit f6d61d3d86971d6a202b46ff2fab8c8799a4d057
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sat May 24 20:01:36 2008 +0200

    EXA: Don't migrate twice in exaImageGlyphBlt.
    
    exaPrepareAccess already handles migration.

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 67d30f1..edaec23 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -970,10 +970,8 @@ exaImageGlyphBlt (DrawablePtr	pDrawable,
     int		    dstBpp;
     int		    dstXoff, dstYoff;
     FbBits	    depthMask;
-    Bool	    fallback;
     PixmapPtr	    pPixmap = exaGetDrawablePixmap(pDrawable);
     ExaPixmapPriv(pPixmap);
-    ExaMigrationRec pixmaps[1];
     RegionPtr	    pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
     BoxRec	    extents = *REGION_EXTENTS(pScreen, pending_damage);
     int		    xoff, yoff;
@@ -982,16 +980,8 @@ exaImageGlyphBlt (DrawablePtr	pDrawable,
 	return;
 
     depthMask = FbFullMask(pDrawable->depth);
-    fallback = (pGC->planemask & depthMask) != depthMask;
-
-    pixmaps[0].as_dst = TRUE;
-    pixmaps[0].as_src = FALSE;
-    pixmaps[0].pPix = pPixmap;
-    pixmaps[0].pReg = fallback ? NULL : pending_damage;
-
-    exaDoMigration(pixmaps, 1, FALSE);
 
-    if (fallback)
+    if ((pGC->planemask & depthMask) != depthMask)
     {
 	ExaCheckImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppciInit, pglyphBase);
 	return;
@@ -1014,7 +1004,7 @@ exaImageGlyphBlt (DrawablePtr	pDrawable,
     extents.y1 -= yoff;
     extents.y2 -= yoff;
 
-    exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
+    exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pending_damage);
 
     if (TERMINALFONT (pGC->font) && !glyph)
     {
commit d73304398255e0c3b03a497a8d4a2f8d900eef44
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sat May 24 20:01:31 2008 +0200

    EXA: Don't suggest exaCopyDirty be inlined.
    
    Leave the decision to the compiler toolchain.

diff --git a/exa/exa_migration.c b/exa/exa_migration.c
index d3646b0..5f22474 100644
--- a/exa/exa_migration.c
+++ b/exa/exa_migration.c
@@ -116,7 +116,7 @@ exaPixmapShouldBeInFB (PixmapPtr pPix)
  * If the pixmap is currently dirty, this copies at least the dirty area from
  * FB to system or vice versa.  Both areas must be allocated.
  */
-static _X_INLINE void
+static void
 exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
 	     Bool (*transfer) (PixmapPtr pPix, int x, int y, int w, int h,
 			       char *sys, int sys_pitch), CARD8 *fallback_src,
commit 3baf3b42e079b4e7b61c1e20df305db0724d21f8
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sat May 24 20:01:21 2008 +0200

    EXA: Specify region used for source pixmap migration in exaCopyNtoN.
    
    Avoids excessive migration overhead in some pathological cases. See
    http://bugs.freedesktop.org/show_bug.cgi?id=15845 .

diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 844683c..67d30f1 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -487,7 +487,8 @@ exaCopyNtoN (DrawablePtr    pSrcDrawable,
     int	    src_off_x, src_off_y;
     int	    dst_off_x, dst_off_y;
     ExaMigrationRec pixmaps[2];
-    RegionPtr region = NULL;
+    RegionPtr srcregion = NULL, dstregion = NULL;
+    xRectangle *rects;
 
     pSrcPixmap = exaGetDrawablePixmap (pSrcDrawable);
     pDstPixmap = exaGetDrawablePixmap (pDstDrawable);
@@ -495,33 +496,38 @@ exaCopyNtoN (DrawablePtr    pSrcDrawable,
     exaGetDrawableDeltas (pSrcDrawable, pSrcPixmap, &src_off_x, &src_off_y);
     exaGetDrawableDeltas (pDstDrawable, pDstPixmap, &dst_off_x, &dst_off_y);
 
-    if (!pGC || !exaGCReadsDestination(pDstDrawable, pGC->planemask,
-				       pGC->fillStyle, pGC->alu)) {
-	xRectangle *rects = xalloc(nbox * sizeof(xRectangle));
+    rects = xalloc(nbox * sizeof(xRectangle));
 
-	if (rects) {
-	    int i;
+    if (rects) {
+	int i;
 
-	    for (i = 0; i < nbox; i++) {
-		rects[i].x = pbox[i].x1 + dst_off_x;
-		rects[i].y = pbox[i].y1 + dst_off_y;
-		rects[i].width = pbox[i].x2 - pbox[i].x1;
-		rects[i].height = pbox[i].y2 - pbox[i].y1;
-	    }
+	for (i = 0; i < nbox; i++) {
+	    rects[i].x = pbox[i].x1 + dx + src_off_x;
+	    rects[i].y = pbox[i].y1 + dy + src_off_y;
+	    rects[i].width = pbox[i].x2 - pbox[i].x1;
+	    rects[i].height = pbox[i].y2 - pbox[i].y1;
+	}
 
-	    region  = RECTS_TO_REGION(pScreen, nbox, rects, CT_YXBANDED);
-	    xfree(rects);
+	srcregion  = RECTS_TO_REGION(pScreen, nbox, rects, CT_YXBANDED);
+	xfree(rects);
+
+	if (!pGC || !exaGCReadsDestination(pDstDrawable, pGC->planemask,
+					   pGC->fillStyle, pGC->alu)) {
+	    dstregion = REGION_CREATE(pScreen, NullBox, 0);
+	    REGION_COPY(pScreen, dstregion, srcregion);
+	    REGION_TRANSLATE(pScreen, dstregion, dst_off_x - dx - src_off_x,
+			     dst_off_y - dy - src_off_y);
 	}
     }
 
     pixmaps[0].as_dst = TRUE;
     pixmaps[0].as_src = FALSE;
     pixmaps[0].pPix = pDstPixmap;
-    pixmaps[0].pReg = region;
+    pixmaps[0].pReg = dstregion;
     pixmaps[1].as_dst = FALSE;
     pixmaps[1].as_src = TRUE;
     pixmaps[1].pPix = pSrcPixmap;
-    pixmaps[1].pReg = NULL;
+    pixmaps[1].pReg = srcregion;
 
     pSrcExaPixmap = ExaGetPixmapPriv (pSrcPixmap);
     pDstExaPixmap = ExaGetPixmapPriv (pDstPixmap);
@@ -594,17 +600,21 @@ fallback:
     EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable,
 		  exaDrawableLocation(pSrcDrawable),
 		  exaDrawableLocation(pDstDrawable)));
-    exaPrepareAccessReg (pDstDrawable, EXA_PREPARE_DEST, region);
-    exaPrepareAccess (pSrcDrawable, EXA_PREPARE_SRC);
+    exaPrepareAccessReg (pDstDrawable, EXA_PREPARE_DEST, dstregion);
+    exaPrepareAccessReg (pSrcDrawable, EXA_PREPARE_SRC, srcregion);
     fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse,
 		upsidedown, bitplane, closure);
     exaFinishAccess (pSrcDrawable, EXA_PREPARE_SRC);
     exaFinishAccess (pDstDrawable, EXA_PREPARE_DEST);
 
 out:
-    if (region) {
-	REGION_UNINIT(pScreen, region);
-	REGION_DESTROY(pScreen, region);
+    if (dstregion) {
+	REGION_UNINIT(pScreen, dstregion);
+	REGION_DESTROY(pScreen, dstregion);
+    }
+    if (srcregion) {
+	REGION_UNINIT(pScreen, srcregion);
+	REGION_DESTROY(pScreen, srcregion);
     }
 }
 


More information about the xorg-commit mailing list