[PATCH] dri2: Only invalidate the FrontLeft buffer if the backing pixmap changes

Chris Wilson chris at chris-wilson.co.uk
Fri Mar 16 13:16:19 PDT 2012


Fixes regression from 6f916ffec (dri2: Always re-generate front-buffer
information when asked for it).

Bugzilla: https://bugzilla.freedesktop.org/show_bug.cgi?id=44001
Bugzilla: https://bugzilla.freedesktop.org/show_bug.cgi?id=47388
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---

Just checking the name works for -intel, -ati and -nouveau but it may
not be suitable for all drivers, and so we may need to either consider a
memcmp() or a callback.

Also, I was under the impression that mesa/intel was smart enough to
reuse its existing buffer in this scenario, so it would also be wise to
see what broke there as well.
-Chris

---
 hw/xfree86/dri2/dri2.c |   43 +++++++++++++++++++++++++++++++++----------
 1 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 5cc9068..20fa8a2 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -375,24 +375,47 @@ allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds,
 			 int dimensions_match, DRI2BufferPtr *buffer)
 {
     int old_buf = find_attachment(pPriv, attachment);
+    DRI2BufferPtr ptr = NULL;
+
+    if (old_buf >= 0 &&
+	dimensions_match &&
+	(pPriv->buffers[old_buf]->format == format))
+	    ptr = pPriv->buffers[old_buf];
+
+    /* The FrontLeft buffer is special because it may be shared with the
+     * scanout and as the pixmap for all Windows on this screen. As such it
+     * may be changed at anytime outside of the normal sequence of DRI2 Window
+     * events. Instead of hooking into SetWindowPixmap and invalidating when we
+     * detect the driver has updated the backing buffer for a pixmap, which
+     * would require the drivers keep a 1:1 correspondence between Windows,
+     * Pixmaps and backing storage, we instead recreate the FrontLeft
+     * attachment everytime and look for a change. Ugh.
+     */
+    if (ptr != NULL && attachment == DRI2BufferFrontLeft) {
+	    DRI2BufferPtr new = (*ds->CreateBuffer)(pDraw, attachment, format);
+	    if (new->name != ptr->name) {
+		    *buffer = new;
+		    pPriv->serialNumber = DRI2DrawableSerial(pDraw);
+		    return TRUE;
+	    }
 
-    if ((old_buf < 0)
-	|| attachment == DRI2BufferFrontLeft
-	|| !dimensions_match
-	|| (pPriv->buffers[old_buf]->format != format)) {
-	*buffer = (*ds->CreateBuffer)(pDraw, attachment, format);
-	pPriv->serialNumber = DRI2DrawableSerial(pDraw);
-	return TRUE;
+	    (*ds->DestroyBuffer)(pDraw, new);
+	    ptr = NULL;
+    }
 
-    } else {
-	*buffer = pPriv->buffers[old_buf];
+    if (ptr) {
+	*buffer = ptr;
 
 	if (ds->ReuseBufferNotify)
-		(*ds->ReuseBufferNotify)(pDraw, *buffer);
+		(*ds->ReuseBufferNotify)(pDraw, ptr);
 
 	pPriv->buffers[old_buf] = NULL;
 	return FALSE;
     }
+
+    *buffer = (*ds->CreateBuffer)(pDraw, attachment, format);
+    pPriv->serialNumber = DRI2DrawableSerial(pDraw);
+    return TRUE;
 }
 
 static void
-- 
1.7.9.1



More information about the xorg-devel mailing list