sna: Avoid confusing failure to flip and flipping zero CRTC
During the present unflip path we blindly try to restore the original mode after a flip failure. However, it confuses flipping zero CRTC with a genuine failure. This has the result of undoing a DPMS change (e.g. xset dpms force dpms) under a DRI3 compositor. Reported-by: Jiri Slaby <jirislaby@gmail.com> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=81456 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
95f08c171e
commit
62f62f70ed
|
|
@ -4863,6 +4863,8 @@ sna_page_flip(struct sna *sna,
|
|||
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->scrn->vtSema);
|
||||
|
||||
if ((sna->flags & (data ? SNA_HAS_FLIP : SNA_HAS_ASYNC_FLIP)) == 0)
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1560,11 +1560,13 @@ can_flip(struct sna * sna,
|
|||
if (draw->type == DRAWABLE_PIXMAP)
|
||||
return false;
|
||||
|
||||
if (!sna->scrn->vtSema) {
|
||||
DBG(("%s: no, not attached to VT\n", __FUNCTION__));
|
||||
if (!sna->mode.front_active) {
|
||||
DBG(("%s: no, active CRTC\n", __FUNCTION__));
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(sna->scrn->vtSema);
|
||||
|
||||
if ((sna->flags & (SNA_HAS_FLIP | SNA_HAS_ASYNC_FLIP)) == 0) {
|
||||
DBG(("%s: no, pageflips disabled\n", __FUNCTION__));
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -193,16 +193,13 @@ static bool
|
|||
check_flip__crtc(struct sna *sna,
|
||||
RRCrtcPtr crtc)
|
||||
{
|
||||
if (!sna->scrn->vtSema) {
|
||||
DBG(("%s: not master\n", __FUNCTION__));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sna_crtc_is_on(crtc->devPrivate)) {
|
||||
DBG(("%s: CRTC off\n", __FUNCTION__));
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(sna->scrn->vtSema);
|
||||
|
||||
if (sna->mode.shadow_active) {
|
||||
DBG(("%s: shadow buffer active\n", __FUNCTION__));
|
||||
return false;
|
||||
|
|
@ -415,19 +412,28 @@ sna_present_flip(RRCrtcPtr crtc,
|
|||
static void
|
||||
sna_present_unflip(ScreenPtr screen, uint64_t event_id)
|
||||
{
|
||||
struct sna *sna = to_sna_from_screen(screen);
|
||||
struct kgem_bo *bo;
|
||||
|
||||
DBG(("%s(event=%lld)\n", __FUNCTION__, (long long)event_id));
|
||||
bo = get_flip_bo(screen->GetScreenPixmap(screen));
|
||||
if (bo == NULL || !page_flip(screen, NULL, event_id, bo)) {
|
||||
struct sna *sna = to_sna_from_screen(screen);
|
||||
if (sna->mode.front_active == 0) {
|
||||
const struct ust_msc *swap;
|
||||
DBG(("%s: failed, trying to restore original mode\n", __FUNCTION__));
|
||||
xf86SetDesiredModes(sna->scrn);
|
||||
|
||||
DBG(("%s: no CRTC active, perform no-op flip\n", __FUNCTION__));
|
||||
|
||||
notify:
|
||||
swap = sna_crtc_last_swap(sna_mode_first_crtc(sna));
|
||||
present_event_notify(event_id,
|
||||
ust64(swap->tv_sec, swap->tv_usec),
|
||||
swap->msc);
|
||||
return;
|
||||
}
|
||||
|
||||
bo = get_flip_bo(screen->GetScreenPixmap(screen));
|
||||
if (bo == NULL || !page_flip(screen, NULL, event_id, bo)) {
|
||||
DBG(("%s: failed, trying to restore original mode\n", __FUNCTION__));
|
||||
xf86SetDesiredModes(sna->scrn);
|
||||
goto notify;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue