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 dcb4d323ca
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>
This commit is contained in:
Chris Wilson 2015-06-13 12:53:19 +01:00
parent 7e965a45d1
commit ed7bcae0ab
1 changed files with 19 additions and 14 deletions

View File

@ -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: