diff options
author | Michel Dänzer <michel@tungstengraphics.com> | 2008-05-24 20:01:41 +0200 |
---|---|---|
committer | Michel Dänzer <michel@tungstengraphics.com> | 2008-05-24 20:01:41 +0200 |
commit | 29586101dc11d498b212510f8dedbfeca7f8c859 (patch) | |
tree | 0f9efa252848ed228d102c64b98f539411328d08 | |
parent | f6d61d3d86971d6a202b46ff2fab8c8799a4d057 (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.c | 17 | ||||
-rw-r--r-- | exa/exa_accel.c | 6 | ||||
-rw-r--r-- | exa/exa_migration.c | 6 | ||||
-rw-r--r-- | exa/exa_priv.h | 1 | ||||
-rw-r--r-- | exa/exa_unaccel.c | 5 | ||||
-rw-r--r-- | hw/xfree86/exa/exa.man.pre | 6 | ||||
-rw-r--r-- | hw/xfree86/exa/examodule.c | 2 |
7 files changed, 32 insertions, 11 deletions
@@ -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, ®ion); 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, |