diff options
author | Michel Dänzer <michel@tungstengraphics.com> | 2008-08-08 12:17:58 +0200 |
---|---|---|
committer | Michel Dänzer <michel@tungstengraphics.com> | 2008-08-08 12:17:58 +0200 |
commit | 4212599c922373a224d2235c74672a3a3aa8e0b1 (patch) | |
tree | c143128193b6bb884a963f5473d6419727c316bf | |
parent | 073116cc44859e96374cde46325df8540621d5ee (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.c | 28 | ||||
-rw-r--r-- | exa/exa_accel.c | 58 | ||||
-rw-r--r-- | exa/exa_render.c | 176 | ||||
-rw-r--r-- | exa/exa_unaccel.c | 15 |
4 files changed, 153 insertions, 124 deletions
@@ -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, ®ion, &box, 1); + if (pExaPixmap->pDamage) + pending_damage = DamagePendingRegion(pExaPixmap->pDamage); - exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); + if (pending_damage) { + REGION_INIT(pScreen, ®ion, &box, 1); - REGION_TRANSLATE(pScreen, ®ion, xoff, yoff); - REGION_UNION(pScreen, pending_damage, pending_damage, ®ion); + exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); + + REGION_TRANSLATE(pScreen, ®ion, xoff, yoff); + REGION_UNION(pScreen, pending_damage, pending_damage, ®ion); + } 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, ®ion, -xoff, -yoff); - DamageDamageRegion(pDrawable, ®ion); + if (pending_damage) { + REGION_TRANSLATE(pScreen, ®ion, -xoff, -yoff); + DamageDamageRegion(pDrawable, ®ion); - REGION_UNINIT(pScreen, ®ion); + REGION_UNINIT(pScreen, ®ion); + } } 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, ®ion, &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, ®ion, &box, 1); - exaGetDrawableDeltas(pDst->pDrawable, pPixmap, &xoff, &yoff); + exaGetDrawableDeltas(pDst->pDrawable, pPixmap, &xoff, &yoff); - REGION_TRANSLATE(pScreen, ®ion, xoff, yoff); - pending_damage = DamagePendingRegion(pExaPixmap->pDamage); - REGION_UNION(pScreen, pending_damage, pending_damage, ®ion); - REGION_TRANSLATE(pScreen, ®ion, -xoff, -yoff); + REGION_TRANSLATE(pScreen, ®ion, xoff, yoff); + pending_damage = DamagePendingRegion(pExaPixmap->pDamage); + REGION_UNION(pScreen, pending_damage, pending_damage, ®ion); + REGION_TRANSLATE(pScreen, ®ion, -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, ®ion); - REGION_UNINIT(pScreen, ®ion); + DamageDamageRegion(pDst->pDrawable, ®ion); + REGION_UNINIT(pScreen, ®ion); + } } 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; |