From: Ville Syrjälä <[email protected]>

Eliminate the internal MapWindow+UnmapWindow cycle around window
redirection changes. Instead do the work in a single pass by marking
the afected windows and calling ValidateTree and HandleExposures
directly. This gets rid of unnecessary expose events, and invalid
ClipNotify calls during rediredction changes. Now ClipNotify will only
get called with the final clip values, and expose events are only sent
to areas that actually got exposed.

Signed-off-by: Ville Syrjälä <[email protected]>
Reviewed-by: Adam Jackson <[email protected]>
Reviewed-by: Daniel Stone <[email protected]>
---
v3: Removed the pWin->mapped checks as compMarkWindows() already checks
    pWin->viewable which can't be set unless pWin->mapped is also set.
    Instead I added a few !anyMarked tests to avoid walking the subtree
    multiple times.

 composite/compalloc.c |   87 +++++++++++++++++++++++++-----------------------
 1 files changed, 45 insertions(+), 42 deletions(-)

diff --git a/composite/compalloc.c b/composite/compalloc.c
index c615a4c..8130948 100644
--- a/composite/compalloc.c
+++ b/composite/compalloc.c
@@ -104,6 +104,35 @@ compDestroyDamage (DamagePtr pDamage, void *closure)
     cw->damage = 0;
 }
 
+static Bool
+compMarkWindows(WindowPtr pWin,
+               WindowPtr *ppLayerWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    WindowPtr pLayerWin = pWin;
+
+    if (!pWin->viewable)
+       return FALSE;
+
+    (*pScreen->MarkOverlappedWindows)(pWin, pWin, &pLayerWin);
+    (*pScreen->MarkWindow)(pLayerWin->parent);
+
+    *ppLayerWin = pLayerWin;
+
+    return TRUE;
+}
+
+static void
+compHandleMarkedWindows(WindowPtr pWin, WindowPtr pLayerWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    (*pScreen->ValidateTree)(pLayerWin->parent, pLayerWin, VTOther);
+    (*pScreen->HandleExposures)(pLayerWin->parent);
+    if (pScreen->PostValidateTree)
+       (*pScreen->PostValidateTree)(pLayerWin->parent, pLayerWin, VTOther);
+}
+
 /*
  * Redirect one window for one client
  */
@@ -112,8 +141,9 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int 
update)
 {
     CompWindowPtr      cw = GetCompWindow (pWin);
     CompClientWindowPtr        ccw;
-    Bool               wasMapped = pWin->mapped;
     CompScreenPtr       cs = GetCompScreen(pWin->drawable.pScreen);
+    WindowPtr          pLayerWin;
+    Bool               anyMarked = FALSE;
     
     if (pWin == cs->pOverlayWin) {
        return Success;
@@ -163,12 +193,8 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int 
update)
            free(cw);
            return BadAlloc;
        }
-       if (wasMapped)
-       {
-           DisableMapUnmapEvents (pWin);
-           UnmapWindow (pWin, FALSE);
-           EnableMapUnmapEvents (pWin);
-       }
+
+       anyMarked = compMarkWindows (pWin, &pLayerWin);
 
        /* Make sure our borderClip is correct for ValidateTree */
        RegionNull(&cw->borderClip);
@@ -190,16 +216,9 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int 
update)
        return BadAlloc;
     if (ccw->update == CompositeRedirectManual)
     {
-       /* If the window was CompositeRedirectAutomatic, then
-        * unmap the window so that the parent clip list will
-        * be correctly recomputed.
-        */
-       if (pWin->mapped) 
-       {
-           DisableMapUnmapEvents (pWin);
-           UnmapWindow (pWin, FALSE);
-           EnableMapUnmapEvents (pWin);
-       }
+       if (!anyMarked)
+           anyMarked = compMarkWindows (pWin, &pLayerWin);
+
        if (cw->damageRegistered)
        {
            DamageUnregister (&pWin->drawable, cw->damage);
@@ -213,15 +232,9 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int 
update)
        FreeResource (ccw->id, RT_NONE);
        return BadAlloc;
     }
-    if (wasMapped && !pWin->mapped)
-    {
-       Bool    overrideRedirect = pWin->overrideRedirect;
-       pWin->overrideRedirect = TRUE;
-       DisableMapUnmapEvents (pWin);
-       MapWindow (pWin, pClient);
-       EnableMapUnmapEvents (pWin);
-       pWin->overrideRedirect = overrideRedirect;
-    }
+
+    if (anyMarked)
+       compHandleMarkedWindows (pWin, pLayerWin);
     
     return Success;
 }
@@ -235,7 +248,8 @@ compFreeClientWindow (WindowPtr pWin, XID id)
 {
     CompWindowPtr      cw = GetCompWindow (pWin);
     CompClientWindowPtr        ccw, *prev;
-    Bool               wasMapped = pWin->mapped;
+    Bool               anyMarked = FALSE;
+    WindowPtr          pLayerWin;
 
     if (!cw)
        return;
@@ -252,12 +266,7 @@ compFreeClientWindow (WindowPtr pWin, XID id)
     }
     if (!cw->clients)
     {
-       if (wasMapped)
-       {
-           DisableMapUnmapEvents (pWin);
-           UnmapWindow (pWin, FALSE);
-           EnableMapUnmapEvents (pWin);
-       }
+       anyMarked = compMarkWindows (pWin, &pLayerWin);
     
        if (pWin->redirectDraw != RedirectDrawNone)
            compFreePixmap (pWin);
@@ -278,15 +287,9 @@ compFreeClientWindow (WindowPtr pWin, XID id)
        pWin->redirectDraw = RedirectDrawAutomatic;
        DamageDamageRegion(&pWin->drawable, &pWin->borderSize);
     }
-    if (wasMapped && !pWin->mapped)
-    {
-       Bool    overrideRedirect = pWin->overrideRedirect;
-       pWin->overrideRedirect = TRUE;
-       DisableMapUnmapEvents (pWin);
-       MapWindow (pWin, clients[CLIENT_ID(id)]);
-       EnableMapUnmapEvents (pWin);
-       pWin->overrideRedirect = overrideRedirect;
-    }
+
+    if (anyMarked)
+       compHandleMarkedWindows (pWin, pLayerWin);
 }
 
 /*
-- 
1.7.3.4

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to