On Wed, Jul 8, 2015 at 5:25 AM, Michel Dänzer <[email protected]> wrote: > From: Michel Dänzer <[email protected]> > > It's not always possible to use the page flip ioctl for this, e.g. > during DPMS off. We were previously just skipping the unflip in that > case, which could result in hangs when setting DPMS off while a > fullscreen Present app is running, e.g. at the GNOME3 lock screen. > > Signed-off-by: Michel Dänzer <[email protected]>
Having to do a full modeset is pretty ugly, but I don't have a better solution. Series is: Reviewed-by: Alex Deucher <[email protected]> > --- > src/drmmode_display.c | 19 +++++++++++++++---- > src/drmmode_display.h | 3 +++ > src/radeon_present.c | 46 ++++++++++++++++++++++++++++++++++------------ > 3 files changed, 52 insertions(+), 16 deletions(-) > > diff --git a/src/drmmode_display.c b/src/drmmode_display.c > index 8483909..ad2f48b 100644 > --- a/src/drmmode_display.c > +++ b/src/drmmode_display.c > @@ -769,6 +769,9 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr > mode, > > if (crtc->scrn->pScreen) > xf86CrtcSetScreenSubpixelOrder(crtc->scrn->pScreen); > + > + drmmode_crtc->need_modeset = FALSE; > + > /* go through all the outputs and force DPMS them back on? */ > for (i = 0; i < xf86_config->num_output; i++) { > xf86OutputPtr output = xf86_config->output[i]; > @@ -1153,20 +1156,28 @@ 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; > > if (!koutput) > return; > > - if (mode != DPMSModeOn && output->crtc) > - drmmode_do_crtc_dpms(output->crtc, mode); > + if (mode != DPMSModeOn && crtc) > + drmmode_do_crtc_dpms(crtc, mode); > > drmModeConnectorSetProperty(drmmode->fd, koutput->connector_id, > drmmode_output->dpms_enum_id, mode); > > - if (mode == DPMSModeOn && output->crtc) > - drmmode_do_crtc_dpms(output->crtc, 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); > + else > + drmmode_do_crtc_dpms(crtc, mode); > + } > } > > > diff --git a/src/drmmode_display.h b/src/drmmode_display.h > index ca42c7d..ab6c590 100644 > --- a/src/drmmode_display.h > +++ b/src/drmmode_display.h > @@ -99,6 +99,9 @@ typedef struct { > uint32_t interpolated_vblanks; > uint16_t lut_r[256], lut_g[256], lut_b[256]; > int prime_pixmap_x; > + > + /* Modeset needed for DPMS on */ > + Bool need_modeset; > } drmmode_crtc_private_rec, *drmmode_crtc_private_ptr; > > typedef struct { > diff --git a/src/radeon_present.c b/src/radeon_present.c > index c48df13..bc1053e 100644 > --- a/src/radeon_present.c > +++ b/src/radeon_present.c > @@ -341,30 +341,52 @@ radeon_present_unflip(ScreenPtr screen, uint64_t > event_id) > { > ScrnInfoPtr scrn = xf86ScreenToScrn(screen); > RADEONInfoPtr info = RADEONPTR(scrn); > + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); > struct radeon_present_vblank_event *event; > PixmapPtr pixmap = screen->GetScreenPixmap(screen); > uint32_t handle; > - Bool ret; > + int i; > > if (!radeon_present_check_flip(NULL, screen->root, pixmap, TRUE)) > - return; > + goto modeset; > > - if (!radeon_get_pixmap_handle(pixmap, &handle)) > - return; > + if (!radeon_get_pixmap_handle(pixmap, &handle)) { > + ErrorF("%s: radeon_get_pixmap_handle failed, display might freeze\n", > + __func__); > + goto modeset; > + } > > event = calloc(1, sizeof(struct radeon_present_vblank_event)); > - if (!event) > - return; > + if (!event) { > + ErrorF("%s: calloc failed, display might freeze\n", __func__); > + goto modeset; > + } > > event->event_id = event_id; > > - ret = radeon_do_pageflip(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, handle, > - event_id, event, -1, radeon_present_flip_event, > - radeon_present_flip_abort); > - if (!ret) { > - xf86DrvMsg(scrn->scrnIndex, X_ERROR, "present unflip failed\n"); > - info->drmmode.present_flipping = FALSE; > + if (radeon_do_pageflip(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, handle, > + event_id, event, -1, radeon_present_flip_event, > + radeon_present_flip_abort)) > + return; > + > +modeset: > + for (i = 0; i < config->num_crtc; i++) { > + xf86CrtcPtr crtc = config->crtc[i]; > + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; > + > + 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); > + > + info->drmmode.present_flipping = FALSE; > } > > static present_screen_info_rec radeon_present_screen_info = { > -- > 2.1.4 > > _______________________________________________ > xorg-driver-ati mailing list > [email protected] > http://lists.x.org/mailman/listinfo/xorg-driver-ati _______________________________________________ xorg-driver-ati mailing list [email protected] http://lists.x.org/mailman/listinfo/xorg-driver-ati
