From a6613a8fe3908433ee33a167f57a0fae4e785a22 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 22 May 2014 23:48:20 +0100 Subject: [PATCH] sna/dri2: Queue the flip immediately for the next frame If we compute that we want to flip on the next frame, queue it immediately rather than take a round trip through the kernel and risk missing the vblank. Signed-off-by: Chris Wilson --- src/sna/sna_dri2.c | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c index 9c655f97..d195856f 100644 --- a/src/sna/sna_dri2.c +++ b/src/sna/sna_dri2.c @@ -1947,7 +1947,6 @@ sna_dri2_schedule_flip(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc, struct sna *sna = to_sna_from_drawable(draw); struct sna_dri2_frame_event *info; int pipe = sna_crtc_to_pipe(crtc); - union drm_wait_vblank vbl; CARD64 current_msc; if (immediate_swap(sna, *target_msc, divisor, crtc, ¤t_msc)) { @@ -2057,12 +2056,6 @@ out: sna_dri2_reference_buffer(front); sna_dri2_reference_buffer(back); - VG_CLEAR(vbl); - - vbl.request.type = - DRM_VBLANK_ABSOLUTE | - DRM_VBLANK_EVENT; - /* * If divisor is zero, or current_msc is smaller than target_msc * we just need to make sure target_msc passes before initiating @@ -2081,15 +2074,31 @@ out: *target_msc += divisor; } - /* Account for 1 frame extra pageflip delay */ - vbl.reply.sequence = *target_msc - 1; - DBG(("%s: flip adjusted sequence = %d\n", - __FUNCTION__, vbl.request.sequence)); + if (*target_msc <= current_msc + 1) { + if (!sna_dri2_page_flip(sna, info)) { + sna_dri2_frame_event_info_free(sna, draw, info); + return false; + } + *target_msc = current_msc + 1; + } else { + union drm_wait_vblank vbl; - vbl.request.signal = (unsigned long)info; - if (sna_wait_vblank(sna, &vbl, pipe)) { - sna_dri2_frame_event_info_free(sna, draw, info); - return false; + VG_CLEAR(vbl); + + vbl.request.type = + DRM_VBLANK_ABSOLUTE | + DRM_VBLANK_EVENT; + + /* Account for 1 frame extra pageflip delay */ + vbl.reply.sequence = *target_msc - 1; + DBG(("%s: flip adjusted sequence = %d\n", + __FUNCTION__, vbl.request.sequence)); + + vbl.request.signal = (unsigned long)info; + if (sna_wait_vblank(sna, &vbl, pipe)) { + sna_dri2_frame_event_info_free(sna, draw, info); + return false; + } } info->queued = true;