[PATCH 3/4] dri2: Invalidate DRI2 buffers for all windows with the same pixmap on swap

Ville Syrjälä syrjala at sci.fi
Sun Dec 18 08:29:40 PST 2011


From: Keith Packard <keithp at keithp.com>

Without this, when a compositing manager unredirects a fullscreen window which
uses DRI2 and page flipping, the DRI2 buffer information for the compositing
manager's output window (typically the Composite Overlay Window or root window)
may become stale, resulting in all kinds of hilarity.

Fixes https://bugs.freedesktop.org/show_bug.cgi?id=35452 .

[Original patch by Michel Dänzer <michel at daenzer.net>]
[Tree walk optimized version by Keith Packard <keithp at keithp.com>]

Signed-off-by: Ville Syrjälä <syrjala at sci.fi>
---
 hw/xfree86/dri2/dri2.c |   31 ++++++++++++++++++++++++++++++-
 1 files changed, 30 insertions(+), 1 deletions(-)

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index eb84aa5..86e98a5 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -830,6 +830,19 @@ DRI2WaitSwap(ClientPtr client, DrawablePtr pDrawable)
     return FALSE;
 }
 
+/*
+ * A TraverseTree callback to invalidate all windows using the same
+ * pixmap
+ */
+static int
+DRI2InvalidateWalk(WindowPtr pWin, pointer data)
+{
+    if (pWin->drawable.pScreen->GetWindowPixmap(pWin) != data)
+	return WT_DONTWALKCHILDREN;
+    DRI2InvalidateDrawable(&pWin->drawable);
+    return WT_WALKCHILDREN;
+}
+
 int
 DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
 		CARD64 divisor, CARD64 remainder, CARD64 *swap_target,
@@ -930,7 +943,23 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
      */
     *swap_target = pPriv->swap_count + pPriv->swapsPending;
 
-    DRI2InvalidateDrawable(pDraw);
+    if (pDraw->type == DRAWABLE_WINDOW) {
+	WindowPtr	pWin = (WindowPtr) pDraw;
+	PixmapPtr	pPixmap = pScreen->GetWindowPixmap(pWin);
+
+	/*
+	 * Find the top-most window using this pixmap
+	 */
+	while (pWin->parent && pScreen->GetWindowPixmap(pWin->parent) == pPixmap)
+	    pWin = pWin->parent;
+
+	/*
+	 * Walk the sub-tree to invalidate all of the
+	 * windows using the same pixmap
+	 */
+	TraverseTree(pWin, DRI2InvalidateWalk, pPixmap);
+    } else
+	DRI2InvalidateDrawable(pDraw);
 
     return Success;
 }
-- 
1.7.3.4



More information about the xorg-devel mailing list