From 3fc942b3744958fe9570bda2dfbc47a1a0dbae57 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 15 Feb 2015 09:30:52 +0000 Subject: [PATCH] sna/present: Avoid tricks with the TearFree flag Modifying the flag may cause havoc if we need to modeset whilst Present is in control as the CRTC will be setup without reference to TearFree, but then when Present unflips, we restore the stale configuration. So let's have a separate flag just to disable TearFree flips when a Present flip chain is active. Signed-off-by: Chris Wilson --- src/sna/sna.h | 2 +- src/sna/sna_display.c | 10 +++++++--- src/sna/sna_present.c | 26 +++++++++----------------- 3 files changed, 17 insertions(+), 21 deletions(-) diff --git a/src/sna/sna.h b/src/sna/sna.h index bbcea080..b7ed2b34 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -287,6 +287,7 @@ struct sna { unsigned rr_active; unsigned flip_active; unsigned hidden; + bool shadow_enabled; bool dirty; int max_crtc_width, max_crtc_height; @@ -356,7 +357,6 @@ struct sna { bool open; #if HAVE_PRESENT uint64_t unflip; - void *tearfree; #endif } present; diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index ac130c75..cbfa921a 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -1399,6 +1399,7 @@ static bool sna_mode_enable_shadow(struct sna *sna) return false; DamageRegister(&sna->front->drawable, sna->mode.shadow_damage); + sna->mode.shadow_enabled = true; return true; } @@ -1406,8 +1407,10 @@ static void sna_mode_disable_shadow(struct sna *sna) { struct sna_pixmap *priv; - if (!sna->mode.shadow_damage) + if (!sna->mode.shadow_damage) { + assert(!sna->mode.shadow_enabled); return; + } DBG(("%s\n", __FUNCTION__)); @@ -1418,6 +1421,7 @@ static void sna_mode_disable_shadow(struct sna *sna) DamageUnregister(&sna->front->drawable, sna->mode.shadow_damage); DamageDestroy(sna->mode.shadow_damage); sna->mode.shadow_damage = NULL; + sna->mode.shadow_enabled = false; if (sna->mode.shadow) { kgem_bo_destroy(&sna->kgem, sna->mode.shadow); @@ -4448,6 +4452,7 @@ sna_mode_resize(ScrnInfoPtr scrn, int width, int height) for (i = 0; i < sna->mode.num_real_crtc; i++) sna_crtc_disable_shadow(sna, to_sna_crtc(config->crtc[i])); assert(sna->mode.shadow_active == 0); + assert(!sna->mode.shadow_enabled); assert(sna->mode.shadow_damage == NULL); assert(sna->mode.shadow == NULL); @@ -5422,7 +5427,6 @@ sna_page_flip(struct sna *sna, assert(bo->refcnt); assert((sna->flags & SNA_IS_HOSTED) == 0); - assert((sna->flags & SNA_TEAR_FREE) == 0); assert(sna->mode.flip_active == 0); assert(sna->mode.front_active); assert(!sna->mode.hidden); @@ -7233,7 +7237,7 @@ void sna_mode_redisplay(struct sna *sna) return; } - if (!sna->mode.shadow_damage) + if (!sna->mode.shadow_enabled || !sna->mode.shadow_damage) return; DBG(("%s: posting shadow damage? %d (flips pending? %d, mode reconfiguration pending? %d)\n", diff --git a/src/sna/sna_present.c b/src/sna/sna_present.c index 613721c3..881b18a0 100644 --- a/src/sna/sna_present.c +++ b/src/sna/sna_present.c @@ -533,11 +533,9 @@ sna_present_flip(RRCrtcPtr crtc, return FALSE; } - if (sna->flags & SNA_TEAR_FREE) { - sna->present.tearfree = sna->mode.shadow_damage; - sna->mode.shadow_damage = NULL; - sna->flags &= ~SNA_TEAR_FREE; - } + if (sna->flags & SNA_TEAR_FREE) + sna->mode.shadow_enabled = false; + assert(!sna->mode.shadow_enabled); if (sna->mode.flip_active) { DBG(("%s: flips still pending\n", __FUNCTION__)); @@ -555,7 +553,6 @@ sna_present_unflip(ScreenPtr screen, uint64_t event_id) { struct sna *sna = to_sna_from_screen(screen); struct kgem_bo *bo; - bool ok; DBG(("%s(event=%lld)\n", __FUNCTION__, (long long)event_id)); if (sna->mode.front_active == 0 || sna->mode.rr_active) { @@ -580,6 +577,9 @@ notify: return; } + if (sna->flags & SNA_TEAR_FREE) + sna->mode.shadow_enabled = sna->mode.shadow_damage != NULL; + bo = get_flip_bo(screen->GetScreenPixmap(screen)); if (bo == NULL) { reset_mode: @@ -588,21 +588,13 @@ reset_mode: goto notify; } - ok = false; if (sna->flags & SNA_HAS_ASYNC_FLIP) { DBG(("%s: trying async flip restore\n", __FUNCTION__)); - ok = flip__async(sna, NULL, event_id, 0, bo); - } - if (!ok) - ok = flip(sna, NULL, event_id, 0, bo); - - if (sna->present.tearfree) { - sna->flags |= SNA_TEAR_FREE; - sna->mode.shadow_damage = sna->present.tearfree; - sna->present.tearfree = NULL; + if (flip__async(sna, NULL, event_id, 0, bo)) + return; } - if (!ok) + if (!flip(sna, NULL, event_id, 0, bo)) goto reset_mode; }