summaryrefslogtreecommitdiff
path: root/src/sna/sna_dri2.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2015-06-13 12:53:19 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2015-06-13 13:19:40 +0100
commited7bcae0ab0af41bc51dbcb729e4af34e2ba5094 (patch)
tree9f99fba131fbc5bc8c04eaadccc74d54f4d97f2a /src/sna/sna_dri2.c
parent7e965a45d1bb3d39ddb9c62dde536d0d66e92537 (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.c33
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: