From: Ville Syrjälä <ville.syrj...@nokia.com>

TraverseTree visits the parent before the children. When performing
the automatic redirection updates, the children must be visited before
the parent.

If there are automatically redirected windows on multiple levels of the
tree, updating the parents before the children would cause the parent
updates to use stale data for areas covered by the children. Also
updating the damaged children would re-damage the parent, which would
cause additional walks over the tree.

In the worst case with an unbroken chain of automatically redirected
subwindows, all of which are damaged, only the leaf window would be
properly updated on the first round. Then it's parent would be properly
updated on the second round, and so on. And on every round all of the
ancestor windows would be updated as well, but with stale data.
So with N damaged windows you would end up with (N^2+N)/2 updates,
instead of the expected N.

This reverts commit 648c8871c92727d7b6b16859f27f12266a06a16e.

Signed-off-by: Ville Syrjälä <ville.syrj...@nokia.com>
---
 composite/compwindow.c |   30 +++++++++++++++---------------
 1 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/composite/compwindow.c b/composite/compwindow.c
index bbd5756..22d2374 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -653,9 +653,10 @@ compWindowFormat (WindowPtr pWin)
 }
 
 static void
-compWindowUpdateAutomatic (WindowPtr pWin, ScreenPtr pScreen)
+compWindowUpdateAutomatic (WindowPtr pWin)
 {
     CompWindowPtr   cw = GetCompWindow (pWin);
+    ScreenPtr      pScreen = pWin->drawable.pScreen;
     WindowPtr      pParent = pWin->parent;
     PixmapPtr      pSrcPixmap = (*pScreen->GetWindowPixmap) (pWin);
     PictFormatPtr   pSrcFormat = compWindowFormat (pWin);
@@ -678,7 +679,8 @@ compWindowUpdateAutomatic (WindowPtr pWin, ScreenPtr 
pScreen)
     /*
      * First move the region from window to screen coordinates
      */
-    RegionTranslate(pRegion, pWin->drawable.x, pWin->drawable.y);
+    RegionTranslate(pRegion,
+                     pWin->drawable.x, pWin->drawable.y);
 
     /*
      * Clip against the "real" border clip
@@ -688,7 +690,8 @@ compWindowUpdateAutomatic (WindowPtr pWin, ScreenPtr 
pScreen)
     /*
      * Now translate from screen to dest coordinates
      */
-    RegionTranslate(pRegion, -pParent->drawable.x, -pParent->drawable.y);
+    RegionTranslate(pRegion,
+                     -pParent->drawable.x, -pParent->drawable.y);
 
     /*
      * Clip the picture
@@ -717,26 +720,23 @@ compWindowUpdateAutomatic (WindowPtr pWin, ScreenPtr 
pScreen)
     DamageEmpty (cw->damage);
 }
 
-static int
-compWindowUpdateVisit(WindowPtr pWin, void *data)
+void
+compWindowUpdate (WindowPtr pWin)
 {
+    WindowPtr  pChild;
+
+    for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
+       compWindowUpdate (pChild);
     if (pWin->redirectDraw != RedirectDrawNone)
     {
-       CompWindowPtr cw = GetCompWindow(pWin);
+       CompWindowPtr   cw = GetCompWindow(pWin);
+
        if (cw->damaged)
        {
-           compWindowUpdateAutomatic(pWin, data);
+           compWindowUpdateAutomatic (pWin);
            cw->damaged = FALSE;
        }
     }
-
-    return WT_WALKCHILDREN;
-}
-
-void
-compWindowUpdate (WindowPtr pWin)
-{
-    TraverseTree(pWin, compWindowUpdateVisit, pWin->drawable.pScreen);
 }
 
 WindowPtr
-- 
1.7.2.2

_______________________________________________
xorg-devel@lists.x.org: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to