Blob Blame Raw
From 17fb37f3b81aa3575a1549ced11da9022e439246 Mon Sep 17 00:00:00 2001
From: Keith Packard <keithp@keithp.com>
Date: Thu, 28 Apr 2011 13:34:28 +1000
Subject: [PATCH] dri2: Invalidate DRI2 buffers for all windows with the same
 pixmap on swap

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

JFDI already.

Tested-by: Ian Pilcher <arequipeno@gmail.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>

fix 2
---
 hw/xfree86/dri2/dri2.c |   33 ++++++++++++++++++++++++++++++++-
 1 files changed, 32 insertions(+), 1 deletions(-)

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 5c42a51..85c9764 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -343,6 +343,7 @@ allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds,
     int old_buf = find_attachment(pPriv, attachment);
 
     if ((old_buf < 0)
+	|| attachment == DRI2BufferFrontLeft
 	|| !dimensions_match
 	|| (pPriv->buffers[old_buf]->format != format)) {
 	*buffer = (*ds->CreateBuffer)(pDraw, attachment, format);
@@ -786,6 +787,20 @@ 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,
@@ -886,7 +901,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.4.4