[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