diff options
author | Michel Dänzer <michel@tungstengraphics.com> | 2006-12-19 18:57:22 +0100 |
---|---|---|
committer | Michel Dänzer <michel@tungstengraphics.com> | 2006-12-19 18:57:22 +0100 |
commit | 9563b2eea2f61246b6a9e14e00c701f693efa4e1 (patch) | |
tree | 4f5bb21af1c9a52b6d429f067e5d09b97ed2ddab | |
parent | 467c00cf450826e0bf06fe94470ec193af625d68 (diff) |
EXA: Lots of damage tracking fixes.exa-damagetrack
Mostly due to exaDrawableDirty() now calculating the backing pixmap coordinates
internally, for cases where they aren't trivially known. There's a new
exaPixmapDirty() function for the other cases.
-rw-r--r-- | exa/exa.c | 96 | ||||
-rw-r--r-- | exa/exa_accel.c | 89 | ||||
-rw-r--r-- | exa/exa_priv.h | 3 | ||||
-rw-r--r-- | exa/exa_render.c | 36 | ||||
-rw-r--r-- | exa/exa_unaccel.c | 40 |
5 files changed, 138 insertions, 126 deletions
@@ -122,22 +122,49 @@ exaGetDrawablePixmap(DrawablePtr pDrawable) } /** - * exaDrawableDirty() marks a pixmap backing a drawable as dirty, allowing for + * Sets the offsets to add to coordinates to make them address the same bits in + * the backing drawable. These coordinates are nonzero only for redirected + * windows. + */ +static void +exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap, + int *xp, int *yp) +{ +#ifdef COMPOSITE + if (pDrawable->type == DRAWABLE_WINDOW) { + *xp = -pPixmap->screen_x; + *yp = -pPixmap->screen_y; + return; + } +#endif + + *xp = 0; + *yp = 0; +} + +/** + * exaPixmapDirty() marks a pixmap as dirty, allowing for * optimizations in pixmap migration when no changes have occurred. */ void -exaDrawableDirty (DrawablePtr pDrawable, int x1, int y1, int x2, int y2) +exaPixmapDirty (PixmapPtr pPix, int x1, int y1, int x2, int y2) { - ExaPixmapPrivPtr pExaPixmap; + ExaPixmapPriv(pPix); + BoxRec box; RegionPtr pDamageReg; - BoxRec box = { .x1 = max(x1,0), .x2 = min(x2,pDrawable->width), - .y1 = max(y1,0), .y2 = min(y2,pDrawable->height) }; RegionRec region; - pExaPixmap = ExaGetPixmapPriv(exaGetDrawablePixmap (pDrawable)); - if (!pExaPixmap || box.x1 >= box.x2 || box.y1 >= box.y2) + if (!pExaPixmap) return; + box.x1 = max(x1, 0); + box.y1 = max(y1, 0); + box.x2 = min(x2, pPix->drawable.width); + box.y2 = min(y2, pPix->drawable.height); + + if (box.x1 >= box.x2 || box.y1 >= box.y2) + return; + pDamageReg = DamageRegion(pExaPixmap->pDamage); REGION_INIT(pScreen, ®ion, &box, 1); @@ -145,6 +172,29 @@ exaDrawableDirty (DrawablePtr pDrawable, int x1, int y1, int x2, int y2) REGION_UNINIT(pScreen, ®ion); } +/** + * exaDrawableDirty() marks a pixmap backing a drawable as dirty, allowing for + * optimizations in pixmap migration when no changes have occurred. + */ +void +exaDrawableDirty (DrawablePtr pDrawable, int x1, int y1, int x2, int y2) +{ + PixmapPtr pPix = exaGetDrawablePixmap(pDrawable); + int xoff, yoff; + + x1 = max(x1, pDrawable->x); + y1 = max(y1, pDrawable->y); + x2 = min(x2, pDrawable->x + pDrawable->width); + y2 = min(y2, pDrawable->y + pDrawable->height); + + if (x1 >= x2 || y1 >= y2) + return; + + exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff); + + exaPixmapDirty(pPix, x1 + xoff, y1 + yoff, x2 + xoff, y2 + yoff); +} + static Bool exaDestroyPixmap (PixmapPtr pPixmap) { @@ -289,32 +339,14 @@ exaDrawableIsOffscreen (DrawablePtr pDrawable) /** * Returns the pixmap which backs a drawable, and the offsets to add to * coordinates to make them address the same bits in the backing drawable. - * These coordinates are nonzero only for redirected windows. */ PixmapPtr exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp) { - PixmapPtr pPixmap; - int x, y; + PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable); + + exaGetDrawableDeltas (pDrawable, pPixmap, xp, yp); - if (pDrawable->type == DRAWABLE_WINDOW) { - pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr) pDrawable); -#ifdef COMPOSITE - x = -pPixmap->screen_x; - y = -pPixmap->screen_y; -#else - x = 0; - y = 0; -#endif - } - else - { - pPixmap = (PixmapPtr) pDrawable; - x = 0; - y = 0; - } - *xp = x; - *yp = y; if (exaPixmapIsOffscreen (pPixmap)) return pPixmap; else @@ -428,7 +460,7 @@ exaValidateGC (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) exaPrepareAccess(&pOldTile->drawable, EXA_PREPARE_SRC); pNewTile = fb24_32ReformatTile (pOldTile, pDrawable->bitsPerPixel); - exaDrawableDirty(&pNewTile->drawable, 0, 0, pNewTile->drawable.width, pNewTile->drawable.height); + exaPixmapDirty(pNewTile, 0, 0, pNewTile->drawable.width, pNewTile->drawable.height); exaFinishAccess(&pOldTile->drawable, EXA_PREPARE_SRC); } if (pNewTile) @@ -449,9 +481,9 @@ exaValidateGC (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) */ exaMoveOutPixmap(pGC->tile.pixmap); fbPadPixmap (pGC->tile.pixmap); - exaDrawableDirty(&pGC->tile.pixmap->drawable, 0, 0, - pGC->tile.pixmap->drawable.width, - pGC->tile.pixmap->drawable.height); + exaPixmapDirty(pGC->tile.pixmap, 0, 0, + pGC->tile.pixmap->drawable.width, + pGC->tile.pixmap->drawable.height); } /* Mask out the GCTile change notification, now that we've done FB's * job for it. diff --git a/exa/exa_accel.c b/exa/exa_accel.c index d2fe2e034..6fa481ad0 100644 --- a/exa/exa_accel.c +++ b/exa/exa_accel.c @@ -109,9 +109,8 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n, (*pExaScr->info->Solid) (pPixmap, fullX1 + off_x, fullY1 + off_y, fullX2 + off_x, fullY1 + 1 + off_y); - exaDrawableDirty (pDrawable, - fullX1 + off_x, fullY1 + off_y, - fullX2 + off_x, fullY1 + 1 + off_y); + exaPixmapDirty (pPixmap, fullX1 + off_x, fullY1 + off_y, + fullX2 + off_x, fullY1 + 1 + off_y); } else { @@ -130,9 +129,8 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n, (*pExaScr->info->Solid) (pPixmap, partX1 + off_x, fullY1 + off_y, partX2 + off_x, fullY1 + 1 + off_y); - exaDrawableDirty (pDrawable, - partX1 + off_x, fullY1 + off_y, - partX2 + off_x, fullY1 + 1 + off_y); + exaPixmapDirty (pPixmap, partX1 + off_x, fullY1 + off_y, + partX2 + off_x, fullY1 + 1 + off_y); } } pbox++; @@ -233,7 +231,7 @@ exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, exaFinishAccess(pDrawable, EXA_PREPARE_DEST); } - exaDrawableDirty(pDrawable, x1 + xoff, y1 + yoff, x2 + xoff, y2 + yoff); + exaPixmapDirty(pPix, x1 + xoff, y1 + yoff, x2 + xoff, y2 + yoff); } return; @@ -362,9 +360,8 @@ exaCopyNtoNTwoDir (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, dst_off_y + pbox->y1 + i, pbox->x2 - pbox->x1, 1); } - exaDrawableDirty(pDstDrawable, - dst_off_x + pbox->x1, dst_off_y + pbox->y1, - dst_off_x + pbox->x2, dst_off_y + pbox->y2); + exaPixmapDirty(pDstPixmap, dst_off_x + pbox->x1, dst_off_y + pbox->y1, + dst_off_x + pbox->x2, dst_off_y + pbox->y2); } if (dirsetup != 0) pExaScr->info->DoneCopy(pDstPixmap); @@ -437,9 +434,9 @@ exaCopyNtoN (DrawablePtr pSrcDrawable, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); - exaDrawableDirty (pDstDrawable, - pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, - pbox->x2 + dst_off_x, pbox->y2 + dst_off_y); + exaPixmapDirty (pDstPixmap, + pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, + pbox->x2 + dst_off_x, pbox->y2 + dst_off_y); pbox++; } (*pExaScr->info->DoneCopy) (pDstPixmap); @@ -460,9 +457,7 @@ fallback: exaFinishAccess (pDstDrawable, EXA_PREPARE_DEST); while (nbox--) { - exaDrawableDirty (pDstDrawable, - pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, - pbox->x2 + dst_off_x, pbox->y2 + dst_off_y); + exaDrawableDirty (pDstDrawable, pbox->x1, pbox->y1, pbox->x2, pbox->y2); pbox++; } } @@ -704,9 +699,8 @@ exaPolyFillRect(DrawablePtr pDrawable, (*pExaScr->info->Solid) (pPixmap, fullX1 + xoff, fullY1 + yoff, fullX2 + xoff, fullY2 + yoff); - exaDrawableDirty (pDrawable, - fullX1 + xoff, fullY1 + yoff, - fullX2 + xoff, fullY2 + yoff); + exaPixmapDirty (pPixmap, fullX1 + xoff, fullY1 + yoff, + fullX2 + xoff, fullY2 + yoff); } else { @@ -736,9 +730,8 @@ exaPolyFillRect(DrawablePtr pDrawable, (*pExaScr->info->Solid) (pPixmap, partX1 + xoff, partY1 + yoff, partX2 + xoff, partY2 + yoff); - exaDrawableDirty (pDrawable, - partX1 + xoff, partY1 + yoff, - partX2 + xoff, partY2 + yoff); + exaPixmapDirty (pPixmap, partX1 + xoff, partY1 + yoff, + partX2 + xoff, partY2 + yoff); } } } @@ -770,9 +763,6 @@ exaSolidBoxClipped (DrawablePtr pDrawable, pixmaps[0].as_src = FALSE; pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable); - /* We need to initialize x/yoff for tracking damage in the fallback case */ - pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); - if (pExaScr->swappedOut || pPixmap->drawable.width > pExaScr->info->maxX || pPixmap->drawable.height > pExaScr->info->maxY) @@ -825,13 +815,14 @@ fallback: if (partY2 <= partY1) continue; - if (!fallback) + if (!fallback) { (*pExaScr->info->Solid) (pPixmap, partX1 + xoff, partY1 + yoff, partX2 + xoff, partY2 + yoff); - exaDrawableDirty (pDrawable, - partX1 + xoff, partY1 + yoff, - partX2 + xoff, partY2 + yoff); + exaPixmapDirty (pPixmap, partX1 + xoff, partY1 + yoff, + partX2 + xoff, partY2 + yoff); + } else + exaDrawableDirty (pDrawable, partX1, partY1, partX2, partY2); } if (fallback) @@ -950,12 +941,17 @@ exaImageGlyphBlt (DrawablePtr pDrawable, pPriv->fg, gx + dstXoff, gHeight); + exaDrawableDirty (pDrawable, gx, gy, gx + gWidth, gy + gHeight); } else { + RegionPtr pClip = fbGetCompositeClip(pGC); + int nbox; + BoxPtr pbox; + gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip); fbPutXYImage (pDrawable, - fbGetCompositeClip(pGC), + pClip, pPriv->fg, pPriv->bg, pPriv->pm, @@ -969,9 +965,19 @@ exaImageGlyphBlt (DrawablePtr pDrawable, (FbStip *) pglyph, gStride, 0); + + for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip); + nbox--; pbox++) { + int x1 = max(gx, pbox->x1), x2 = min(gx + gWidth, pbox->x2); + int y1 = max(gy, pbox->y1), y2 = min(gy + gHeight, pbox->y2); + + if (x1 >= x2 || y1 >= y2) + continue; + + exaDrawableDirty (pDrawable, gx, gy, gx + gWidth, + gy + gHeight); + } } - exaDrawableDirty(pDrawable, gx + dstXoff, gy + dstYoff, - gx + dstXoff + gWidth, gy + dstYoff + gHeight); } x += pci->metrics.characterWidth; } @@ -1062,9 +1068,8 @@ exaFillRegionSolid (DrawablePtr pDrawable, (*pExaScr->info->Solid) (pPixmap, pBox->x1 + xoff, pBox->y1 + yoff, pBox->x2 + xoff, pBox->y2 + yoff); - exaDrawableDirty (pDrawable, - pBox->x1 + xoff, pBox->y1 + yoff, - pBox->x2 + xoff, pBox->y2 + yoff); + exaPixmapDirty (pPixmap, pBox->x1 + xoff, pBox->y1 + yoff, + pBox->x2 + xoff, pBox->y2 + yoff); pBox++; } (*pExaScr->info->DoneSolid) (pPixmap); @@ -1081,9 +1086,7 @@ fallback: exaFinishAccess (pDrawable, EXA_PREPARE_DEST); while (nbox--) { - exaDrawableDirty (pDrawable, - pBox->x1 + xoff, pBox->y1 + yoff, - pBox->x2 + xoff, pBox->y2 + yoff); + exaDrawableDirty (pDrawable, pBox->x1, pBox->y1, pBox->x2, pBox->y2); pBox++; } } @@ -1123,9 +1126,6 @@ exaFillRegionTiled (DrawablePtr pDrawable, pixmaps[1].as_src = TRUE; pixmaps[1].pPix = pTile; - /* We need to initialize x/yoff for tracking damage in the fallback case */ - pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); - if (pPixmap->drawable.width > pExaScr->info->maxX || pPixmap->drawable.height > pExaScr->info->maxY || tileWidth > pExaScr->info->maxX || @@ -1182,8 +1182,8 @@ exaFillRegionTiled (DrawablePtr pDrawable, dstY += h; tileY = 0; } - exaDrawableDirty (pDrawable, pBox->x1 + xoff, pBox->y1 + yoff, - pBox->x2 + xoff, pBox->y2 + yoff); + exaPixmapDirty (pPixmap, pBox->x1 + xoff, pBox->y1 + yoff, + pBox->x2 + xoff, pBox->y2 + yoff); pBox++; } (*pExaScr->info->DoneCopy) (pPixmap); @@ -1202,8 +1202,7 @@ fallback: exaFinishAccess (pDrawable, EXA_PREPARE_DEST); while (nbox--) { - exaDrawableDirty (pDrawable, pBox->x1 + xoff, pBox->y1 + yoff, - pBox->x2 + xoff, pBox->y2 + yoff); + exaDrawableDirty (pDrawable, pBox->x1, pBox->y1, pBox->x2, pBox->y2); pBox++; } } diff --git a/exa/exa_priv.h b/exa/exa_priv.h index 80cf60903..926e02a1f 100644 --- a/exa/exa_priv.h +++ b/exa/exa_priv.h @@ -340,6 +340,9 @@ void exaFinishAccess(DrawablePtr pDrawable, int index); void +exaPixmapDirty(PixmapPtr pPix, int x1, int y1, int x2, int y2); + +void exaDrawableDirty(DrawablePtr pDrawable, int x1, int y1, int x2, int y2); Bool diff --git a/exa/exa_render.c b/exa/exa_render.c index be7c2403b..75108a75c 100644 --- a/exa/exa_render.c +++ b/exa/exa_render.c @@ -302,9 +302,8 @@ exaTryDriverSolidFill(PicturePtr pSrc, (*pExaScr->info->Solid) (pDstPix, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, pbox->x2 + dst_off_x, pbox->y2 + dst_off_y); - exaDrawableDirty (pDst->pDrawable, - pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, - pbox->x2 + dst_off_x, pbox->y2 + dst_off_y); + exaPixmapDirty (pDstPix, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, + pbox->x2 + dst_off_x, pbox->y2 + dst_off_y); pbox++; } (*pExaScr->info->DoneSolid) (pDstPix); @@ -447,9 +446,8 @@ exaTryDriverComposite(CARD8 op, pbox->y1 + dst_off_y, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); - exaDrawableDirty (pDst->pDrawable, - pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, - pbox->x2 + dst_off_x, pbox->y2 + dst_off_y); + exaPixmapDirty (pDstPix, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, + pbox->x2 + dst_off_x, pbox->y2 + dst_off_y); pbox++; } (*pExaScr->info->DoneComposite) (pDstPix); @@ -712,18 +710,19 @@ void exaRasterizeTrapezoid (PicturePtr pPicture, xTrapezoid *trap, int x_off, int y_off) { + DrawablePtr pDraw = pPicture->pDrawable; ExaMigrationRec pixmaps[1]; pixmaps[0].as_dst = TRUE; pixmaps[0].as_src = TRUE; - pixmaps[0].pPix = exaGetDrawablePixmap (pPicture->pDrawable); + pixmaps[0].pPix = exaGetDrawablePixmap (pDraw); exaDoMigration(pixmaps, 1, FALSE); - exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST); + exaPrepareAccess(pDraw, EXA_PREPARE_DEST); fbRasterizeTrapezoid(pPicture, trap, x_off, y_off); - exaDrawableDirty(pPicture->pDrawable, 0, 0, - pPicture->pDrawable->width, pPicture->pDrawable->height); - exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST); + exaDrawableDirty(pDraw, pDraw->x, pDraw->y, + pDraw->x + pDraw->width, pDraw->y + pDraw->height); + exaFinishAccess(pDraw, EXA_PREPARE_DEST); } /** @@ -734,18 +733,19 @@ void exaAddTriangles (PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntri, xTriangle *tris) { + DrawablePtr pDraw = pPicture->pDrawable; ExaMigrationRec pixmaps[1]; pixmaps[0].as_dst = TRUE; pixmaps[0].as_src = TRUE; - pixmaps[0].pPix = exaGetDrawablePixmap (pPicture->pDrawable); + pixmaps[0].pPix = exaGetDrawablePixmap (pDraw); exaDoMigration(pixmaps, 1, FALSE); - exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST); + exaPrepareAccess(pDraw, EXA_PREPARE_DEST); fbAddTriangles(pPicture, x_off, y_off, ntri, tris); - exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST); - exaDrawableDirty(pPicture->pDrawable, 0, 0, - pPicture->pDrawable->width, pPicture->pDrawable->height); + exaDrawableDirty(pDraw, pDraw->x, pDraw->y, + pDraw->x + pDraw->width, pDraw->y + pDraw->height); + exaFinishAccess(pDraw, EXA_PREPARE_DEST); } /** @@ -1036,8 +1036,8 @@ exaGlyphs (CARD8 op, 0, 0, glyph->info.width, glyph->info.height, 0, 0); } - exaDrawableDirty (&pPixmap->drawable, 0, 0, - glyph->info.width, glyph->info.height); + exaPixmapDirty (pPixmap, 0, 0, + glyph->info.width, glyph->info.height); if (maskFormat) { diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c index a30911507..7713a08c9 100644 --- a/exa/exa_unaccel.c +++ b/exa/exa_unaccel.c @@ -23,26 +23,6 @@ #include "exa_priv.h" -#define TRIM_BOX(box, pGC) if (pGC->pCompositeClip) { \ - BoxPtr extents = &pGC->pCompositeClip->extents;\ - if(box.x1 < extents->x1) box.x1 = extents->x1; \ - if(box.x2 > extents->x2) box.x2 = extents->x2; \ - if(box.y1 < extents->y1) box.y1 = extents->y1; \ - if(box.y2 > extents->y2) box.y2 = extents->y2; \ - } - -#define TRANSLATE_BOX(box, pDrawable) { \ - box.x1 += pDrawable->x; \ - box.x2 += pDrawable->x; \ - box.y1 += pDrawable->y; \ - box.y2 += pDrawable->y; \ - } - -#define TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC) { \ - TRANSLATE_BOX(box, pDrawable); \ - TRIM_BOX(box, pGC); \ - } - /* * These functions wrap the low-level fb rendering functions and * synchronize framebuffer/accelerated drawing by stalling until @@ -222,10 +202,9 @@ ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC, EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); if (nrect) { - BoxRec box = { .x1 = max(prect->x,0), - .x2 = min(prect->x + prect->width,pDrawable->width), - .y1 = max(prect->y,0), - .y2 = min(prect->y + prect->height,pDrawable->height) }; + int x1 = max(prect->x, 0), y1 = max(prect->y, 0); + int x2 = min(prect->x + prect->width, pDrawable->width); + int y2 = min(prect->y + prect->height, pDrawable->height); exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); exaPrepareAccessGC (pGC); @@ -239,15 +218,14 @@ ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC, while (--nrect) { prect++; - box.x1 = min(box.x1, prect->x); - box.x2 = max(box.x2, prect->x + prect->width); - box.y1 = min(box.y1, prect->y); - box.y2 = max(box.y2, prect->y + prect->height); + x1 = min(x1, prect->x); + x2 = max(x2, prect->x + prect->width); + y1 = min(y1, prect->y); + y2 = max(y2, prect->y + prect->height); } - TRIM_AND_TRANSLATE_BOX(box, pDrawable, pGC); - - exaDrawableDirty (pDrawable, box.x1, box.x2, box.y1, box.y2); + exaDrawableDirty (pDrawable, pDrawable->x + x1, pDrawable->y + y1, + pDrawable->x + x2, pDrawable->y + y2); } } |