[PATCH v2] composite: Suppress ClipNotify during window redirection UnmapWindow

ville.syrjala at nokia.com ville.syrjala at nokia.com
Wed Dec 15 13:47:18 PST 2010


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

When window redirection is changed, UnmapWindow() is called internally,
which leads to windows temporarily getting unrealized. When a window is
unrealized, ClipNotify() is called with an empty clip. In the case of
Xv this leads to video overlays blinking off and on in a very annoying
fashion. Suppress these ClipNotify() calls for the window whose
redirection mode is being changed, and all it's children.

Signed-off-by: Ville Syrjälä <ville.syrjala at nokia.com>
---
Decided to change my approach a little bit since I discovered that
ValidateTree also caused unwanted ClipNotifys. My earlier testing
just happened to not hit the problem. It seems that if video is
rendered to a top level window ValidateTree generates ClipNotifys,
if the video is rendered to a sub window MarkUnrealizedWindow is
the culprit. Anyways this new approach suppresses all ClipNotifys
but only for the target window and it's children.

There's still at least one issue left. My implementation assumes
that composite is the last one to wrap ClipNotify. I suppose to
make it really robust, I should wrap/unwrap around each each
UnmapWindow call.

 composite/compalloc.c  |   24 ++++++++++++++++++++++++
 composite/compint.h    |    1 +
 composite/compwindow.c |   14 ++++++++++++++
 3 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/composite/compalloc.c b/composite/compalloc.c
index 246e4c5..cdd6cf5 100644
--- a/composite/compalloc.c
+++ b/composite/compalloc.c
@@ -47,6 +47,24 @@
 
 #include "compint.h"
 
+static void DisableClipNotify (WindowPtr pWin)
+{
+    CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen);
+
+    assert(cs->disableClipNotifyWindow == NULL);
+
+    cs->disableClipNotifyWindow = pWin;
+}
+
+static void EnableClipNotify (WindowPtr pWin)
+{
+    CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen);
+
+    assert(cs->disableClipNotifyWindow != NULL);
+
+    cs->disableClipNotifyWindow = NULL;
+}
+
 static void
 compReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure)
 {
@@ -130,7 +148,9 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
 	if (wasMapped)
 	{
 	    DisableMapUnmapEvents (pWin);
+	    DisableClipNotify (pWin);
 	    UnmapWindow (pWin, FALSE);
+	    EnableClipNotify (pWin);
 	    EnableMapUnmapEvents (pWin);
 	}
 
@@ -159,7 +179,9 @@ compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
 	if (pWin->mapped) 
 	{
 	    DisableMapUnmapEvents (pWin);
+	    DisableClipNotify (pWin);
 	    UnmapWindow (pWin, FALSE);
+	    EnableClipNotify (pWin);
 	    EnableMapUnmapEvents (pWin);
 	}
 	if (cw->damageRegistered)
@@ -217,7 +239,9 @@ compFreeClientWindow (WindowPtr pWin, XID id)
 	if (wasMapped)
 	{
 	    DisableMapUnmapEvents (pWin);
+	    DisableClipNotify (pWin);
 	    UnmapWindow (pWin, FALSE);
+	    EnableClipNotify (pWin);
 	    EnableMapUnmapEvents (pWin);
 	}
     
diff --git a/composite/compint.h b/composite/compint.h
index 80083b0..93082a1 100644
--- a/composite/compint.h
+++ b/composite/compint.h
@@ -160,6 +160,7 @@ typedef struct _CompScreen {
     Window			overlayWid;
     CompOverlayClientPtr        pOverlayClients;
     
+    WindowPtr			disableClipNotifyWindow;
 } CompScreenRec, *CompScreenPtr;
 
 extern DevPrivateKeyRec CompScreenPrivateKeyRec;
diff --git a/composite/compwindow.c b/composite/compwindow.c
index 4dab135..a406117 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -266,6 +266,17 @@ compUnrealizeWindow (WindowPtr pWin)
     return ret;
 }
 
+static Bool IsClipNotifyDisabled (WindowPtr pWin)
+{
+    CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen);
+
+    if (!cs->disableClipNotifyWindow)
+	return FALSE;
+
+    return cs->disableClipNotifyWindow == pWin ||
+	IsParent(cs->disableClipNotifyWindow, pWin);
+}
+
 /*
  * Called after the borderClip for the window has settled down
  * We use this to make sure our extra borderClip has the right origin
@@ -278,6 +289,9 @@ compClipNotify (WindowPtr pWin, int dx, int dy)
     CompScreenPtr	cs = GetCompScreen (pScreen);
     CompWindowPtr	cw = GetCompWindow (pWin);
 
+    if (IsClipNotifyDisabled (pWin))
+	return;
+
     if (cw)
     {
 	if (cw->borderClipX != pWin->drawable.x ||
-- 
1.7.2.2



More information about the xorg-devel mailing list