summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Dänzer <michel@tungstengraphics.com>2008-08-08 12:17:58 +0200
committerMichel Dänzer <michel@tungstengraphics.com>2008-08-08 12:17:58 +0200
commit4212599c922373a224d2235c74672a3a3aa8e0b1 (patch)
treec143128193b6bb884a963f5473d6419727c316bf
parent073116cc44859e96374cde46325df8540621d5ee (diff)
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.
-rw-r--r--exa/exa.c28
-rw-r--r--exa/exa_accel.c58
-rw-r--r--exa/exa_render.c176
-rw-r--r--exa/exa_unaccel.c15
4 files changed, 153 insertions, 124 deletions
diff --git a/exa/exa.c b/exa/exa.c
index b8294bb69..c276d9aa7 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -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,21 +359,22 @@ 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,
- pScreen, pPixmap);
+ /* Set up damage tracking */
+ pExaPixmap->pDamage = DamageCreate (ExaDamageReport, NULL,
+ DamageReportRawRegion, TRUE,
+ pScreen, pPixmap);
- if (pExaPixmap->pDamage == NULL) {
- fbDestroyPixmap (pPixmap);
- return NULL;
- }
+ if (pExaPixmap->pDamage == NULL) {
+ fbDestroyPixmap (pPixmap);
+ return NULL;
+ }
- DamageRegister (&pPixmap->drawable, pExaPixmap->pDamage);
- DamageSetReportAfterOp (pExaPixmap->pDamage, TRUE);
+ 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);
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 48af459a2..8ac21b8f8 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -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;
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = pPix;
- pixmaps[0].pReg = DamagePendingRegion(pExaPixmap->pDamage);
- exaDoMigration (pixmaps, 1, TRUE);
+ 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;
- REGION_INIT(pScreen, &region, &box, 1);
+ if (pExaPixmap->pDamage)
+ pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
- exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
+ if (pending_damage) {
+ REGION_INIT(pScreen, &region, &box, 1);
- REGION_TRANSLATE(pScreen, &region, xoff, yoff);
- REGION_UNION(pScreen, pending_damage, pending_damage, &region);
+ 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,10 +327,12 @@ exaShmPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, unsigned int format,
exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
}
- REGION_TRANSLATE(pScreen, &region, -xoff, -yoff);
- DamageDamageRegion(pDrawable, &region);
+ if (pending_damage) {
+ REGION_TRANSLATE(pScreen, &region, -xoff, -yoff);
+ DamageDamageRegion(pDrawable, &region);
- REGION_UNINIT(pScreen, &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 (extents.x1 >= extents.x2 || extents.y1 >= extents.y2)
- return;
+ if (pExaPixmap->pDamage)
+ pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
- depthMask = FbFullMask(pDrawable->depth);
+ 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;
diff --git a/exa/exa_render.c b/exa/exa_render.c
index b480c6d05..704228537 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -466,65 +466,67 @@ exaCompositeRects(CARD8 op,
{
PixmapPtr pPixmap = exaGetDrawablePixmap(pDst->pDrawable);
ExaPixmapPriv(pPixmap);
-
- 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,
- * and EXA depends on damage to track what needs to be migrated between
- * offscreen and onscreen.
- */
+ if (pExaPixmap->pDamage) {
+ int xoff, yoff;
+ int x1 = MAXSHORT;
+ int y1 = MAXSHORT;
+ int x2 = MINSHORT;
+ int y2 = MINSHORT;
+ RegionPtr pending_damage;
+ BoxRec box;
+
+ /* We have to manage the damage ourselves, since CompositeRects isn't
+ * something in the screen that can be managed by the damage extension,
+ * and EXA depends on damage to track what needs to be migrated between
+ * offscreen and onscreen.
+ */
- /* Compute the overall extents of the composited region - we're making
- * the assumption here that we are compositing a bunch of glyphs that
- * cluster closely together and damaging each glyph individually would
- * be a loss compared to damaging the bounding box.
- */
- n = nrect;
- r = rects;
- while (n--) {
- int rect_x2 = r->xDst + r->width;
- int rect_y2 = r->yDst + r->width;
-
- if (r->xDst < x1) x1 = r->xDst;
- if (r->xDst < y1) y1 = r->xDst;
- if (rect_x2 > x2) x2 = rect_x2;
- if (rect_y2 > y2) y2 = rect_y2;
-
- r++;
- }
+ /* Compute the overall extents of the composited region - we're making
+ * the assumption here that we are compositing a bunch of glyphs that
+ * cluster closely together and damaging each glyph individually would
+ * be a loss compared to damaging the bounding box.
+ */
+ n = nrect;
+ r = rects;
+ while (n--) {
+ int rect_x2 = r->xDst + r->width;
+ int rect_y2 = r->yDst + r->width;
- if (x2 <= x1 && y2 <= y1)
- return;
+ if (r->xDst < x1) x1 = r->xDst;
+ if (r->xDst < y1) y1 = r->xDst;
+ if (rect_x2 > x2) x2 = rect_x2;
+ if (rect_y2 > y2) y2 = rect_y2;
- box.x1 = x1;
- box.x2 = x2 < MAXSHORT ? x2 : MAXSHORT;
- box.y1 = y1;
- box.y2 = y2 < MAXSHORT ? y2 : MAXSHORT;
-
- /* The pixmap migration code relies on pendingDamage indicating
- * the bounds of the current rendering, so we need to force
- * the actual damage into that region before we do anything, and
- * (see use of DamagePendingRegion in exaCopyDirty)
- */
-
- REGION_INIT(pScreen, &region, &box, 1);
+ r++;
+ }
+
+ if (x2 <= x1 && y2 <= y1)
+ return;
+
+ box.x1 = x1;
+ box.x2 = x2 < MAXSHORT ? x2 : MAXSHORT;
+ box.y1 = y1;
+ box.y2 = y2 < MAXSHORT ? y2 : MAXSHORT;
+
+ /* The pixmap migration code relies on pendingDamage indicating
+ * the bounds of the current rendering, so we need to force
+ * the actual damage into that region before we do anything, and
+ * (see use of DamagePendingRegion in exaCopyDirty)
+ */
+
+ REGION_INIT(pScreen, &region, &box, 1);
- exaGetDrawableDeltas(pDst->pDrawable, pPixmap, &xoff, &yoff);
+ exaGetDrawableDeltas(pDst->pDrawable, pPixmap, &xoff, &yoff);
- REGION_TRANSLATE(pScreen, &region, xoff, yoff);
- pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
- REGION_UNION(pScreen, pending_damage, pending_damage, &region);
- REGION_TRANSLATE(pScreen, &region, -xoff, -yoff);
+ REGION_TRANSLATE(pScreen, &region, xoff, yoff);
+ pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
+ REGION_UNION(pScreen, pending_damage, pending_damage, &region);
+ REGION_TRANSLATE(pScreen, &region, -xoff, -yoff);
+ }
/************************************************************/
@@ -546,14 +548,16 @@ exaCompositeRects(CARD8 op,
/************************************************************/
- /* 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
- * use above; the effect is the same.)
- */
+ 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
+ * use above; the effect is the same.)
+ */
- DamageDamageRegion(pDst->pDrawable, &region);
- REGION_UNINIT(pScreen, &region);
+ DamageDamageRegion(pDst->pDrawable, &region);
+ REGION_UNINIT(pScreen, &region);
+ }
}
static int
@@ -1067,23 +1071,26 @@ exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
DrawablePtr pDraw = pDst->pDrawable;
PixmapPtr pixmap = exaGetDrawablePixmap (pDraw);
ExaPixmapPriv (pixmap);
- RegionRec migration;
- RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
- int xoff, yoff;
- exaGetDrawableDeltas(pDraw, pixmap, &xoff, &yoff);
+ if (pExaPixmap->pDamage) {
+ RegionRec migration;
+ RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
+ int xoff, yoff;
+
+ exaGetDrawableDeltas(pDraw, pixmap, &xoff, &yoff);
- xoff += pDraw->x;
- yoff += pDraw->y;
+ xoff += pDraw->x;
+ yoff += pDraw->y;
- bounds.x1 += xoff;
- bounds.y1 += yoff;
- bounds.x2 += xoff;
- bounds.y2 += yoff;
+ bounds.x1 += xoff;
+ bounds.y1 += yoff;
+ bounds.x2 += xoff;
+ bounds.y2 += yoff;
- REGION_INIT(pScreen, &migration, &bounds, 1);
- REGION_UNION(pScreen, pending_damage, pending_damage, &migration);
- REGION_UNINIT(pScreen, &migration);
+ REGION_INIT(pScreen, &migration, &bounds, 1);
+ REGION_UNION(pScreen, pending_damage, pending_damage, &migration);
+ REGION_UNINIT(pScreen, &migration);
+ }
exaPrepareAccess(pDraw, EXA_PREPARE_DEST);
@@ -1170,23 +1177,26 @@ exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
DrawablePtr pDraw = pDst->pDrawable;
PixmapPtr pixmap = exaGetDrawablePixmap (pDraw);
ExaPixmapPriv (pixmap);
- RegionRec migration;
- RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
- int xoff, yoff;
- exaGetDrawableDeltas(pDraw, pixmap, &xoff, &yoff);
+ if (pExaPixmap->pDamage) {
+ RegionRec migration;
+ RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
+ int xoff, yoff;
- xoff += pDraw->x;
- yoff += pDraw->y;
+ exaGetDrawableDeltas(pDraw, pixmap, &xoff, &yoff);
- bounds.x1 += xoff;
- bounds.y1 += yoff;
- bounds.x2 += xoff;
- bounds.y2 += yoff;
+ xoff += pDraw->x;
+ yoff += pDraw->y;
- REGION_INIT(pScreen, &migration, &bounds, 1);
- REGION_UNION(pScreen, pending_damage, pending_damage, &migration);
- REGION_UNINIT(pScreen, &migration);
+ bounds.x1 += xoff;
+ bounds.y1 += yoff;
+ bounds.x2 += xoff;
+ bounds.y2 += yoff;
+
+ 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);
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index ee6b98e35..d5d6a306a 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -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;