From ed7bcae0ab0af41bc51dbcb729e4af34e2ba5094 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 13 Jun 2015 12:53:19 +0100 Subject: [PATCH] sna/dri2: SWAP_THROTTLE is also used for a delayed SWAP If there is already a pending operation on the drawable, the swap is queued. It is queued with SWAP_THROTTLE which classes with the vblank_mode=0 chaining, so the choice is to either review all other uses of SWAP_THROTTLE and duplicate the chain swap handling, or to choose when use to the alternate copy or back buffer. This patch opts for the latter. Fixes regression from commit dcb4d323ca19f86fbe0230378ac9035161a70f9e Author: Chris Wilson Date: Thu Jun 11 13:54:49 2015 +0100 sna/dri2: Mark the pending backbuffer copy as active Reported-by: Christoph Haag Reported-by: Andreas Reis Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=90968 Signed-off-by: Chris Wilson --- src/sna/sna_dri2.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c index 6cb346f4..1041c52e 100644 --- a/src/sna/sna_dri2.c +++ b/src/sna/sna_dri2.c @@ -2261,16 +2261,10 @@ static void chain_swap(struct sna_dri2_event *chain) * exchange back again so that we are consistent with the * client once more. */ - assert(get_private(chain->back)->copy); - DBG(("%s: removing active marker [%d] from handle=%d\n", - __FUNCTION__, - get_private(chain->back)->copy->active_scanout, - get_private(chain->back)->copy->handle)); - assert(get_private(chain->back)->copy->active_scanout); - get_private(chain->back)->copy->active_scanout--; - - tmp = get_private(chain->back)->bo; - get_private(chain->back)->bo = get_private(chain->back)->copy; + if (get_private(chain->back)->copy) { + tmp = get_private(chain->back)->bo; + get_private(chain->back)->bo = get_private(chain->back)->copy; + } if (can_xchg(chain->sna, chain->draw, chain->front, chain->back)) { sna_dri2_xchg(chain->draw, chain->front, chain->back); @@ -2280,10 +2274,21 @@ static void chain_swap(struct sna_dri2_event *chain) assert(chain->queued); __sna_dri2_copy_event(chain, DRI2_BO); } - get_private(chain->back)->bo = tmp; - kgem_bo_destroy(&chain->sna->kgem, - get_private(chain->back)->copy); - get_private(chain->back)->copy = NULL; + + if (get_private(chain->back)->copy) { + DBG(("%s: removing active marker [%d] from handle=%d\n", + __FUNCTION__, + get_private(chain->back)->copy->active_scanout, + get_private(chain->back)->copy->handle)); + assert(get_private(chain->back)->copy->active_scanout); + get_private(chain->back)->copy->active_scanout--; + + kgem_bo_destroy(&chain->sna->kgem, + get_private(chain->back)->copy); + get_private(chain->back)->copy = NULL; + + get_private(chain->back)->bo = tmp; + } case SWAP: break; default: