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 <ajax@redhat.com>
Reviewed-by: Aaron Plattner <aplattner@nvidia.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
			
			
This commit is contained in:
		
							parent
							
								
									ad0156c369
								
							
						
					
					
						commit
						4dc2a76740
					
				|  | @ -436,9 +436,13 @@ damageCreateGC(GCPtr pGC) | ||||||
| static void | static void | ||||||
| damageValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) | damageValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) | ||||||
| { | { | ||||||
|  |     drawableDamage(pDrawable); | ||||||
|     DAMAGE_GC_FUNC_PROLOGUE(pGC); |     DAMAGE_GC_FUNC_PROLOGUE(pGC); | ||||||
|     (*pGC->funcs->ValidateGC) (pGC, changes, pDrawable); |     (*pGC->funcs->ValidateGC) (pGC, changes, pDrawable); | ||||||
|     pGCPriv->ops = pGC->ops;    /* just so it's not NULL */ |     if (pDamage) | ||||||
|  |         pGCPriv->ops = pGC->ops; /* so it's not NULL, so FUNC_EPILOGUE does work */ | ||||||
|  |     else | ||||||
|  |         pGCPriv->ops = NULL; | ||||||
|     DAMAGE_GC_FUNC_EPILOGUE(pGC); |     DAMAGE_GC_FUNC_EPILOGUE(pGC); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -1663,14 +1667,38 @@ miDamageCreate(DamagePtr pDamage) | ||||||
| { | { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * We only wrap into the GC when there's a registered listener.  For windows, | ||||||
|  |  * damage includes damage to children.  So if there's a GC validated against | ||||||
|  |  * a subwindow and we then register a damage on the parent, we need to bump | ||||||
|  |  * the serial numbers of the children to re-trigger validation. | ||||||
|  |  * | ||||||
|  |  * Since we can't know if a GC has been validated against one of the affected | ||||||
|  |  * children, just bump them all to be safe. | ||||||
|  |  */ | ||||||
|  | static int  | ||||||
|  | damageRegisterVisit(WindowPtr pWin, void *data) | ||||||
|  | { | ||||||
|  |     pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; | ||||||
|  |     return WT_WALKCHILDREN; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void | void | ||||||
| miDamageRegister(DrawablePtr pDrawable, DamagePtr pDamage) | miDamageRegister(DrawablePtr pDrawable, DamagePtr pDamage) | ||||||
| { | { | ||||||
|  |     if (pDrawable->type == DRAWABLE_WINDOW) | ||||||
|  |         TraverseTree((WindowPtr)pDrawable, damageRegisterVisit, NULL); | ||||||
|  |     else | ||||||
|  |         pDrawable->serialNumber = NEXT_SERIAL_NUMBER; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| miDamageUnregister(DrawablePtr pDrawable, DamagePtr pDamage) | miDamageUnregister(DrawablePtr pDrawable, DamagePtr pDamage) | ||||||
| { | { | ||||||
|  |     if (pDrawable->type == DRAWABLE_WINDOW) | ||||||
|  |         TraverseTree((WindowPtr)pDrawable, damageRegisterVisit, NULL); | ||||||
|  |     else | ||||||
|  |         pDrawable->serialNumber = NEXT_SERIAL_NUMBER; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue