From ec1681e0f638631697028b0d4c0fec5a93031689 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 16 Mar 2012 19:49:45 +0000 Subject: [PATCH] dri2: Only invalidate the FrontLeft buffer if the backing pixmap changes 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 --- 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