diff --git a/present/present_scmd.c b/present/present_scmd.c index e762e02328..c528d1319d 100644 --- a/present/present_scmd.c +++ b/present/present_scmd.c @@ -58,29 +58,6 @@ present_flip_pending_pixmap(ScreenPtr screen) return screen_priv->flip_pending->pixmap; } -static inline Bool -present_check_driver_flip(RRCrtcPtr crtc, - WindowPtr window, - PixmapPtr pixmap, - Bool sync_flip, - present_screen_priv_ptr screen_priv, - PresentFlipReason *reason) -{ - if (screen_priv->info->version >= 1 && screen_priv->info->check_flip2) { - if (!(*screen_priv->info->check_flip2) (crtc, window, pixmap, sync_flip, reason)) { - DebugPresent(("\td %08" PRIx32 " -> %08" PRIx32 "\n", window->drawable.id, pixmap ? pixmap->drawable.id : 0)); - return FALSE; - } - } else if (screen_priv->info->check_flip) { - if (!(*screen_priv->info->check_flip) (crtc, window, pixmap, sync_flip)) { - DebugPresent(("\td %08" PRIx32 " -> %08" PRIx32 "\n", window->drawable.id, pixmap ? pixmap->drawable.id : 0)); - return FALSE; - } - } - - return TRUE; -} - static Bool present_check_flip(RRCrtcPtr crtc, WindowPtr window, @@ -95,6 +72,7 @@ present_check_flip(RRCrtcPtr crtc, PixmapPtr window_pixmap; WindowPtr root = screen->root; present_screen_priv_ptr screen_priv = present_screen_priv(screen); + PresentFlipReason tmp_reason = PRESENT_FLIP_REASON_UNKNOWN; if (crtc) { screen_priv = present_screen_priv(crtc->pScreen); @@ -115,6 +93,27 @@ present_check_flip(RRCrtcPtr crtc, if (!screen_priv->info->flip) return FALSE; + /* Ask the driver for permission. Do this now to see if there's TearFree. */ + if (screen_priv->info->version >= 1 && screen_priv->info->check_flip2) { + if (!(*screen_priv->info->check_flip2) (crtc, window, pixmap, sync_flip, &tmp_reason)) { + DebugPresent(("\td %08" PRIx32 " -> %08" PRIx32 "\n", window->drawable.id, pixmap ? pixmap->drawable.id : 0)); + /* It's fine to return now unless the page flip failure reason is + * PRESENT_FLIP_REASON_BUFFER_FORMAT; we must only output that + * reason if all the other checks pass. + */ + if (!reason || tmp_reason != PRESENT_FLIP_REASON_BUFFER_FORMAT) { + if (reason) + *reason = tmp_reason; + return FALSE; + } + } + } else if (screen_priv->info->check_flip) { + if (!(*screen_priv->info->check_flip) (crtc, window, pixmap, sync_flip)) { + DebugPresent(("\td %08" PRIx32 " -> %08" PRIx32 "\n", window->drawable.id, pixmap ? pixmap->drawable.id : 0)); + return FALSE; + } + } + /* Make sure the window hasn't been redirected with Composite */ window_pixmap = screen->GetWindowPixmap(window); if (window_pixmap != screen->GetScreenPixmap(screen) && @@ -145,13 +144,9 @@ present_check_flip(RRCrtcPtr crtc, return FALSE; } - /** - * Ask the driver for permission - * - * We need to call the driver check flip after the full-screen window check. - * See: https://github.com/X11Libre/xserver/issues/1754 - */ - if (!present_check_driver_flip(crtc, window, pixmap, sync_flip, screen_priv, reason)) { + if (tmp_reason == PRESENT_FLIP_REASON_BUFFER_FORMAT) { + if (reason) + *reason = tmp_reason; return FALSE; }