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 <chris@chris-wilson.co.uk>
This commit is contained in:
parent
74553bf4d2
commit
3fc942b374
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue