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.
This commit is contained in:
parent
f6d61d3d86
commit
29586101dc
17
exa/exa.c
17
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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -145,7 +145,7 @@ exaDDXDriverInit(ScreenPtr pScreen)
|
|||
pExaScr->optimize_migration =
|
||||
xf86ReturnOptValBool(pScreenPriv->options,
|
||||
EXAOPT_OPTIMIZE_MIGRATION,
|
||||
FALSE);
|
||||
TRUE);
|
||||
}
|
||||
|
||||
if (xf86ReturnOptValBool(pScreenPriv->options,
|
||||
|
|
Loading…
Reference in New Issue