When the display driver supports async flipping this mode of operation is always used. This means that, when the swap interval is none 0, the present extension relies on vblank events to get synchronised flips. However, by the time present gets the event, requests a flip and the GPU has finished we might have missed the vblank period. This results in tearing.
Fix this by always doing synced flips unless the client uses the PresentOptionAsync flag when presenting a pixmap. Signed-off-by: Frank Binns <[email protected]> --- present/present.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/present/present.c b/present/present.c index 32160b9..ec9f457 100644 --- a/present/present.c +++ b/present/present.c @@ -693,7 +693,7 @@ present_pixmap(WindowPtr window, } } else { target_msc = crtc_msc; - if (!(options & PresentOptionAsync)) + if (!(options & PresentOptionAsync) || !screen_priv->info || !(screen_priv->info->capabilities & PresentCapabilityAsync)) target_msc++; } } @@ -768,7 +768,7 @@ present_pixmap(WindowPtr window, vblank->notifies = notifies; vblank->num_notifies = num_notifies; - if (!screen_priv->info || !(screen_priv->info->capabilities & PresentCapabilityAsync)) + if (!(options & PresentOptionAsync) || !screen_priv->info || !(screen_priv->info->capabilities & PresentCapabilityAsync)) vblank->sync_flip = TRUE; if (pixmap && present_check_flip (target_crtc, window, pixmap, vblank->sync_flip, valid, x_off, y_off)) { @@ -797,7 +797,7 @@ present_pixmap(WindowPtr window, xorg_list_add(&vblank->event_queue, &present_exec_queue); vblank->queued = TRUE; - if (target_msc >= crtc_msc) { + if (target_msc > crtc_msc) { ret = present_queue_vblank(screen, target_crtc, vblank->event_id, target_msc); if (ret != Success) { xorg_list_del(&vblank->event_queue); -- 1.8.5.4.gfdaaaa2 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
