From b6f204b62bbf2d0918761bb7773d2f80fff985fd Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 15 Mar 2016 21:24:20 +0000 Subject: sna/dri2: Prevent starting a swap chain for a decoupled Pixmap When a Window is resized, a new Pixmap is attached to the Window and the DRI2 buffers invalidated. However, the client may have requested a swap before it is notified of the resize and so we have to discard the stale swap. In doing so, we do not want to start a swap chain as it references the wrong frontbuffer and causes dire confusion when we start swapping for real. Reported-by: Jiri Slaby Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70461#c131 Signed-off-by: Chris Wilson --- src/sna/sna_dri2.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'src/sna/sna_dri2.c') diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c index 63d1f276..e3dce811 100644 --- a/src/sna/sna_dri2.c +++ b/src/sna/sna_dri2.c @@ -874,8 +874,9 @@ static void _sna_dri2_destroy_buffer(struct sna *sna, if (buffer == NULL) return; - DBG(("%s: %p [handle=%d] -- refcnt=%d, pixmap=%ld, proxy?=%d\n", + DBG(("%s: %p [handle=%d] -- refcnt=%d, draw=%ld, pixmap=%ld, proxy?=%d\n", __FUNCTION__, buffer, private->bo->handle, private->refcnt, + draw ? draw->id : 0, private->pixmap ? private->pixmap->drawable.serialNumber : 0, private->proxy != NULL)); assert(private->refcnt > 0); @@ -2329,10 +2330,10 @@ sna_dri2_xchg(DrawablePtr draw, DRI2BufferPtr front, DRI2BufferPtr back) back_bo = get_private(back)->bo; front_bo = get_private(front)->bo; - DBG(("%s: win=%ld, exchange front=%d/%d and back=%d/%d, pixmap=%ld %dx%d\n", + DBG(("%s: win=%ld, exchange front=%d/%d,ref=%d and back=%d/%d,ref=%d, pixmap=%ld %dx%d\n", __FUNCTION__, win->drawable.id, - front_bo->handle, front->name, - back_bo->handle, back->name, + front_bo->handle, front->name, get_private(front)->refcnt, + back_bo->handle, back->name, get_private(back)->refcnt, pixmap->drawable.serialNumber, pixmap->drawable.width, pixmap->drawable.height)); @@ -3304,6 +3305,14 @@ sna_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front, assert(get_private(front)->bo->refcnt); assert(get_private(back)->bo->refcnt); + if (get_private(front)->pixmap != get_drawable_pixmap(draw)) { + DBG(("%s: decoupled DRI2 front pixmap=%ld, actual pixmap=%ld\n", + __FUNCTION__, + get_private(front)->pixmap->drawable.serialNumber, + get_drawable_pixmap(draw)->drawable.serialNumber)); + goto fake; + } + if (get_private(back)->stale) { DBG(("%s: stale back buffer\n", __FUNCTION__)); goto skip; @@ -3317,6 +3326,7 @@ sna_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front, front = priv->front; assert(front->attachment == DRI2BufferFrontLeft); assert(get_private(front)->refcnt); + assert(get_private(front)->pixmap == get_drawable_pixmap(draw)); } if (win->clipList.extents.x2 <= win->clipList.extents.x1 || @@ -3331,16 +3341,8 @@ sna_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, DRI2BufferPtr front, } } - DBG(("%s: using front handle=%d, active_scanout?=%d\n", __FUNCTION__, get_private(front)->bo->handle, get_private(front)->bo->active_scanout)); + DBG(("%s: using front handle=%d, active_scanout?=%d, flush?=%d\n", __FUNCTION__, get_private(front)->bo->handle, get_private(front)->bo->active_scanout, sna_pixmap_from_drawable(draw)->flush)); assert(get_private(front)->bo->active_scanout); - if (get_private(front)->pixmap != get_drawable_pixmap(draw)) { - DBG(("%s: decoupled DRI2 front pixmap=%ld, actual pixmap=%ld\n", - __FUNCTION__, - get_private(front)->pixmap->drawable.serialNumber, - get_drawable_pixmap(draw)->drawable.serialNumber)); - goto skip; - } - assert(sna_pixmap_from_drawable(draw)->flush); /* Drawable not displayed... just complete the swap */ -- cgit v1.2.3