[PATCH] modesetting: handle unflip while dpms off

Dave Airlie airlied at gmail.com
Mon Jun 22 22:10:27 PDT 2015


From: Dave Airlie <airlied at redhat.com>

This is port of Michel's changse from the ATI driver.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 hw/xfree86/drivers/modesetting/drmmode_display.c |  9 +++++++++
 hw/xfree86/drivers/modesetting/drmmode_display.h |  2 ++
 hw/xfree86/drivers/modesetting/present.c         | 23 +++++++++++++++++++----
 3 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 40fe6b4..5ab74a3 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -398,6 +398,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
         if (crtc->scrn->pScreen)
             xf86CrtcSetScreenSubpixelOrder(crtc->scrn->pScreen);
 
+        drmmode_crtc->need_modeset = FALSE;
         crtc->funcs->dpms(crtc, DPMSModeOn);
 
         /* go through all the outputs and force DPMS them back on? */
@@ -1035,6 +1036,7 @@ static void
 drmmode_output_dpms(xf86OutputPtr output, int mode)
 {
     drmmode_output_private_ptr drmmode_output = output->driver_private;
+    xf86CrtcPtr crtc = output->crtc;
     drmModeConnectorPtr koutput = drmmode_output->mode_output;
     drmmode_ptr drmmode = drmmode_output->drmmode;
 
@@ -1043,6 +1045,13 @@ drmmode_output_dpms(xf86OutputPtr output, int mode)
 
     drmModeConnectorSetProperty(drmmode->fd, koutput->connector_id,
                                 drmmode_output->dpms_enum_id, mode);
+
+    if (mode == DPMSModeOn && crtc) {
+        drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+        if (drmmode_crtc->need_modeset)
+            drmmode_set_mode_major(crtc, &crtc->mode, crtc->rotation,
+                                   crtc->x, crtc->y);
+    }
     return;
 }
 
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index 09844e5..9ceddf2 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -109,6 +109,8 @@ typedef struct {
     uint32_t msc_prev;
     uint64_t msc_high;
     /** @} */
+
+    Bool need_modeset;
 } drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
 
 typedef struct {
diff --git a/hw/xfree86/drivers/modesetting/present.c b/hw/xfree86/drivers/modesetting/present.c
index 1dc1959..82aeab0 100644
--- a/hw/xfree86/drivers/modesetting/present.c
+++ b/hw/xfree86/drivers/modesetting/present.c
@@ -580,14 +580,29 @@ ms_present_unflip(ScreenPtr screen, uint64_t event_id)
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
     PixmapPtr pixmap = screen->GetScreenPixmap(screen);
     Bool ret;
+    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+    int i;
 
-    if (!ms_present_check_flip(NULL, screen->root, pixmap, TRUE))
+    if (ms_present_check_flip(NULL, screen->root, pixmap, TRUE) &&
+        ms_do_pageflip(screen, pixmap, -1, FALSE, event_id)) {
         return;
+    }
+
+    for (i = 0; i < config->num_crtc; i++) {
+        xf86CrtcPtr crtc = config->crtc[i];
+	drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 
-    ret = ms_do_pageflip(screen, pixmap, -1, FALSE, event_id);
-    if (!ret) {
-        xf86DrvMsg(scrn->scrnIndex, X_ERROR, "present unflip failed\n");
+	if (!crtc->enabled)
+	    continue;
+
+	if (drmmode_crtc->dpms_mode == DPMSModeOn)
+	    crtc->funcs->set_mode_major(crtc, &crtc->mode, crtc->rotation,
+					crtc->x, crtc->y);
+	else
+	    drmmode_crtc->need_modeset = TRUE;
     }
+
+    present_event_notify(event_id, 0, 0);
 }
 #endif
 
-- 
2.4.1



More information about the xorg-devel mailing list