[PATCH] [RFC] present: let unflipping fail.

Dave Airlie airlied at gmail.com
Mon Jun 22 01:18:31 PDT 2015


From: Dave Airlie <airlied at redhat.com>

With modesetting driver:
run mutter
run glxgears -fullscreen
xset dpms force off
xset dpms force on

after a few cycles, things will stop changing on the screen,

This is because we try to unflip while we are on the "fake"
crtc, so unflip fails, but we set the unflip event.

So change the ABI so unflip can fail, and when it fails,
clear the unflip event id.

There may be more work to do here, but this seems to make
the hangs not happen anymore.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 hw/xfree86/drivers/modesetting/present.c | 10 +++++++---
 present/present.c                        |  6 +++++-
 present/present.h                        |  2 +-
 3 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/hw/xfree86/drivers/modesetting/present.c b/hw/xfree86/drivers/modesetting/present.c
index 1dc1959..54dab99 100644
--- a/hw/xfree86/drivers/modesetting/present.c
+++ b/hw/xfree86/drivers/modesetting/present.c
@@ -574,20 +574,24 @@ ms_present_flip(RRCrtcPtr crtc,
 /*
  * Queue a flip back to the normal frame buffer
  */
-static void
+static Bool
 ms_present_unflip(ScreenPtr screen, uint64_t event_id)
 {
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
     PixmapPtr pixmap = screen->GetScreenPixmap(screen);
     Bool ret;
 
-    if (!ms_present_check_flip(NULL, screen->root, pixmap, TRUE))
-        return;
+    if (!ms_present_check_flip(NULL, screen->root, pixmap, TRUE)) {
+        xf86DrvMsg(scrn->scrnIndex, X_ERROR, "present unflip failed 1\n");
+        return FALSE;
+    }
 
     ret = ms_do_pageflip(screen, pixmap, -1, FALSE, event_id);
     if (!ret) {
         xf86DrvMsg(scrn->scrnIndex, X_ERROR, "present unflip failed\n");
+        return FALSE;
     }
+    return TRUE;
 }
 #endif
 
diff --git a/present/present.c b/present/present.c
index 743a6c5..b5a8787 100644
--- a/present/present.c
+++ b/present/present.c
@@ -410,6 +410,7 @@ present_unflip(ScreenPtr screen)
 {
     present_screen_priv_ptr screen_priv = present_screen_priv(screen);
     PixmapPtr pixmap = (*screen->GetScreenPixmap)(screen);
+    Bool ret;
 
     assert (!screen_priv->unflip_event_id);
     assert (!screen_priv->flip_pending);
@@ -428,7 +429,10 @@ present_unflip(ScreenPtr screen)
     }
     screen_priv->unflip_event_id = ++present_event_id;
     DebugPresent(("u %lld\n", screen_priv->unflip_event_id));
-    (*screen_priv->info->unflip) (screen, screen_priv->unflip_event_id);
+    ret = (*screen_priv->info->unflip) (screen, screen_priv->unflip_event_id);
+    if (ret == FALSE) {
+        screen_priv->unflip_event_id = 0;
+    }
 }
 
 static void
diff --git a/present/present.h b/present/present.h
index aab2e16..1b145fc 100644
--- a/present/present.h
+++ b/present/present.h
@@ -80,7 +80,7 @@ typedef Bool (*present_flip_ptr) (RRCrtcPtr crtc,
  *
  * present_event_notify should be called with 'event_id' when the unflip occurs.
  */
-typedef void (*present_unflip_ptr) (ScreenPtr screen,
+typedef Bool (*present_unflip_ptr) (ScreenPtr screen,
                                     uint64_t event_id);
 
 #define PRESENT_SCREEN_INFO_VERSION        0
-- 
2.4.1



More information about the xorg-devel mailing list