[xserver-commit] xserver/miext/damage damage.c,1.4,1.5 damagestr.h,1.2,1.3

Keith Packard xserver-commit@pdx.freedesktop.org
Sat, 08 Nov 2003 23:06:01 -0800


Committed by: keithp

Update of /cvs/xserver/xserver/miext/damage
In directory pdx:/tmp/cvs-serv8142/miext/damage

Modified Files:
	damage.c damagestr.h 
Log Message:
	* composite/compinit.c: (compCloseScreen), (compScreenInit):
	* composite/compint.h:
	* composite/compwindow.c: (compCheckWindow),
	(compPaintWindowBackground), (compDestroyWindow):
	* damageext/damageext.c: (DamageExtNotify), (DamageExtDestroy),
	(ProcDamageSubtract), (FreeDamageExt), (FreeDamageExtWin):
	* dix/window.c: (SetBorderSize):
	* miext/damage/damage.c: (damageDamageRegion), (damageDamageBox),
	(damageDestroyPixmap), (damagePaintWindow), (damageCopyWindow),
	(damageRestoreAreas), (damageSetWindowPixmap),
	(damageDestroyWindow), (DamageSetup), (DamageCreate),
	(DamageRegister), (DamageUnregister), (DamageSubtract),
	(DamageDamageRegion):
	* miext/damage/damagestr.h:
	* render/mirect.c: (miColorRects):

	Wrap PaintWindowBackground in composite extension to
	disable painting window background in manual Subwindows mode.

	compDestroyWindow needed to refetch cw and csw because
	CompFreeClientWindow/compFreeClientSubwindows zeroed them.

	Damage must store all damage in window relative
	coordinates so that damage tracks window movement.  I doubt
	this will work "right" with bitGravity, apps are likely to
	lose in that case anyway.

	Check for clientGone before trying to write events.

	Better checking for freeing datastructures in various orders

	dix/window.c: oops.  Was setting wrong region in COMPOSITE side
	of SetBorderSize.

	Damage must be associated with windows, not just underlying pixmap
	in case that changes.  Wrap SetWindowPixmap to track changes
	to window pixmaps (and DestroyWindow as well).

	Don't smash PaintWindow/CopyWindow regions in damageDamageRegion.
	Also, translate region back for those cases.

	render/mirect.c: track subWindowMode (oops)


Index: damage.c
===================================================================
RCS file: /cvs/xserver/xserver/miext/damage/damage.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- damage.c	7 Nov 2003 23:29:29 -0000	1.4
+++ damage.c	9 Nov 2003 07:05:59 -0000	1.5
@@ -81,17 +81,20 @@
 #define windowDamage(pWin)	drawableDamage(&(pWin)->drawable)
 #define getDrawableDamage(pDrawable)    damageGetPixPriv(GetDrawablePixmap(pDrawable))
 #define getWindowDamage(pWin)	    getDrawableDamage(&(pWin)->drawable)
-#define pixDamageRef(pDrawable) \
+#define pixDamageRef(pPixmap) \
     DamagePtr	*pPrev = (DamagePtr *) \
-	    &(pPixmap->devPrivates[damagePixPrivateIndex].ptr);
+	    &(pPixmap->devPrivates[damagePixPrivateIndex].ptr)
+#define winDamageRef(pWindow) \
+    DamagePtr	*pPrev = (DamagePtr *) \
+	    &(pWindow->devPrivates[damageWinPrivateIndex].ptr)
 
 #if DAMAGE_DEBUG_ENABLE
 static void
-_damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, char *where)
-#define damageDamageRegion(d,r) _damageDamageRegion(d,r,__FUNCTION__)
+_damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip, char *where)
+#define damageDamageRegion(d,r,c) _damageDamageRegion(d,r,c,__FUNCTION__)
 #else
 static void
-damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion)
+damageDamageRegion (DrawablePtr pDrawable, RegionPtr pRegion, Bool clip)
 #endif
 {
     damageScrPriv(pDrawable->pScreen);
@@ -102,20 +105,25 @@
     Bool	    was_empty;
     RegionRec	    tmpRegion;
     BoxRec	    tmpBox;
+    int		    draw_x, draw_y;
+    int		    x = 0, y = 0;
 
-    if (pDrawable->type == DRAWABLE_WINDOW)
-	pClip = &((WindowPtr)pDrawable)->borderClip;
-    else
+    if (clip)
     {
-	BoxRec	box;
-	box.x1 = pDrawable->x;
-	box.y1 = pDrawable->y;
-	box.x2 = pDrawable->x + pDrawable->width;
-	box.y2 = pDrawable->y + pDrawable->height;
-	REGION_INIT(pScreen, &pixClip, &box, 1);
-	pClip = &pixClip;
+	if (pDrawable->type == DRAWABLE_WINDOW)
+	    pClip = &((WindowPtr)pDrawable)->borderClip;
+	else
+	{
+	    BoxRec	box;
+	    box.x1 = pDrawable->x;
+	    box.y1 = pDrawable->y;
+	    box.x2 = pDrawable->x + pDrawable->width;
+	    box.y2 = pDrawable->y + pDrawable->height;
+	    REGION_INIT(pScreen, &pixClip, &box, 1);
+	    pClip = &pixClip;
+	}
+	REGION_INTERSECT (pScreen, pRegion, pRegion, pClip);
     }
-    REGION_INTERSECT (pScreen, pRegion, pRegion, pClip);
     DAMAGE_DEBUG (("%s %d x %d +%d +%d\n", where,
 		   pRegion->extents.x2 - pRegion->extents.x1,
 		   pRegion->extents.y2 - pRegion->extents.y1,
@@ -131,6 +139,14 @@
 			   pScrPriv->internalLevel));
 	    continue;
 	}
+	draw_x = pDamage->pDrawable->x;
+	draw_y = pDamage->pDrawable->y;
+	if (draw_x != x || draw_y != y)
+	{
+	    REGION_TRANSLATE (pScreen, pRegion, x - draw_x, y - draw_y);
+	    x = draw_x;
+	    y = draw_y;
+	}
 	switch (pDamage->damageLevel) {
 	case DamageReportRawRegion:
 	    (*pDamage->damageReport) (pDamage, pRegion, pDamage->closure);
@@ -165,6 +181,11 @@
 	    break;
 	}
     }
+    if (!clip)
+    {
+	if (x || y)
+	    REGION_TRANSLATE (pScreen, pRegion, x, y);
+    }
 }
 
 #if DAMAGE_DEBUG_ENABLE
@@ -180,9 +201,9 @@
 
     REGION_INIT (pDrawable->pScreen, &region, pBox, 1);
 #if DAMAGE_DEBUG_ENABLE
-    _damageDamageRegion (pDrawable, &region, where);
+    _damageDamageRegion (pDrawable, &region, TRUE, where);
 #else
-    damageDamageRegion (pDrawable, &region);
+    damageDamageRegion (pDrawable, &region, TRUE);
 #endif
     REGION_UNINIT (pDrawable->pScreen, &region);
 }
@@ -1371,7 +1392,8 @@
 	while ((pDamage = damageGetPixPriv(pPixmap)))
 	{
 	    damageRemoveDamage (pPixmap, pDamage);
-	    DamageDestroy (pDamage);
+	    if (!pDamage->isWindow)
+		DamageDestroy (pDamage);
 	}
     }
     unwrap (pScrPriv, pScreen, DestroyPixmap);
@@ -1389,7 +1411,7 @@
     damageScrPriv(pScreen);
 
     if (getWindowDamage (pWindow))
-	damageDamageRegion (&pWindow->drawable, prgn);
+	damageDamageRegion (&pWindow->drawable, prgn, FALSE);
     if(what == PW_BACKGROUND) {
 	unwrap (pScrPriv, pScreen, PaintWindowBackground);
 	(*pScreen->PaintWindowBackground) (pWindow, prgn, what);
@@ -1420,7 +1442,7 @@
 	 * at the destination location.  Translate back and forth.
 	 */
 	REGION_TRANSLATE (pScreen, prgnSrc, dx, dy);
-	damageDamageRegion (&pWindow->drawable, prgnSrc);
+	damageDamageRegion (&pWindow->drawable, prgnSrc, FALSE);
 	REGION_TRANSLATE (pScreen, prgnSrc, -dx, -dy);
     }
     unwrap (pScrPriv, pScreen, CopyWindow);
@@ -1455,7 +1477,7 @@
     ScreenPtr pScreen = pWindow->drawable.pScreen;
     damageScrPriv(pScreen);
 
-    damageDamageRegion (&pWindow->drawable, prgn);
+    damageDamageRegion (&pWindow->drawable, prgn, FALSE);
     unwrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas);
     (*pScreen->BackingStoreFuncs.RestoreAreas) (pPixmap, prgn,
 						xorg, yorg, pWindow);
@@ -1463,6 +1485,54 @@
 			     damageRestoreAreas);
 }
 
+static void
+damageSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap)
+{
+    DamagePtr	pDamage;
+    ScreenPtr	pScreen = pWindow->drawable.pScreen;
+    damageScrPriv(pScreen);
+
+    if ((pDamage = damageGetWinPriv(pWindow)))
+    {
+	PixmapPtr   pOldPixmap = (*pScreen->GetWindowPixmap) (pWindow);
+	while (pDamage)
+	{
+	    damageRemoveDamage (pOldPixmap, pDamage);
+	    pDamage = pDamage->pNextWin;
+	}
+    }
+    unwrap (pScrPriv, pScreen, SetWindowPixmap);
+    (*pScreen->SetWindowPixmap) (pWindow, pPixmap);
+    wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap);
+    if ((pDamage = damageGetWinPriv(pWindow)))
+    {
+	while (pDamage)
+	{
+	    damageInsertDamage (pPixmap, pDamage);
+	    pDamage = pDamage->pNextWin;
+	}
+    }
+}
+
+static Bool
+damageDestroyWindow (WindowPtr pWindow)
+{
+    DamagePtr	pDamage;
+    ScreenPtr	pScreen = pWindow->drawable.pScreen;
+    Bool	ret;
+    damageScrPriv(pScreen);
+
+    while ((pDamage = damageGetWinPriv(pWindow)))
+    {
+	DamageUnregister (&pWindow->drawable, pDamage);
+	DamageDestroy (pDamage);
+    }
+    unwrap (pScrPriv, pScreen, DestroyWindow);
+    ret = (*pScreen->DestroyWindow) (pWindow);
+    wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow);
+    return ret;
+}
+
 static Bool
 damageCloseScreen (int i, ScreenPtr pScreen)
 {
@@ -1482,6 +1552,7 @@
 int damageScrPrivateIndex;
 int damagePixPrivateIndex;
 int damageGCPrivateIndex;
+int damageWinPrivateIndex;
 int damageGeneration;
 
 Bool
@@ -1503,6 +1574,9 @@
 	damagePixPrivateIndex = AllocatePixmapPrivateIndex ();
 	if (damagePixPrivateIndex == -1)
 	    return FALSE;
+	damageWinPrivateIndex = AllocateWindowPrivateIndex ();
+	if (damageWinPrivateIndex == -1)
+	    return FALSE;
 	damageGeneration = serverGeneration;
     }
     if (pScreen->devPrivates[damageScrPrivateIndex].ptr)
@@ -1512,6 +1586,9 @@
 	return FALSE;
     if (!AllocatePixmapPrivate (pScreen, damagePixPrivateIndex, 0))
 	return FALSE;
+    if (!AllocateWindowPrivate (pScreen, damageWinPrivateIndex, 0))
+	return FALSE;
+
     pScrPriv = (DamageScrPrivPtr) xalloc (sizeof (DamageScrPrivRec));
     if (!pScrPriv)
 	return FALSE;
@@ -1522,6 +1599,8 @@
     wrap (pScrPriv, pScreen, CreateGC, damageCreateGC);
     wrap (pScrPriv, pScreen, PaintWindowBackground, damagePaintWindow);
     wrap (pScrPriv, pScreen, PaintWindowBorder, damagePaintWindow);
+    wrap (pScrPriv, pScreen, DestroyWindow, damageDestroyWindow);
+    wrap (pScrPriv, pScreen, SetWindowPixmap, damageSetWindowPixmap);
     wrap (pScrPriv, pScreen, CopyWindow, damageCopyWindow);
     wrap (pScrPriv, pScreen, CloseScreen, damageCloseScreen);
     wrap (pScrPriv, pScreen, BackingStoreFuncs.RestoreAreas,
@@ -1549,13 +1628,18 @@
     pDamage = xalloc (sizeof (DamageRec));
     if (!pDamage)
 	return 0;
-    REGION_INIT(pScreen, &pDamage->damage, NullBox, 0);
     pDamage->pNext = 0;
-    pDamage->damageReport = damageReport;
-    pDamage->damageDestroy = damageDestroy;
+    pDamage->pNextWin = 0;
+    REGION_INIT(pScreen, &pDamage->damage, NullBox, 0);
+    
     pDamage->damageLevel = damageLevel;
     pDamage->isInternal = isInternal;
     pDamage->closure = closure;
+    pDamage->isWindow = FALSE;
+    pDamage->pDrawable = 0;
+
+    pDamage->damageReport = damageReport;
+    pDamage->damageDestroy = damageDestroy;
     return pDamage;
 }
 
@@ -1563,6 +1647,18 @@
 DamageRegister (DrawablePtr pDrawable,
 		DamagePtr   pDamage)
 {
+    if (pDrawable->type == DRAWABLE_WINDOW)
+    {
+	WindowPtr   pWindow = (WindowPtr) pDrawable;
+	winDamageRef(pWindow);
+
+	pDamage->pNextWin = *pPrev;
+	*pPrev = pDamage;
+	pDamage->isWindow = TRUE;
+    }
+    else
+	pDamage->isWindow = FALSE;
+    pDamage->pDrawable = pDrawable;
     damageInsertDamage (GetDrawablePixmap (pDrawable), pDamage);
 }
 
@@ -1578,6 +1674,22 @@
 DamageUnregister (DrawablePtr	    pDrawable,
 		  DamagePtr	    pDamage)
 {
+    if (pDrawable->type == DRAWABLE_WINDOW)
+    {
+	WindowPtr   pWindow = (WindowPtr) pDrawable;
+	winDamageRef (pWindow);
+
+	while (*pPrev)
+	{
+	    if (*pPrev == pDamage)
+	    {
+		*pPrev = pDamage->pNextWin;
+		break;
+	    }
+	    pPrev = &(*pPrev)->pNextWin;
+	}
+    }
+    pDamage->pDrawable = 0;
     damageRemoveDamage (GetDrawablePixmap (pDrawable), pDamage);
 }
 
@@ -1594,7 +1706,30 @@
 DamageSubtract (DamagePtr	    pDamage,
 		const RegionPtr	    pRegion)
 {
+    RegionPtr	pClip;
+    RegionRec	pixmapClip;
+    DrawablePtr	pDrawable = pDamage->pDrawable;
+    
     REGION_SUBTRACT (pScreen, &pDamage->damage, &pDamage->damage, pRegion);
+    if (pDrawable)
+    {
+	if (pDrawable->type == DRAWABLE_WINDOW)
+	    pClip = &((WindowPtr) pDrawable)->borderSize;
+	else
+	{
+	    BoxRec  box;
+
+	    box.x1 = pDrawable->x;
+	    box.y1 = pDrawable->y;
+	    box.x2 = pDrawable->x + pDrawable->width;
+	    box.y2 = pDrawable->y + pDrawable->height;
+	    REGION_INIT (pScren, &pixmapClip, &box, 1);
+	    pClip = &pixmapClip;
+	}
+    }
+    REGION_TRANSLATE (pScreen, &pDamage->damage, pDrawable->x, pDrawable->y);
+    REGION_INTERSECT (pScreen, &pDamage->damage, &pDamage->damage, pClip);
+    REGION_TRANSLATE (pScreen, &pDamage->damage, -pDrawable->x, -pDrawable->y);
     return REGION_NOTEMPTY (pScreen, &pDamage->damage);
 }
 
@@ -1614,5 +1749,5 @@
 DamageDamageRegion (DrawablePtr	pDrawable,
 		    RegionPtr	pRegion)
 {
-    damageDamageRegion (pDrawable, pRegion);
+    damageDamageRegion (pDrawable, pRegion, TRUE);
 }

Index: damagestr.h
===================================================================
RCS file: /cvs/xserver/xserver/miext/damage/damagestr.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- damagestr.h	2 Nov 2003 19:56:10 -0000	1.2
+++ damagestr.h	9 Nov 2003 07:05:59 -0000	1.3
@@ -30,11 +30,14 @@
 
 typedef struct _damage {
     DamagePtr		pNext;
+    DamagePtr		pNextWin;
     RegionRec		damage;
     
     DamageReportLevel	damageLevel;
     Bool		isInternal;
     void		*closure;
+    Bool		isWindow;
+    DrawablePtr		pDrawable;
     
     DamageReportFunc	damageReport;
     DamageDestroyFunc	damageDestroy;
@@ -49,6 +52,8 @@
     CloseScreenProcPtr		CloseScreen;
     CreateGCProcPtr		CreateGC;
     DestroyPixmapProcPtr	DestroyPixmap;
+    SetWindowPixmapProcPtr	SetWindowPixmap;
+    DestroyWindowProcPtr	DestroyWindow;
 #ifdef RENDER
     CompositeProcPtr		Composite;
     GlyphsProcPtr		Glyphs;
@@ -64,6 +69,7 @@
 extern int damageScrPrivateIndex;
 extern int damagePixPrivateIndex;
 extern int damageGCPrivateIndex;
+extern int damageWinPrivateIndex;
 
 #define damageGetScrPriv(pScr) \
     ((DamageScrPrivPtr) (pScr)->devPrivates[damageScrPrivateIndex].ptr)
@@ -86,4 +92,10 @@
 #define damageGCPriv(pGC) \
     DamageGCPrivPtr  pGCPriv = damageGetGCPriv(pGC)
 
+#define damageGetWinPriv(pWin) \
+    ((DamagePtr) (pWin)->devPrivates[damageWinPrivateIndex].ptr)
+
+#define damageSetWinPriv(pWin,d) \
+    ((pWin)->devPrivates[damageWinPrivateIndex].ptr = (d))
+
 #endif /* _DAMAGESTR_H_ */