[PATCH v4 7/7] composite: Support updating an arbitrary subtree

ville.syrjala at nokia.com ville.syrjala at nokia.com
Wed Jan 5 05:51:37 PST 2011


From: Ville Syrjälä <ville.syrjala at nokia.com>

Rename compUpdateWindow to compPaintWindowToParent and split the child
walk to compPaintChildrenToWindow. Calling compPaintChildrenToWindow
allows an arbitrary subtree to be updated, instead of having to update
all the windows. This will be used to make sure all the descendants are
copied to the parent when the parent window contents need to be accessed
in IncludeInferios sub-window mode.

WindowRec has a new member 'damagedDescendants' that is used to keep
track of which subtrees need updating. When a window is damaged,
'damagedDescendants' will be set for all the ancestors, and when a
subtree is updated, the tree walk can be stopped early if no damaged
descendants are present.

CompScreenRec no longer needs the 'damaged' member since the root
window's 'damagedDescendants' provides the same information.

Signed-off-by: Ville Syrjälä <ville.syrjala at nokia.com>
---
v4: No changes

 composite/compalloc.c  |   12 +++++++++---
 composite/compinit.c   |   13 +++----------
 composite/compint.h    |    3 +--
 composite/compwindow.c |   22 +++++++++++++++++-----
 dix/window.c           |    4 ++++
 include/windowstr.h    |    3 +++
 6 files changed, 37 insertions(+), 20 deletions(-)

diff --git a/composite/compalloc.c b/composite/compalloc.c
index c140d47..e7f871f 100644
--- a/composite/compalloc.c
+++ b/composite/compalloc.c
@@ -51,12 +51,18 @@ static void
 compReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure)
 {
     WindowPtr	    pWin = (WindowPtr) closure;
-    ScreenPtr	    pScreen = pWin->drawable.pScreen;
-    CompScreenPtr   cs = GetCompScreen (pScreen);
     CompWindowPtr   cw = GetCompWindow (pWin);
 
-    cs->damaged = TRUE;
     cw->damaged = TRUE;
+
+    /* Mark the ancestors */
+    pWin = pWin->parent;
+    while (pWin) {
+	if (pWin->damagedDescendants)
+	    break;
+	pWin->damagedDescendants = TRUE;
+	pWin = pWin->parent;
+    }
 }
 
 static void
diff --git a/composite/compinit.c b/composite/compinit.c
index 80b9ddc..96ced1f 100644
--- a/composite/compinit.c
+++ b/composite/compinit.c
@@ -136,14 +136,8 @@ compChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
 static void
 compScreenUpdate (ScreenPtr pScreen)
 {
-    CompScreenPtr   cs = GetCompScreen (pScreen);
-
     compCheckTree (pScreen);
-    if (cs->damaged)
-    {
-	compWindowUpdate (pScreen->root);
-	cs->damaged = FALSE;
-    }
+    compPaintChildrenToWindow (pScreen->root);
 }
 
 static void
@@ -175,7 +169,7 @@ compGetImage (DrawablePtr pDrawable,
 
     pScreen->GetImage = cs->GetImage;
     if (pDrawable->type == DRAWABLE_WINDOW)
-	compScreenUpdate (pScreen);
+	compPaintChildrenToWindow ((WindowPtr) pDrawable);
     (*pScreen->GetImage) (pDrawable, sx, sy, w, h, format, planemask, pdstLine);
     cs->GetImage = pScreen->GetImage;
     pScreen->GetImage = compGetImage;
@@ -191,7 +185,7 @@ static void compSourceValidate(DrawablePtr pDrawable,
 
     pScreen->SourceValidate = cs->SourceValidate;
     if (pDrawable->type == DRAWABLE_WINDOW && subWindowMode == IncludeInferiors)
-	compScreenUpdate (pScreen);
+	compPaintChildrenToWindow ((WindowPtr) pDrawable);
     if (pScreen->SourceValidate)
 	(*pScreen->SourceValidate) (pDrawable, x, y, width, height,
 				    subWindowMode);
@@ -371,7 +365,6 @@ compScreenInit (ScreenPtr pScreen)
     if (!cs)
 	return FALSE;
 
-    cs->damaged = FALSE;
     cs->overlayWid = FakeClientID(0);
     cs->pOverlayWin = NULL;
     cs->pOverlayClients = NULL;
diff --git a/composite/compint.h b/composite/compint.h
index 99d27f6..57e0b5d 100644
--- a/composite/compint.h
+++ b/composite/compint.h
@@ -152,7 +152,6 @@ typedef struct _CompScreen {
 
     ScreenBlockHandlerProcPtr	BlockHandler;
     CloseScreenProcPtr		CloseScreen;
-    Bool			damaged;
     int				numAlternateVisuals;
     VisualID			*alternateVisuals;
 
@@ -316,7 +315,7 @@ void
 compCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
 
 void
-compWindowUpdate (WindowPtr pWin);
+compPaintChildrenToWindow (WindowPtr pWin);
 
 WindowPtr
 CompositeRealChildHead (WindowPtr pWin);
diff --git a/composite/compwindow.c b/composite/compwindow.c
index 22d2374..2440f18 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -720,13 +720,11 @@ compWindowUpdateAutomatic (WindowPtr pWin)
     DamageEmpty (cw->damage);
 }
 
-void
-compWindowUpdate (WindowPtr pWin)
+static void
+compPaintWindowToParent (WindowPtr pWin)
 {
-    WindowPtr	pChild;
+    compPaintChildrenToWindow (pWin);
 
-    for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
-	compWindowUpdate (pChild);
     if (pWin->redirectDraw != RedirectDrawNone)
     {
 	CompWindowPtr	cw = GetCompWindow(pWin);
@@ -739,6 +737,20 @@ compWindowUpdate (WindowPtr pWin)
     }
 }
 
+void
+compPaintChildrenToWindow (WindowPtr pWin)
+{
+    WindowPtr pChild;
+
+    if (!pWin->damagedDescendants)
+	return;
+
+    for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
+	compPaintWindowToParent (pChild);
+
+    pWin->damagedDescendants = FALSE;
+}
+
 WindowPtr
 CompositeRealChildHead (WindowPtr pWin)
 {
diff --git a/dix/window.c b/dix/window.c
index d140dda..9be7064 100644
--- a/dix/window.c
+++ b/dix/window.c
@@ -298,6 +298,10 @@ SetWindowToDefaults(WindowPtr pWin)
 #ifdef ROOTLESS
     pWin->rootlessUnhittable = FALSE;
 #endif
+
+#ifdef COMPOSITE
+    pWin->damagedDescendants = FALSE;
+#endif
 }
 
 static void
diff --git a/include/windowstr.h b/include/windowstr.h
index 0b66ebb..4a7a0f4 100644
--- a/include/windowstr.h
+++ b/include/windowstr.h
@@ -167,6 +167,9 @@ typedef struct _Window {
 #ifdef ROOTLESS
     unsigned		rootlessUnhittable:1;	/* doesn't hit-test */
 #endif
+#ifdef COMPOSITE
+    unsigned		damagedDescendants:1;	/* some descendants are damaged */
+#endif
 } WindowRec;
 
 /*
-- 
1.7.2.2



More information about the xorg-devel mailing list