diff options
Diffstat (limited to 'hw/xfree86/drivers/modesetting/dri2.c')
-rw-r--r-- | hw/xfree86/drivers/modesetting/dri2.c | 74 |
1 files changed, 53 insertions, 21 deletions
diff --git a/hw/xfree86/drivers/modesetting/dri2.c b/hw/xfree86/drivers/modesetting/dri2.c index 8f44899b3..8944ef136 100644 --- a/hw/xfree86/drivers/modesetting/dri2.c +++ b/hw/xfree86/drivers/modesetting/dri2.c @@ -695,16 +695,19 @@ ms_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, CARD64 target_msc, { ScreenPtr screen = draw->pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + modesettingPtr ms = modesettingPTR(scrn); ms_dri2_frame_event_ptr wait_info; + drmVBlank vbl; int ret; xf86CrtcPtr crtc = ms_dri2_crtc_covering_drawable(draw); + drmmode_crtc_private_ptr drmmode_crtc; CARD64 current_msc, current_ust, request_msc; uint32_t seq; - uint64_t queued_msc; /* Drawable not visible, return immediately */ if (!crtc) goto out_complete; + drmmode_crtc = crtc->driver_private; wait_info = calloc(1, sizeof(*wait_info)); if (!wait_info) @@ -744,8 +747,13 @@ ms_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, CARD64 target_msc, if (current_msc >= target_msc) target_msc = current_msc; + vbl.request.type = (DRM_VBLANK_ABSOLUTE | + DRM_VBLANK_EVENT | + drmmode_crtc->vblank_pipe); + vbl.request.sequence = ms_crtc_msc_to_kernel_msc(crtc, target_msc); + vbl.request.signal = (unsigned long)seq; - ret = ms_queue_vblank(crtc, MS_QUEUE_ABSOLUTE, target_msc, &queued_msc, seq); + ret = drmWaitVBlank(ms->fd, &vbl); if (ret) { static int limit = 5; if (limit) { @@ -758,7 +766,7 @@ ms_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, CARD64 target_msc, goto out_free; } - wait_info->frame = queued_msc; + wait_info->frame = ms_kernel_msc_to_crtc_msc(crtc, vbl.reply.sequence); DRI2BlockClient(client, draw); return TRUE; } @@ -767,6 +775,9 @@ ms_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, CARD64 target_msc, * If we get here, target_msc has already passed or we don't have one, * so we queue an event that will satisfy the divisor/remainder equation. */ + vbl.request.type = + DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT | drmmode_crtc->vblank_pipe; + request_msc = current_msc - (current_msc % divisor) + remainder; /* @@ -784,7 +795,11 @@ ms_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, CARD64 target_msc, if (!seq) goto out_free; - if (!ms_queue_vblank(crtc, MS_QUEUE_ABSOLUTE, request_msc, &queued_msc, seq)) { + vbl.request.sequence = ms_crtc_msc_to_kernel_msc(crtc, request_msc); + vbl.request.signal = (unsigned long)seq; + + ret = drmWaitVBlank(ms->fd, &vbl); + if (ret) { static int limit = 5; if (limit) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, @@ -796,8 +811,7 @@ ms_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, CARD64 target_msc, goto out_free; } - wait_info->frame = queued_msc; - + wait_info->frame = ms_kernel_msc_to_crtc_msc(crtc, vbl.reply.sequence); DRI2BlockClient(client, draw); return TRUE; @@ -825,18 +839,20 @@ ms_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, { ScreenPtr screen = draw->pScreen; ScrnInfoPtr scrn = xf86ScreenToScrn(screen); + modesettingPtr ms = modesettingPTR(scrn); + drmVBlank vbl; int ret, flip = 0; xf86CrtcPtr crtc = ms_dri2_crtc_covering_drawable(draw); + drmmode_crtc_private_ptr drmmode_crtc; ms_dri2_frame_event_ptr frame_info = NULL; uint64_t current_msc, current_ust; uint64_t request_msc; uint32_t seq; - ms_queue_flag ms_flag = MS_QUEUE_ABSOLUTE; - uint64_t queued_msc; /* Drawable not displayed... just complete the swap */ if (!crtc) goto blit_fallback; + drmmode_crtc = crtc->driver_private; frame_info = calloc(1, sizeof(*frame_info)); if (!frame_info) @@ -862,8 +878,6 @@ ms_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, ms_dri2_reference_buffer(back); ret = ms_get_crtc_ust_msc(crtc, ¤t_ust, ¤t_msc); - if (ret != Success) - goto blit_fallback; /* Flips need to be submitted one frame before */ if (can_flip(scrn, draw, front, back)) { @@ -878,19 +892,22 @@ ms_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, if (*target_msc > 0) *target_msc -= flip; - /* If non-pageflipping, but blitting/exchanging, we need to use - * DRM_VBLANK_NEXTONMISS to avoid unreliable timestamping later - * on. - */ - if (flip == 0) - ms_flag |= MS_QUEUE_NEXT_ON_MISS; - /* * If divisor is zero, or current_msc is smaller than target_msc * we just need to make sure target_msc passes before initiating * the swap. */ if (divisor == 0 || current_msc < *target_msc) { + vbl.request.type = (DRM_VBLANK_ABSOLUTE | + DRM_VBLANK_EVENT | + drmmode_crtc->vblank_pipe); + + /* If non-pageflipping, but blitting/exchanging, we need to use + * DRM_VBLANK_NEXTONMISS to avoid unreliable timestamping later + * on. + */ + if (flip == 0) + vbl.request.type |= DRM_VBLANK_NEXTONMISS; /* If target_msc already reached or passed, set it to * current_msc to ensure we return a reasonable value back @@ -905,14 +922,19 @@ ms_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, if (!seq) goto blit_fallback; - if (!ms_queue_vblank(crtc, ms_flag, *target_msc, &queued_msc, seq)) { + vbl.request.sequence = ms_crtc_msc_to_kernel_msc(crtc, *target_msc); + vbl.request.signal = (unsigned long)seq; + + ret = drmWaitVBlank(ms->fd, &vbl); + if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "divisor 0 get vblank counter failed: %s\n", strerror(errno)); goto blit_fallback; } - *target_msc = queued_msc + flip; + *target_msc = ms_kernel_msc_to_crtc_msc(crtc, + vbl.reply.sequence + flip); frame_info->frame = *target_msc; return TRUE; @@ -923,6 +945,11 @@ ms_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, * and we need to queue an event that will satisfy the divisor/remainder * equation. */ + vbl.request.type = (DRM_VBLANK_ABSOLUTE | + DRM_VBLANK_EVENT | + drmmode_crtc->vblank_pipe); + if (flip == 0) + vbl.request.type |= DRM_VBLANK_NEXTONMISS; request_msc = current_msc - (current_msc % divisor) + remainder; @@ -939,6 +966,7 @@ ms_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, if (request_msc <= current_msc) request_msc += divisor; + seq = ms_drm_queue_alloc(crtc, frame_info, ms_dri2_frame_event_handler, ms_dri2_frame_event_abort); @@ -946,7 +974,11 @@ ms_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, goto blit_fallback; /* Account for 1 frame extra pageflip delay if flip > 0 */ - if (!ms_queue_vblank(crtc, ms_flag, request_msc - flip, &queued_msc, seq)) { + vbl.request.sequence = ms_crtc_msc_to_kernel_msc(crtc, request_msc) - flip; + vbl.request.signal = (unsigned long)seq; + + ret = drmWaitVBlank(ms->fd, &vbl); + if (ret) { xf86DrvMsg(scrn->scrnIndex, X_WARNING, "final get vblank counter failed: %s\n", strerror(errno)); @@ -954,7 +986,7 @@ ms_dri2_schedule_swap(ClientPtr client, DrawablePtr draw, } /* Adjust returned value for 1 fame pageflip offset of flip > 0 */ - *target_msc = queued_msc + flip; + *target_msc = ms_kernel_msc_to_crtc_msc(crtc, vbl.reply.sequence + flip); frame_info->frame = *target_msc; return TRUE; |