Signed-off-by: Qiang Yu <Qiang.Yu at amd.com> --- hw/xfree86/drivers/modesetting/dri2.c | 13 +++++++++++-- hw/xfree86/drivers/modesetting/drmmode_display.h | 3 +++ hw/xfree86/drivers/modesetting/present.c | 15 +++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/hw/xfree86/drivers/modesetting/dri2.c b/hw/xfree86/drivers/modesetting/dri2.c index 11e0e6f..1abf98c 100644 --- a/hw/xfree86/drivers/modesetting/dri2.c +++ b/hw/xfree86/drivers/modesetting/dri2.c @@ -423,9 +423,14 @@ ms_dri2_flip_abort(void *data) { struct ms_crtc_pageflip *flip = data; struct ms_flipdata *flipdata = flip->flipdata; + ScreenPtr screen = flipdata->screen; + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + modesettingPtr ms = modesettingPTR(scrn); - if (flipdata->flip_count == 1) - free(flipdata->event); + if (flipdata->flip_count == 1) { + ms->drmmode.dri2_flipping = FALSE; + free(flipdata->event); + } ms_dri2_flip_free(flip); } @@ -469,6 +474,8 @@ ms_dri2_schedule_flip(ms_dri2_frame_event_ptr info) { DrawablePtr draw = info->drawable; ScreenPtr screen = draw->pScreen; + ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + modesettingPtr ms = modesettingPTR(scrn); ms_dri2_buffer_private_ptr back_priv = info->back->driverPrivate; struct ms_dri2_vblank_event *event; drmmode_crtc_private_ptr drmmode_crtc = info->crtc->driver_private; @@ -486,6 +493,7 @@ ms_dri2_schedule_flip(ms_dri2_frame_event_ptr info) drmmode_crtc->vblank_pipe, FALSE, ms_dri2_flip_handler, ms_dri2_flip_abort)) { + ms->drmmode.dri2_flipping = TRUE; return TRUE; } return FALSE; @@ -571,6 +579,7 @@ can_flip(ScrnInfoPtr scrn, DrawablePtr draw, return draw->type == DRAWABLE_WINDOW && ms->drmmode.pageflip && + !ms->drmmode.present_flipping && scrn->vtSema && DRI2CanFlip(draw) && can_exchange(scrn, draw, front, back); } diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h index 5499c16..f774250 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.h +++ b/hw/xfree86/drivers/modesetting/drmmode_display.h @@ -80,6 +80,9 @@ typedef struct { Bool is_secondary; PixmapPtr fbcon_pixmap; + + Bool dri2_flipping; + Bool present_flipping; } drmmode_rec, *drmmode_ptr; typedef struct { diff --git a/hw/xfree86/drivers/modesetting/present.c b/hw/xfree86/drivers/modesetting/present.c index f4318b4..d10c674 100644 --- a/hw/xfree86/drivers/modesetting/present.c +++ b/hw/xfree86/drivers/modesetting/present.c @@ -53,6 +53,7 @@ struct ms_present_vblank_event { uint64_t event_id; + Bool unflip; }; static RRCrtcPtr @@ -221,6 +222,7 @@ ms_present_flip_handler(uint64_t msc, uint64_t ust, void *data) ScrnInfoPtr scrn = xf86ScreenToScrn(screen); modesettingPtr ms = modesettingPTR(scrn); struct ms_flipdata *flipdata = flip->flipdata; + struct ms_present_vblank_event *event = flipdata->event; DebugPresent(("\t\tms:fh %lld c %d msc %llu ust %llu\n", (long long) flipdata->event->event_id, @@ -238,6 +240,8 @@ ms_present_flip_handler(uint64_t msc, uint64_t ust, void *data) flipdata->flip_count, (long long) flipdata->fe_msc, (long long) flipdata->fe_usec)); + if (event->unflip) + ms->drmmode.present_flipping = FALSE; ms_present_vblank_handler(flipdata->fe_msc, flipdata->fe_usec, @@ -284,6 +288,9 @@ ms_present_check_flip(RRCrtcPtr crtc, if (!ms->drmmode.pageflip) return FALSE; + if (ms->drmmode.dri2_flipping) + return FALSE; + if (!scrn->vtSema) return FALSE; @@ -330,6 +337,7 @@ ms_present_flip(RRCrtcPtr crtc, { ScreenPtr screen = crtc->pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + modesettingPtr ms = modesettingPTR(scrn); xf86CrtcPtr xf86_crtc = crtc->devPrivate; drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private; Bool ret; @@ -343,10 +351,14 @@ ms_present_flip(RRCrtcPtr crtc, return FALSE; event->event_id = event_id; + event->unflip = FALSE; + ret = ms_do_pageflip(screen, pixmap, event, drmmode_crtc->vblank_pipe, !sync_flip, ms_present_flip_handler, ms_present_flip_abort); if (!ret) xf86DrvMsg(scrn->scrnIndex, X_ERROR, "present flip failed\n"); + else + ms->drmmode.present_flipping = TRUE; return ret; } @@ -358,6 +370,7 @@ static void ms_present_unflip(ScreenPtr screen, uint64_t event_id) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + modesettingPtr ms = modesettingPTR(scrn); PixmapPtr pixmap = screen->GetScreenPixmap(screen); xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); int i; @@ -368,6 +381,7 @@ ms_present_unflip(ScreenPtr screen, uint64_t event_id) return; event->event_id = event_id; + event->unflip = TRUE; if (ms_present_check_flip(NULL, screen->root, pixmap, TRUE) && ms_do_pageflip(screen, pixmap, event, -1, FALSE, @@ -399,6 +413,7 @@ ms_present_unflip(ScreenPtr screen, uint64_t event_id) } present_event_notify(event_id, 0, 0); + ms->drmmode.present_flipping = FALSE; } #endif -- 2.7.4