diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2015-06-13 12:53:19 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2015-06-13 13:19:40 +0100 |
commit | ed7bcae0ab0af41bc51dbcb729e4af34e2ba5094 (patch) | |
tree | 9f99fba131fbc5bc8c04eaadccc74d54f4d97f2a /src/sna/sna_dri2.c | |
parent | 7e965a45d1bb3d39ddb9c62dde536d0d66e92537 (diff) |
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 <chris@chris-wilson.co.uk>
Date: Thu Jun 11 13:54:49 2015 +0100
sna/dri2: Mark the pending backbuffer copy as active
Reported-by: Christoph Haag <haagch@frickel.club>
Reported-by: Andreas Reis <andreas.reis@gmail.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=90968
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna/sna_dri2.c')
-rw-r--r-- | src/sna/sna_dri2.c | 33 |
1 files 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: |