EXA: Make sure damage tracking code is inactive if the driver manages pixmaps.

It was always supposed to be like that... It was only recently pointed out (in
a rather convoluted way) that it was not in fact the case.
This commit is contained in:
Michel Dänzer 2008-08-08 12:17:58 +02:00
parent 073116cc44
commit 4212599c92
4 changed files with 155 additions and 126 deletions

View File

@ -159,7 +159,7 @@ exaPixmapDirty (PixmapPtr pPix, int x1, int y1, int x2, int y2)
RegionPtr pDamageReg;
RegionRec region;
if (!pExaPixmap)
if (!pExaPixmap || !pExaPixmap->pDamage)
return;
box.x1 = max(x1, 0);
@ -334,6 +334,7 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth,
paddedWidth, NULL);
pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED;
pExaPixmap->fb_ptr = NULL;
pExaPixmap->pDamage = NULL;
} else {
pExaPixmap->driverPriv = NULL;
/* Scratch pixmaps may have w/h equal to zero, and may not be
@ -358,12 +359,10 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth,
fbDestroyPixmap(pPixmap);
return NULL;
}
}
pExaPixmap->area = NULL;
/* Set up damage tracking */
pExaPixmap->pDamage = DamageCreate (ExaDamageReport, NULL, DamageReportRawRegion, TRUE,
pExaPixmap->pDamage = DamageCreate (ExaDamageReport, NULL,
DamageReportRawRegion, TRUE,
pScreen, pPixmap);
if (pExaPixmap->pDamage == NULL) {
@ -373,6 +372,9 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth,
DamageRegister (&pPixmap->drawable, pExaPixmap->pDamage);
DamageSetReportAfterOp (pExaPixmap->pDamage, TRUE);
}
pExaPixmap->area = NULL;
/* None of the pixmap bits are valid initially */
REGION_NULL(pScreen, &pExaPixmap->validSys);

View File

@ -144,7 +144,6 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
ExaScreenPriv (pDrawable->pScreen);
PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
ExaPixmapPriv(pPix);
ExaMigrationRec pixmaps[1];
RegionPtr pClip;
BoxPtr pbox;
int nbox;
@ -166,11 +165,16 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
if (pExaScr->swappedOut)
return FALSE;
if (pExaPixmap->pDamage) {
ExaMigrationRec pixmaps[1];
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
pixmaps[0].pPix = pPix;
pixmaps[0].pReg = DamagePendingRegion(pExaPixmap->pDamage);
exaDoMigration (pixmaps, 1, TRUE);
}
pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
@ -297,14 +301,19 @@ exaShmPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, unsigned int format,
.x2 = pDrawable->x + dx + sw, .y2 = pDrawable->y + dy + sh };
RegionRec region;
int xoff, yoff;
RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
RegionPtr pending_damage = NULL;
if (pExaPixmap->pDamage)
pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
if (pending_damage) {
REGION_INIT(pScreen, &region, &box, 1);
exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
REGION_TRANSLATE(pScreen, &region, xoff, yoff);
REGION_UNION(pScreen, pending_damage, pending_damage, &region);
}
if (!exaDoShmPutImage(pDrawable, pGC, depth, format, w, h, sx, sy, sw, sh,
dx, dy, data)) {
@ -318,11 +327,13 @@ exaShmPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, unsigned int format,
exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
}
if (pending_damage) {
REGION_TRANSLATE(pScreen, &region, -xoff, -yoff);
DamageDamageRegion(pDrawable, &region);
REGION_UNINIT(pScreen, &region);
}
}
ShmFuncs exaShmFuncs = { NULL, exaShmPutImage };
@ -968,16 +979,23 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
FbBits depthMask;
PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
ExaPixmapPriv(pPixmap);
RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
BoxRec extents = *REGION_EXTENTS(pScreen, pending_damage);
RegionPtr pending_damage = NULL;
BoxRec extents;
int xoff, yoff;
if (pExaPixmap->pDamage)
pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
if (pending_damage) {
extents = *REGION_EXTENTS(pScreen, pending_damage);
if (extents.x1 >= extents.x2 || extents.y1 >= extents.y2)
return;
depthMask = FbFullMask(pDrawable->depth);
}
if ((pGC->planemask & depthMask) != depthMask)
if (!pending_damage || (pGC->planemask & depthMask) != depthMask)
{
ExaCheckImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppciInit, pglyphBase);
return;

View File

@ -466,17 +466,18 @@ exaCompositeRects(CARD8 op,
{
PixmapPtr pPixmap = exaGetDrawablePixmap(pDst->pDrawable);
ExaPixmapPriv(pPixmap);
RegionRec region;
int n;
ExaCompositeRectPtr r;
if (pExaPixmap->pDamage) {
int xoff, yoff;
int x1 = MAXSHORT;
int y1 = MAXSHORT;
int x2 = MINSHORT;
int y2 = MINSHORT;
RegionRec region;
RegionPtr pending_damage;
BoxRec box;
int n;
ExaCompositeRectPtr r;
/* We have to manage the damage ourselves, since CompositeRects isn't
* something in the screen that can be managed by the damage extension,
@ -525,6 +526,7 @@ exaCompositeRects(CARD8 op,
pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
REGION_UNION(pScreen, pending_damage, pending_damage, &region);
REGION_TRANSLATE(pScreen, &region, -xoff, -yoff);
}
/************************************************************/
@ -546,6 +548,7 @@ exaCompositeRects(CARD8 op,
/************************************************************/
if (pExaPixmap->pDamage) {
/* Now we have to flush the damage out from pendingDamage => damage
* Calling DamageDamageRegion has that effect. (We could pass
* in an empty region here, but we pass in the same region we
@ -555,6 +558,7 @@ exaCompositeRects(CARD8 op,
DamageDamageRegion(pDst->pDrawable, &region);
REGION_UNINIT(pScreen, &region);
}
}
static int
exaTryDriverComposite(CARD8 op,
@ -1067,6 +1071,8 @@ exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
DrawablePtr pDraw = pDst->pDrawable;
PixmapPtr pixmap = exaGetDrawablePixmap (pDraw);
ExaPixmapPriv (pixmap);
if (pExaPixmap->pDamage) {
RegionRec migration;
RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
int xoff, yoff;
@ -1084,6 +1090,7 @@ exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
REGION_INIT(pScreen, &migration, &bounds, 1);
REGION_UNION(pScreen, pending_damage, pending_damage, &migration);
REGION_UNINIT(pScreen, &migration);
}
exaPrepareAccess(pDraw, EXA_PREPARE_DEST);
@ -1170,6 +1177,8 @@ exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
DrawablePtr pDraw = pDst->pDrawable;
PixmapPtr pixmap = exaGetDrawablePixmap (pDraw);
ExaPixmapPriv (pixmap);
if (pExaPixmap->pDamage) {
RegionRec migration;
RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
int xoff, yoff;
@ -1187,6 +1196,7 @@ exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
REGION_INIT(pScreen, &migration, &bounds, 1);
REGION_UNION(pScreen, pending_damage, pending_damage, &migration);
REGION_UNINIT(pScreen, &migration);
}
exaPrepareAccess(pDraw, EXA_PREPARE_DEST);
(*ps->AddTriangles) (pDst, 0, 0, ntri, tris);

View File

@ -104,8 +104,8 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
pGC->alu))
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
else
exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST,
DamagePendingRegion(pExaPixmap->pDamage));
exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pExaPixmap->pDamage ?
DamagePendingRegion(pExaPixmap->pDamage) : NULL);
fbPutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
@ -362,23 +362,22 @@ ExaCheckComposite (CARD8 op,
CARD32
exaGetPixmapFirstPixel (PixmapPtr pPixmap)
{
ExaScreenPriv(pPixmap->drawable.pScreen);
CARD32 pixel;
void *fb;
Bool need_finish = FALSE;
BoxRec box;
RegionRec migration;
ExaPixmapPriv (pPixmap);
Bool sys_valid = !miPointInRegion(&pExaPixmap->validSys, 0, 0, &box);
Bool damaged = miPointInRegion(DamageRegion(pExaPixmap->pDamage), 0, 0,
&box);
Bool sys_valid = pExaPixmap->pDamage &&
!miPointInRegion(&pExaPixmap->validSys, 0, 0, &box);
Bool damaged = pExaPixmap->pDamage &&
miPointInRegion(DamageRegion(pExaPixmap->pDamage), 0, 0, &box);
Bool offscreen = exaPixmapIsOffscreen(pPixmap);
fb = pExaPixmap->sys_ptr;
/* Try to avoid framebuffer readbacks */
if (pExaScr->info->CreatePixmap ||
(!offscreen && !sys_valid && !damaged) ||
if ((!offscreen && !sys_valid && !damaged) ||
(offscreen && (!sys_valid || damaged)))
{
box.x1 = 0;