On Thu, Jun 11, 2015 at 5:59 AM, Michel Dänzer <[email protected]> wrote: > From: Michel Dänzer <[email protected]> > > Fixes corrupted display and hangs when switching between DRI2 and DRI3 > fullscreen apps, e.g. a compositor using DRI3 and a fullscreen app using > DRI2 or vice versa. > > Signed-off-by: Michel Dänzer <[email protected]>
Reviewed-by: Alex Deucher <[email protected]> > --- > src/drmmode_display.h | 3 +++ > src/radeon_dri2.c | 23 +++++++++++++++++------ > src/radeon_present.c | 17 ++++++++++++++++- > 3 files changed, 36 insertions(+), 7 deletions(-) > > diff --git a/src/drmmode_display.h b/src/drmmode_display.h > index 2fdd3e0..ca42c7d 100644 > --- a/src/drmmode_display.h > +++ b/src/drmmode_display.h > @@ -54,6 +54,9 @@ typedef struct { > int count_crtcs; > > Bool delete_dp_12_displays; > + > + Bool dri2_flipping; > + Bool present_flipping; > } drmmode_rec, *drmmode_ptr; > > typedef struct { > diff --git a/src/radeon_dri2.c b/src/radeon_dri2.c > index a1f0145..7587a0c 100644 > --- a/src/radeon_dri2.c > +++ b/src/radeon_dri2.c > @@ -584,6 +584,7 @@ static void > radeon_dri2_flip_event_handler(ScrnInfoPtr scrn, uint32_t frame, uint64_t > usec, > void *event_data) > { > + RADEONInfoPtr info = RADEONPTR(scrn); > DRI2FrameEventPtr flip = event_data; > unsigned tv_sec, tv_usec; > DrawablePtr drawable; > @@ -627,6 +628,7 @@ radeon_dri2_flip_event_handler(ScrnInfoPtr scrn, uint32_t > frame, uint64_t usec, > DRI2SwapComplete(flip->client, drawable, frame, tv_sec, tv_usec, > DRI2_FLIP_COMPLETE, flip->event_complete, > flip->event_data); > + info->drmmode.dri2_flipping = FALSE; > break; > default: > xf86DrvMsg(scrn->scrnIndex, X_WARNING, "%s: unknown vblank event > received\n", __func__); > @@ -644,6 +646,7 @@ radeon_dri2_schedule_flip(ScrnInfoPtr scrn, ClientPtr > client, > DRI2BufferPtr back, DRI2SwapEventPtr func, > void *data, unsigned int target_msc) > { > + RADEONInfoPtr info = RADEONPTR(scrn); > struct dri2_buffer_priv *back_priv; > struct radeon_bo *bo; > DRI2FrameEventPtr flip_info; > @@ -670,11 +673,16 @@ radeon_dri2_schedule_flip(ScrnInfoPtr scrn, ClientPtr > client, > back_priv = back->driverPrivate; > bo = radeon_get_pixmap_bo(back_priv->pixmap); > > - return radeon_do_pageflip(scrn, client, bo->handle, > - RADEON_DRM_QUEUE_ID_DEFAULT, flip_info, > - ref_crtc_hw_id, > - radeon_dri2_flip_event_handler, > - radeon_dri2_flip_event_abort); > + if (radeon_do_pageflip(scrn, client, bo->handle, > + RADEON_DRM_QUEUE_ID_DEFAULT, flip_info, > + ref_crtc_hw_id, > + radeon_dri2_flip_event_handler, > + radeon_dri2_flip_event_abort)) { > + info->drmmode.dri2_flipping = TRUE; > + return TRUE; > + } > + > + return FALSE; > } > > static Bool > @@ -742,8 +750,11 @@ static Bool > can_flip(ScrnInfoPtr pScrn, DrawablePtr draw, > DRI2BufferPtr front, DRI2BufferPtr back) > { > + RADEONInfoPtr info = RADEONPTR(pScrn); > + > return draw->type == DRAWABLE_WINDOW && > - RADEONPTR(pScrn)->allowPageFlip && > + info->allowPageFlip && > + !info->drmmode.present_flipping && > pScrn->vtSema && > DRI2CanFlip(draw) && > can_exchange(pScrn, draw, front, back); > diff --git a/src/radeon_present.c b/src/radeon_present.c > index 2626044..c48df13 100644 > --- a/src/radeon_present.c > +++ b/src/radeon_present.c > @@ -50,6 +50,7 @@ > > struct radeon_present_vblank_event { > uint64_t event_id; > + xf86CrtcPtr crtc; > }; > > static uint32_t crtc_select(int crtc_id) > @@ -238,6 +239,9 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr > window, PixmapPtr pixmap, > if (!sync_flip) > return FALSE; > > + if (info->drmmode.dri2_flipping) > + return FALSE; > + > /* The kernel driver doesn't handle flipping between BOs with different > * tiling parameters correctly yet > */ > @@ -266,8 +270,12 @@ radeon_present_check_flip(RRCrtcPtr crtc, WindowPtr > window, PixmapPtr pixmap, > static void > radeon_present_flip_event(ScrnInfoPtr scrn, uint32_t msc, uint64_t ust, void > *pageflip_data) > { > + RADEONInfoPtr info = RADEONPTR(scrn); > struct radeon_present_vblank_event *event = pageflip_data; > > + if (!event->crtc) > + info->drmmode.present_flipping = FALSE; > + > present_event_notify(event->event_id, ust, msc); > free(event); > } > @@ -293,6 +301,7 @@ radeon_present_flip(RRCrtcPtr crtc, uint64_t event_id, > uint64_t target_msc, > { > ScreenPtr screen = crtc->pScreen; > ScrnInfoPtr scrn = xf86ScreenToScrn(screen); > + RADEONInfoPtr info = RADEONPTR(scrn); > struct radeon_present_vblank_event *event; > xf86CrtcPtr xf86_crtc = crtc->devPrivate; > int crtc_id = xf86_crtc ? drmmode_get_crtc_id(xf86_crtc) : -1; > @@ -310,6 +319,7 @@ radeon_present_flip(RRCrtcPtr crtc, uint64_t event_id, > uint64_t target_msc, > return FALSE; > > event->event_id = event_id; > + event->crtc = xf86_crtc; > > ret = radeon_do_pageflip(scrn, RADEON_DRM_QUEUE_CLIENT_DEFAULT, handle, > event_id, event, crtc_id, > @@ -317,6 +327,8 @@ radeon_present_flip(RRCrtcPtr crtc, uint64_t event_id, > uint64_t target_msc, > radeon_present_flip_abort); > if (!ret) > xf86DrvMsg(scrn->scrnIndex, X_ERROR, "present flip failed\n"); > + else > + info->drmmode.present_flipping = TRUE; > > return ret; > } > @@ -328,6 +340,7 @@ static void > radeon_present_unflip(ScreenPtr screen, uint64_t event_id) > { > ScrnInfoPtr scrn = xf86ScreenToScrn(screen); > + RADEONInfoPtr info = RADEONPTR(scrn); > struct radeon_present_vblank_event *event; > PixmapPtr pixmap = screen->GetScreenPixmap(screen); > uint32_t handle; > @@ -348,8 +361,10 @@ radeon_present_unflip(ScreenPtr screen, uint64_t > 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) > + if (!ret) { > xf86DrvMsg(scrn->scrnIndex, X_ERROR, "present unflip failed\n"); > + 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
