summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <michel@tungstengraphics.com>2008-05-24 20:01:41 +0200
committerMichel Dänzer <michel@tungstengraphics.com>2008-05-24 20:01:41 +0200
commit29586101dc11d498b212510f8dedbfeca7f8c859 (patch)
tree0f9efa252848ed228d102c64b98f539411328d08
parentf6d61d3d86971d6a202b46ff2fab8c8799a4d057 (diff)
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.
-rw-r--r--exa/exa.c17
-rw-r--r--exa/exa_accel.c6
-rw-r--r--exa/exa_migration.c6
-rw-r--r--exa/exa_priv.h1
-rw-r--r--exa/exa_unaccel.c5
-rw-r--r--hw/xfree86/exa/exa.man.pre6
-rw-r--r--hw/xfree86/exa/examodule.c2
7 files changed, 32 insertions, 11 deletions
diff --git a/exa/exa.c b/exa/exa.c
index 809fb4b00..fc047483d 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 edaec23df..1dbb269f6 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 5f22474e9..3c79f683c 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 f3b72ae66..9ec2a560c 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 c55ef032b..5a2576414 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 14859bc8f..31e1cfe34 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 e18da0a37..63ea8c56b 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,