summaryrefslogtreecommitdiff
path: root/miext/damage/damage.c
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2006-06-12 20:12:31 +0200
committerMichel Dänzer <daenzer@thor.lorrainebruecke.local>2006-06-12 20:12:31 +0200
commit6060b612de6b41f872d034c6130770c1d189d0a3 (patch)
treecb88913bada7cbea1baa96bbeb4f9edd36b1877a /miext/damage/damage.c
parentf8535edec736cf19740bd41ed2adfe531f2c26ac (diff)
Provide option to report damage after operation is complete.
Diffstat (limited to 'miext/damage/damage.c')
-rwxr-xr-xmiext/damage/damage.c150
1 files changed, 113 insertions, 37 deletions
diff --git a/miext/damage/damage.c b/miext/damage/damage.c
index ef7bca455..5b9402898 100755
--- a/miext/damage/damage.c
+++ b/miext/damage/damage.c
@@ -113,6 +113,52 @@ getDrawableDamageRef (DrawablePtr pDrawable)
DamagePtr *pPrev = (DamagePtr *) \
&(pWindow->devPrivates[damageWinPrivateIndex].ptr)
+static void
+DamageReportDamage (DamagePtr pDamage, RegionPtr pDamageRegion)
+{
+ BoxRec tmpBox;
+ RegionRec tmpRegion;
+ Bool was_empty;
+
+ switch (pDamage->damageLevel) {
+ case DamageReportRawRegion:
+ (*pDamage->damageReport) (pDamage, pDamageRegion, pDamage->closure);
+ break;
+ case DamageReportDeltaRegion:
+ REGION_NULL (pScreen, &tmpRegion);
+ REGION_SUBTRACT (pScreen, &tmpRegion, pDamageRegion, &pDamage->damage);
+ if (REGION_NOTEMPTY (pScreen, &tmpRegion)) {
+ REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,
+ pDamageRegion);
+ (*pDamage->damageReport) (pDamage, &tmpRegion, pDamage->closure);
+ }
+ REGION_UNINIT(pScreen, &tmpRegion);
+ break;
+ case DamageReportBoundingBox:
+ tmpBox = *REGION_EXTENTS (pScreen, &pDamage->damage);
+ REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,
+ pDamageRegion);
+ if (!BOX_SAME (&tmpBox, REGION_EXTENTS (pScreen, &pDamage->damage))) {
+ (*pDamage->damageReport) (pDamage, &pDamage->damage,
+ pDamage->closure);
+ }
+ break;
+ case DamageReportNonEmpty:
+ was_empty = !REGION_NOTEMPTY(pScreen, &pDamage->damage);
+ REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,
+ pDamageRegion);
+ if (was_empty && REGION_NOTEMPTY(pScreen, &pDamage->damage)) {
+ (*pDamage->damageReport) (pDamage, &pDamage->damage,
+ pDamage->closure);
+ }
+ break;
+ case DamageReportNone:
+ REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,
+ pDamageRegion);
+ break;
+ }
+}
+
#if DAMAGE_DEBUG_ENABLE
static void
_damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip, int subWindowMode, const char *where)
@@ -130,9 +176,6 @@ damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip,
RegionRec clippedRec;
RegionPtr pDamageRegion;
RegionRec pixClip;
- Bool was_empty;
- RegionRec tmpRegion;
- BoxRec tmpBox;
int draw_x, draw_y;
#ifdef COMPOSITE
int screen_x = 0, screen_y = 0;
@@ -256,41 +299,18 @@ damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip,
*/
if (draw_x || draw_y)
REGION_TRANSLATE (pScreen, pDamageRegion, -draw_x, -draw_y);
-
- switch (pDamage->damageLevel) {
- case DamageReportRawRegion:
- (*pDamage->damageReport) (pDamage, pDamageRegion, pDamage->closure);
- break;
- case DamageReportDeltaRegion:
- REGION_NULL (pScreen, &tmpRegion);
- REGION_SUBTRACT (pScreen, &tmpRegion, pDamageRegion, &pDamage->damage);
- if (REGION_NOTEMPTY (pScreen, &tmpRegion))
- {
- REGION_UNION(pScreen, &pDamage->damage,
- &pDamage->damage, pDamageRegion);
- (*pDamage->damageReport) (pDamage, &tmpRegion, pDamage->closure);
- }
- REGION_UNINIT(pScreen, &tmpRegion);
- break;
- case DamageReportBoundingBox:
- tmpBox = *REGION_EXTENTS (pScreen, &pDamage->damage);
- REGION_UNION(pScreen, &pDamage->damage,
- &pDamage->damage, pDamageRegion);
- if (!BOX_SAME (&tmpBox, REGION_EXTENTS (pScreen, &pDamage->damage)))
- (*pDamage->damageReport) (pDamage, &pDamage->damage, pDamage->closure);
- break;
- case DamageReportNonEmpty:
- was_empty = !REGION_NOTEMPTY(pScreen, &pDamage->damage);
- REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,
- pDamageRegion);
- if (was_empty && REGION_NOTEMPTY(pScreen, &pDamage->damage))
- (*pDamage->damageReport) (pDamage, &pDamage->damage, pDamage->closure);
- break;
- case DamageReportNone:
- REGION_UNION(pScreen, &pDamage->damage, &pDamage->damage,
- pDamageRegion);
- break;
+
+ /* If the damage rec has been flagged to report damage after the op has
+ * completed, then union it into the delayed damage region, which will
+ * be used for reporting after calling down, and skip the reporting
+ */
+ if (!pDamage->reportAfter) {
+ DamageReportDamage (pDamage, pDamageRegion);
+ } else {
+ REGION_UNION(pScreen, &pDamage->pendingDamage,
+ &pDamage->pendingDamage, pDamageRegion);
}
+
/*
* translate original region back
*/
@@ -305,6 +325,21 @@ damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip,
REGION_UNINIT (pScreen, &clippedRec);
}
+static void
+damageReportPostOp (DrawablePtr pDrawable)
+{
+ drawableDamage(pDrawable);
+
+ for (; pDamage != NULL; pDamage = pDamage->pNext)
+ {
+ if (pDamage->reportAfter) {
+ DamageReportDamage (pDamage, &pDamage->pendingDamage);
+ REGION_EMPTY (pScreen, &pDamage->pendingDamage);
+ }
+ }
+
+}
+
#if DAMAGE_DEBUG_ENABLE
#define damageDamageBox(d,b,m) _damageDamageBox(d,b,m,__FUNCTION__)
static void
@@ -550,6 +585,7 @@ damageComposite (CARD8 op,
yDst,
width,
height);
+ damageReportPostOp (pDst->pDrawable);
wrap (pScrPriv, ps, Composite, damageComposite);
}
@@ -616,6 +652,7 @@ damageGlyphs (CARD8 op,
}
unwrap (pScrPriv, ps, Glyphs);
(*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
+ damageReportPostOp (pDst->pDrawable);
wrap (pScrPriv, ps, Glyphs, damageGlyphs);
}
#endif
@@ -668,6 +705,7 @@ damageFillSpans(DrawablePtr pDrawable,
(*pGC->ops->FillSpans)(pDrawable, pGC, npt, ppt, pwidth, fSorted);
+ damageReportPostOp (pDrawable);
DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
}
@@ -715,6 +753,7 @@ damageSetSpans(DrawablePtr pDrawable,
damageDamageBox (pDrawable, &box, pGC->subWindowMode);
}
(*pGC->ops->SetSpans)(pDrawable, pGC, pcharsrc, ppt, pwidth, npt, fSorted);
+ damageReportPostOp (pDrawable);
DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
}
@@ -746,6 +785,7 @@ damagePutImage(DrawablePtr pDrawable,
}
(*pGC->ops->PutImage)(pDrawable, pGC, depth, x, y, w, h,
leftPad, format, pImage);
+ damageReportPostOp (pDrawable);
DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
}
@@ -789,6 +829,7 @@ damageCopyArea(DrawablePtr pSrc,
ret = (*pGC->ops->CopyArea)(pSrc, pDst,
pGC, srcx, srcy, width, height, dstx, dsty);
+ damageReportPostOp (pDst);
DAMAGE_GC_OP_EPILOGUE(pGC, pDst);
return ret;
}
@@ -834,6 +875,7 @@ damageCopyPlane(DrawablePtr pSrc,
ret = (*pGC->ops->CopyPlane)(pSrc, pDst,
pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
+ damageReportPostOp (pDst);
DAMAGE_GC_OP_EPILOGUE(pGC, pDst);
return ret;
}
@@ -875,6 +917,7 @@ damagePolyPoint(DrawablePtr pDrawable,
damageDamageBox (pDrawable, &box, pGC->subWindowMode);
}
(*pGC->ops->PolyPoint)(pDrawable, pGC, mode, npt, ppt);
+ damageReportPostOp (pDrawable);
DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
}
@@ -948,6 +991,7 @@ damagePolylines(DrawablePtr pDrawable,
damageDamageBox (pDrawable, &box, pGC->subWindowMode);
}
(*pGC->ops->Polylines)(pDrawable, pGC, mode, npt, ppt);
+ damageReportPostOp (pDrawable);
DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
}
@@ -1026,6 +1070,7 @@ damagePolySegment(DrawablePtr pDrawable,
damageDamageBox (pDrawable, &box, pGC->subWindowMode);
}
(*pGC->ops->PolySegment)(pDrawable, pGC, nSeg, pSeg);
+ damageReportPostOp (pDrawable);
DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
}
@@ -1087,6 +1132,7 @@ damagePolyRectangle(DrawablePtr pDrawable,
}
}
(*pGC->ops->PolyRectangle)(pDrawable, pGC, nRects, pRects);
+ damageReportPostOp (pDrawable);
DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
}
@@ -1139,6 +1185,7 @@ damagePolyArc(DrawablePtr pDrawable,
damageDamageBox (pDrawable, &box, pGC->subWindowMode);
}
(*pGC->ops->PolyArc)(pDrawable, pGC, nArcs, pArcs);
+ damageReportPostOp (pDrawable);
DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
}
@@ -1197,6 +1244,7 @@ damageFillPolygon(DrawablePtr pDrawable,
}
(*pGC->ops->FillPolygon)(pDrawable, pGC, shape, mode, npt, ppt);
+ damageReportPostOp (pDrawable);
DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
}
@@ -1235,6 +1283,7 @@ damagePolyFillRect(DrawablePtr pDrawable,
damageDamageBox (pDrawable, &box, pGC->subWindowMode);
}
(*pGC->ops->PolyFillRect)(pDrawable, pGC, nRects, pRects);
+ damageReportPostOp (pDrawable);
DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
}
@@ -1276,6 +1325,7 @@ damagePolyFillArc(DrawablePtr pDrawable,
damageDamageBox (pDrawable, &box, pGC->subWindowMode);
}
(*pGC->ops->PolyFillArc)(pDrawable, pGC, nArcs, pArcs);
+ damageReportPostOp (pDrawable);
DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
}
@@ -1386,6 +1436,7 @@ damagePolyText8(DrawablePtr pDrawable,
Linear8Bit, TT_POLY8);
else
x = (*pGC->ops->PolyText8)(pDrawable, pGC, x, y, count, chars);
+ damageReportPostOp (pDrawable);
DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
return x;
}
@@ -1406,6 +1457,7 @@ damagePolyText16(DrawablePtr pDrawable,
TT_POLY16);
else
x = (*pGC->ops->PolyText16)(pDrawable, pGC, x, y, count, chars);
+ damageReportPostOp (pDrawable);
DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
return x;
}
@@ -1425,6 +1477,7 @@ damageImageText8(DrawablePtr pDrawable,
Linear8Bit, TT_IMAGE8);
else
(*pGC->ops->ImageText8)(pDrawable, pGC, x, y, count, chars);
+ damageReportPostOp (pDrawable);
DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
}
@@ -1444,6 +1497,7 @@ damageImageText16(DrawablePtr pDrawable,
TT_IMAGE16);
else
(*pGC->ops->ImageText16)(pDrawable, pGC, x, y, count, chars);
+ damageReportPostOp (pDrawable);
DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
}
@@ -1462,6 +1516,7 @@ damageImageGlyphBlt(DrawablePtr pDrawable,
nglyph, ppci, TRUE, pGC->subWindowMode);
(*pGC->ops->ImageGlyphBlt)(pDrawable, pGC, x, y, nglyph,
ppci, pglyphBase);
+ damageReportPostOp (pDrawable);
DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
}
@@ -1479,6 +1534,7 @@ damagePolyGlyphBlt(DrawablePtr pDrawable,
nglyph, ppci, FALSE, pGC->subWindowMode);
(*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph,
ppci, pglyphBase);
+ damageReportPostOp (pDrawable);
DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
}
@@ -1512,6 +1568,7 @@ damagePushPixels(GCPtr pGC,
damageDamageBox (pDrawable, &box, pGC->subWindowMode);
}
(*pGC->ops->PushPixels)(pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg);
+ damageReportPostOp (pDrawable);
DAMAGE_GC_OP_EPILOGUE(pGC, pDrawable);
}
@@ -1591,10 +1648,12 @@ damagePaintWindow(WindowPtr pWindow,
if(what == PW_BACKGROUND) {
unwrap (pScrPriv, pScreen, PaintWindowBackground);
(*pScreen->PaintWindowBackground) (pWindow, prgn, what);
+ damageReportPostOp (&pWindow->drawable);
wrap (pScrPriv, pScreen, PaintWindowBackground, damagePaintWindow);
} else {
unwrap (pScrPriv, pScreen, PaintWindowBorder);
(*pScreen->PaintWindowBorder) (pWindow, prgn, what);
+ damageReportPostOp (&pWindow->drawable);
wrap (pScrPriv, pScreen, PaintWindowBorder, damagePaintWindow);
}
}
@@ -1623,6 +1682,7 @@ damageCopyWindow(WindowPtr pWindow,
}
unwrap (pScrPriv, pScreen, CopyWindow);
(*pScreen->CopyWindow) (pWindow, ptOldOrg, prgnSrc);
+ damageReportPostOp (&pWindow->drawable);
wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow);
}
@@ -1654,6 +1714,7 @@ damageRestoreAreas (PixmapPtr pPixmap,
unwrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas);
(*pScreen->BackingStoreFuncs.RestoreAreas) (pPixmap, prgn,
xorg, yorg, pWindow);
+ damageReportPostOp (&pWindow->drawable);
wrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas,
damageRestoreAreas);
}
@@ -1822,12 +1883,14 @@ DamageCreate (DamageReportFunc damageReport,
pDamage->pNext = 0;
pDamage->pNextWin = 0;
REGION_NULL(pScreen, &pDamage->damage);
+ REGION_NULL(pScreen, &pDamage->pendingDamage);
pDamage->damageLevel = damageLevel;
pDamage->isInternal = isInternal;
pDamage->closure = closure;
pDamage->isWindow = FALSE;
pDamage->pDrawable = 0;
+ pDamage->reportAfter = FALSE;
pDamage->damageReport = damageReport;
pDamage->damageDestroy = damageDestroy;
@@ -1911,6 +1974,7 @@ DamageDestroy (DamagePtr pDamage)
if (pDamage->damageDestroy)
(*pDamage->damageDestroy) (pDamage, pDamage->closure);
REGION_UNINIT (pDamage->pDrawable->pScreen, &pDamage->damage);
+ REGION_UNINIT (pDamage->pDrawable->pScreen, &pDamage->pendingDamage);
xfree (pDamage);
}
@@ -1964,4 +2028,16 @@ DamageDamageRegion (DrawablePtr pDrawable,
RegionPtr pRegion)
{
damageDamageRegion (pDrawable, pRegion, FALSE, -1);
+
+ /* Go back and report this damage for DamagePtrs with reportAfter set, since
+ * this call isn't part of an in-progress drawing op in the call chain and
+ * the DDX probably just wants to know about it right away.
+ */
+ damageReportPostOp (pDrawable);
+}
+
+void
+DamageSetReportAfterOp (DamagePtr pDamage, Bool reportAfter)
+{
+ pDamage->reportAfter = reportAfter;
}