summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-07-17 10:06:06 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2014-07-17 10:06:06 +0100
commit62f62f70eda97a3ef18c5144031fdf1cb2b7dad0 (patch)
treecd5a377c36f2a64d2ede3386de18e4879cc08cb4
parent95f08c171ebd9b594112ab006c4460702a22bec1 (diff)
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>
-rw-r--r--src/sna/sna_display.c2
-rw-r--r--src/sna/sna_dri2.c6
-rw-r--r--src/sna/sna_present.c26
3 files changed, 22 insertions, 12 deletions
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 747d261f..7c70b4cc 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -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;
diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 0b343cec..be5d8141 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -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;
diff --git a/src/sna/sna_present.c b/src/sna/sna_present.c
index dd4771c9..a1dfc91e 100644
--- a/src/sna/sna_present.c
+++ b/src/sna/sna_present.c
@@ -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;
}
}