[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