Skip to content

Commit 4dc2a76

Browse files
nwnkkeith-packard
authored andcommitted
miext/damage: Only wrap into the GC ops chain if there's a listener (v3)
before after Operation -------- ----------------- ----------------- 1148346.9 1191807.5 ( 1.04) PutImage 10x10 square 2091666.1 2180983.0 ( 1.04) ShmPutImage 10x10 square v3: In miDamage{R,Unr}egister, bump the serial number of the affected drawable (and all children if it's a window) so subsequent drawing against the damage will trigger another ValidateGC pass and we wrap in/out correctly. Spotted by Aaron Plattner. Signed-off-by: Adam Jackson <[email protected]> Reviewed-by: Aaron Plattner <[email protected]> Signed-off-by: Keith Packard <[email protected]>
1 parent ad0156c commit 4dc2a76

File tree

1 file changed

+29
-1
lines changed

1 file changed

+29
-1
lines changed

miext/damage/damage.c

+29-1
Original file line numberDiff line numberDiff line change
@@ -436,9 +436,13 @@ damageCreateGC(GCPtr pGC)
436436
static void
437437
damageValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
438438
{
439+
drawableDamage(pDrawable);
439440
DAMAGE_GC_FUNC_PROLOGUE(pGC);
440441
(*pGC->funcs->ValidateGC) (pGC, changes, pDrawable);
441-
pGCPriv->ops = pGC->ops; /* just so it's not NULL */
442+
if (pDamage)
443+
pGCPriv->ops = pGC->ops; /* so it's not NULL, so FUNC_EPILOGUE does work */
444+
else
445+
pGCPriv->ops = NULL;
442446
DAMAGE_GC_FUNC_EPILOGUE(pGC);
443447
}
444448

@@ -1663,14 +1667,38 @@ miDamageCreate(DamagePtr pDamage)
16631667
{
16641668
}
16651669

1670+
/*
1671+
* We only wrap into the GC when there's a registered listener. For windows,
1672+
* damage includes damage to children. So if there's a GC validated against
1673+
* a subwindow and we then register a damage on the parent, we need to bump
1674+
* the serial numbers of the children to re-trigger validation.
1675+
*
1676+
* Since we can't know if a GC has been validated against one of the affected
1677+
* children, just bump them all to be safe.
1678+
*/
1679+
static int
1680+
damageRegisterVisit(WindowPtr pWin, void *data)
1681+
{
1682+
pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER;
1683+
return WT_WALKCHILDREN;
1684+
}
1685+
16661686
void
16671687
miDamageRegister(DrawablePtr pDrawable, DamagePtr pDamage)
16681688
{
1689+
if (pDrawable->type == DRAWABLE_WINDOW)
1690+
TraverseTree((WindowPtr)pDrawable, damageRegisterVisit, NULL);
1691+
else
1692+
pDrawable->serialNumber = NEXT_SERIAL_NUMBER;
16691693
}
16701694

16711695
void
16721696
miDamageUnregister(DrawablePtr pDrawable, DamagePtr pDamage)
16731697
{
1698+
if (pDrawable->type == DRAWABLE_WINDOW)
1699+
TraverseTree((WindowPtr)pDrawable, damageRegisterVisit, NULL);
1700+
else
1701+
pDrawable->serialNumber = NEXT_SERIAL_NUMBER;
16741702
}
16751703

16761704
void

0 commit comments

Comments
 (0)