On Mon, Feb 29, 2016 at 4:58 AM, Michel Dänzer <[email protected]> wrote: > From: Michel Dänzer <[email protected]> > > If we set a mode while a flip is pending, the kernel driver may program > the flip to the hardware after the modeset. If that happens, the hardware > will display the BO from the flip, whereas we will assume it displays the > BO from the modeset. In other words, the display will most likely freeze, > at least until another modeset. > > Prevent this condition by waiting for a pending flip to finish before > setting a mode. > > Fixes display freezing when setting rotation or a transform with > TearFree enabled. > > Signed-off-by: Michel Dänzer <[email protected]>
For the series: Reviewed-by: Alex Deucher <[email protected]> > --- > src/drmmode_display.c | 13 +++++++++++++ > src/drmmode_display.h | 6 +++++- > src/radeon_kms.c | 2 ++ > 3 files changed, 20 insertions(+), 1 deletion(-) > > diff --git a/src/drmmode_display.c b/src/drmmode_display.c > index 24430a2..f1ca02c 100644 > --- a/src/drmmode_display.c > +++ b/src/drmmode_display.c > @@ -760,6 +760,12 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr > mode, > radeon_bo_wait(drmmode_crtc->scanout[0].bo); > } > } > + > + /* Wait for any pending flip to finish */ > + do {} while (drmmode_crtc->flip_pending && > + drmHandleEvent(drmmode->fd, > + &drmmode->event_context) > 0); > + > if (drmModeSetCrtc(drmmode->fd, > drmmode_crtc->mode_crtc->crtc_id, > fb_id, x, y, output_ids, > @@ -2024,6 +2030,7 @@ static const xf86CrtcConfigFuncsRec > drmmode_xf86crtc_config_funcs = { > static void > drmmode_flip_abort(xf86CrtcPtr crtc, void *event_data) > { > + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; > drmmode_flipdata_ptr flipdata = event_data; > > if (--flipdata->flip_count == 0) { > @@ -2032,11 +2039,14 @@ drmmode_flip_abort(xf86CrtcPtr crtc, void *event_data) > flipdata->abort(crtc, flipdata->event_data); > free(flipdata); > } > + > + drmmode_crtc->flip_pending = FALSE; > } > > static void > drmmode_flip_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec, void > *event_data) > { > + drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; > RADEONInfoPtr info = RADEONPTR(crtc->scrn); > drmmode_flipdata_ptr flipdata = event_data; > > @@ -2059,6 +2069,8 @@ drmmode_flip_handler(xf86CrtcPtr crtc, uint32_t frame, > uint64_t usec, void *even > > free(flipdata); > } > + > + drmmode_crtc->flip_pending = FALSE; > } > > > @@ -2582,6 +2594,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, ClientPtr > client, > "flip queue failed: %s\n", > strerror(errno)); > goto error; > } > + drmmode_crtc->flip_pending = TRUE; > drm_queue = NULL; > } > > diff --git a/src/drmmode_display.h b/src/drmmode_display.h > index 99c6c91..c295735 100644 > --- a/src/drmmode_display.h > +++ b/src/drmmode_display.h > @@ -95,8 +95,12 @@ typedef struct { > uint16_t lut_r[256], lut_g[256], lut_b[256]; > int prime_pixmap_x; > > - /* Modeset needed for DPMS on */ > + /* Modeset needed (for DPMS on or after a page flip crossing with a > + * modeset) > + */ > Bool need_modeset; > + /* A flip is pending for this CRTC */ > + Bool flip_pending; > } drmmode_crtc_private_rec, *drmmode_crtc_private_ptr; > > typedef struct { > diff --git a/src/radeon_kms.c b/src/radeon_kms.c > index 3768983..44fe71e 100644 > --- a/src/radeon_kms.c > +++ b/src/radeon_kms.c > @@ -483,6 +483,7 @@ radeon_scanout_flip_abort(xf86CrtcPtr crtc, void > *event_data) > drmmode_crtc_private_ptr drmmode_crtc = event_data; > > drmmode_crtc->scanout_update_pending = FALSE; > + drmmode_crtc->flip_pending = FALSE; > } > > static void > @@ -523,6 +524,7 @@ radeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info, > > drmmode_crtc->scanout_id = scanout_id; > drmmode_crtc->scanout_update_pending = TRUE; > + drmmode_crtc->flip_pending = TRUE; > } > > static void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL) > -- > 2.7.0 > > _______________________________________________ > xorg-driver-ati mailing list > [email protected] > https://lists.x.org/mailman/listinfo/xorg-driver-ati _______________________________________________ xorg-driver-ati mailing list [email protected] https://lists.x.org/mailman/listinfo/xorg-driver-ati
