xserver: Branch 'master' - 4 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Aug 25 10:30:34 UTC 2020


 present/present_execute.c |   23 ++++++++----------
 present/present_priv.h    |    6 ++--
 present/present_scmd.c    |   16 ++++++++-----
 present/present_vblank.c  |   18 +++++++-------
 present/present_wnmd.c    |   56 ++++++++++++++++++++++++++++------------------
 5 files changed, 67 insertions(+), 52 deletions(-)

New commits:
commit 1cccb486d48a5d2e7649836b993805bb65dc09e3
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Tue Jul 28 18:40:47 2020 +0200

    present/wnmd: Execute copies at target_msc-1 already
    
    It always takes one update cycle for the copy to become visible on the
    host windowing system, so waiting for the target MSC resulted in 1 cycle
    delay.
    
    We re-use the idle list for copies which were executed but need their
    completion event sent.
    
    Fixes black seams when resizing the "Builder" sub-window of
    
     GDK_BACKEND=x11 gtk4-demo
    
    on Xwayland (see
    https://gitlab.gnome.org/GNOME/mutter/-/issues/1290#note_873557).
    
    Unfortunately, this cannot completely fix the seams with apps which
    queue up multiple frames in advance, since there's always at least one
    queued frame corresponding to the old window size. But it should at
    least help a little in that case as well.
    
    v2:
    * Bug fix: Don't update exec_msc in present_wnmd_check_flip_window.
      (Roman Gilg)
    * Use exec_msc = target_msc - 1 instead of exec_msc--, and add a
      comment, for clarity.
    v3:
    * Drop exec_msc = target_msc again in present_wnmd_execute.
    * present_execute_copy should never set vblank->queued in
      present_wnmd_execute now, so replace that branch with an assertion.
      (Roman Gilg)
    
    Reviewed-by: Roman Gilg <subdiff at gmail.com>
    Tested-by: Roman Gilg <subdiff at gmail.com>

diff --git a/present/present_wnmd.c b/present/present_wnmd.c
index 55b2b6463..4ee2585c2 100644
--- a/present/present_wnmd.c
+++ b/present/present_wnmd.c
@@ -222,6 +222,14 @@ present_wnmd_event_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uin
             return;
         }
     }
+
+    /* Copies which were executed but need their completion event sent */
+    xorg_list_for_each_entry(vblank, &window_priv->idle_queue, event_queue) {
+        if (vblank->event_id == event_id) {
+            present_execute_post(vblank, ust, msc);
+            return;
+        }
+    }
 }
 
 void
@@ -369,8 +377,6 @@ present_wnmd_check_flip_window (WindowPtr window)
                                          vblank->sync_flip, vblank->valid, 0, 0, &reason)) {
             vblank->flip = FALSE;
             vblank->reason = reason;
-            if (vblank->sync_flip)
-                vblank->exec_msc = vblank->target_msc;
         }
     }
 }
@@ -470,6 +476,7 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
     vblank->queued = FALSE;
 
     if (vblank->pixmap && vblank->window) {
+        ScreenPtr screen = window->drawable.pScreen;
 
         if (vblank->flip) {
             RegionPtr damage;
@@ -495,7 +502,6 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
             // ask the driver
             if (present_wnmd_flip(vblank->window, vblank->crtc, vblank->event_id,
                                      vblank->target_msc, vblank->pixmap, vblank->sync_flip, damage)) {
-                ScreenPtr screen = window->drawable.pScreen;
                 WindowPtr toplvl_window = present_wnmd_toplvl_pixmap_window(vblank->window);
                 PixmapPtr old_pixmap = screen->GetWindowPixmap(window);
 
@@ -518,7 +524,6 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
               */
             window_priv->flip_pending = NULL;
             vblank->flip = FALSE;
-            vblank->exec_msc = vblank->target_msc;
         }
         DebugPresent(("\tc %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
                       vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id));
@@ -526,9 +531,12 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
         present_wnmd_cancel_flip(window);
 
         present_execute_copy(vblank, crtc_msc);
+        assert(!vblank->queued);
 
-        if (vblank->queued) {
-            xorg_list_add(&vblank->event_queue, &window_priv->exec_queue);
+        if (present_wnmd_queue_vblank(screen, window, vblank->crtc,
+                                      vblank->event_id, crtc_msc + 1)
+            == Success) {
+            xorg_list_add(&vblank->event_queue, &window_priv->idle_queue);
             xorg_list_append(&vblank->window_list, &window_priv->vblank);
 
             return;
@@ -651,8 +659,10 @@ present_wnmd_pixmap(WindowPtr window,
     if (!vblank)
         return BadAlloc;
 
-    if (vblank->flip && vblank->sync_flip)
-        vblank->exec_msc--;
+    /* WNMD presentations always complete (at least) one frame after they
+     * are executed
+     */
+    vblank->exec_msc = vblank->target_msc - 1;
 
     xorg_list_append(&vblank->event_queue, &window_priv->exec_queue);
     vblank->queued = TRUE;
commit d14ea667feccf085c7d66a7c63f380975e07af66
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Tue Jul 28 18:53:45 2020 +0200

    present/wnmd: Move up present_wnmd_queue_vblank
    
    Allowing it to be called from more functions than before. No functional
    change.
    
    Reviewed-by: Roman Gilg <subdiff at gmail.com>
    Tested-by: Roman Gilg <subdiff at gmail.com>

diff --git a/present/present_wnmd.c b/present/present_wnmd.c
index f97083f7b..55b2b6463 100644
--- a/present/present_wnmd.c
+++ b/present/present_wnmd.c
@@ -42,6 +42,17 @@
 static void
 present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc);
 
+static int
+present_wnmd_queue_vblank(ScreenPtr screen,
+                          WindowPtr window,
+                          RRCrtcPtr crtc,
+                          uint64_t event_id,
+                          uint64_t msc)
+{
+    present_screen_priv_ptr screen_priv = present_screen_priv(screen);
+    return (*screen_priv->wnmd_info->queue_vblank) (window, crtc, event_id, msc);
+}
+
 static void
 present_wnmd_create_event_id(present_window_priv_ptr window_priv, present_vblank_ptr vblank)
 {
@@ -527,17 +538,6 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
     present_execute_post(vblank, ust, crtc_msc);
 }
 
-static int
-present_wnmd_queue_vblank(ScreenPtr screen,
-                             WindowPtr window,
-                             RRCrtcPtr crtc,
-                             uint64_t event_id,
-                             uint64_t msc)
-{
-    present_screen_priv_ptr screen_priv = present_screen_priv(screen);
-    return (*screen_priv->wnmd_info->queue_vblank) (window, crtc, event_id, msc);
-}
-
 static void
 present_wnmd_update_window_crtc(WindowPtr window, RRCrtcPtr crtc, uint64_t new_msc)
 {
commit b0b3159abd8001fa3f6dfc44a288a95a62aa5cf6
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Wed Aug 12 17:38:33 2020 +0200

    present: Add present_vblank::exec_msc field
    
    For tracking the MSC when the present can be executed separately from
    the target MSC.
    
    Allows removing the requeue field instead, plus more later.
    
    v2:
    * Rename wait_msc → exec_msc (Roman Gilg)
    * Use exec_msc = target_msc instead of exec_msc++, for clarity.
    * Bug fix: Set exec_msc = target_msc also if present_flip returned
      false in present_execute.
    v3:
    * Set exec_msc = target_msc also if present_wnmd_flip returned
      false in present_wnmd_execute, for consistency.
    v4:
    * Specifically check for exec_msc == crtc_msc + 1 in
      present_execute_wait/copy, to avoid re-introducing
      https://bugs.freedesktop.org/show_bug.cgi?id=94596 .
    
    Reviewed-by: Roman Gilg <subdiff at gmail.com>
    Tested-by: Roman Gilg <subdiff at gmail.com>

diff --git a/present/present_execute.c b/present/present_execute.c
index 8d1ef4a8c..58066db86 100644
--- a/present/present_execute.c
+++ b/present/present_execute.c
@@ -48,16 +48,13 @@ present_execute_wait(present_vblank_ptr vblank, uint64_t crtc_msc)
     ScreenPtr                   screen = window->drawable.pScreen;
     present_screen_priv_ptr screen_priv = present_screen_priv(screen);
 
-    if (vblank->requeue) {
-        vblank->requeue = FALSE;
-        if (msc_is_after(vblank->target_msc, crtc_msc) &&
-            Success == screen_priv->queue_vblank(screen,
-                                                 window,
-                                                 vblank->crtc,
-                                                 vblank->event_id,
-                                                 vblank->target_msc))
-            return TRUE;
-    }
+    /* We may have to requeue for the next MSC if check_flip_window prevented
+     * using a flip.
+     */
+    if (vblank->exec_msc == crtc_msc + 1 &&
+        screen_priv->queue_vblank(screen, window, vblank->crtc, vblank->event_id,
+                                  vblank->exec_msc) == Success)
+        return TRUE;
 
     if (vblank->wait_fence) {
         if (!present_fence_check_triggered(vblank->wait_fence)) {
@@ -75,13 +72,13 @@ present_execute_copy(present_vblank_ptr vblank, uint64_t crtc_msc)
     ScreenPtr                   screen = window->drawable.pScreen;
     present_screen_priv_ptr screen_priv = present_screen_priv(screen);
 
-    /* If present_flip failed, we may have to requeue for the target MSC */
-    if (vblank->target_msc == crtc_msc + 1 &&
+    /* If present_flip failed, we may have to requeue for the next MSC */
+    if (vblank->exec_msc == crtc_msc + 1 &&
         Success == screen_priv->queue_vblank(screen,
                                              window,
                                              vblank->crtc,
                                              vblank->event_id,
-                                             vblank->target_msc)) {
+                                             vblank->exec_msc)) {
         vblank->queued = TRUE;
         return;
     }
diff --git a/present/present_priv.h b/present/present_priv.h
index 7f9d82d8d..bce67b21e 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -70,14 +70,14 @@ struct present_vblank {
     int16_t             y_off;
     CARD16              kind;
     uint64_t            event_id;
-    uint64_t            target_msc;
+    uint64_t            target_msc;     /* target MSC when present should complete */
+    uint64_t            exec_msc;       /* MSC at which present can be executed */
     uint64_t            msc_offset;
     present_fence_ptr   idle_fence;
     present_fence_ptr   wait_fence;
     present_notify_ptr  notifies;
     int                 num_notifies;
     Bool                queued;         /* on present_exec_queue */
-    Bool                requeue;        /* on queue, but target_msc has changed */
     Bool                flip;           /* planning on using flip */
     Bool                flip_ready;     /* wants to flip, but waiting for previous flip or unflip */
     Bool                flip_idler;     /* driver explicitly permitted idling */
diff --git a/present/present_scmd.c b/present/present_scmd.c
index a5a36f2a2..c7184e793 100644
--- a/present/present_scmd.c
+++ b/present/present_scmd.c
@@ -335,8 +335,8 @@ present_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
     ScreenPtr                   screen = vblank->screen;
     present_screen_priv_ptr     screen_priv = present_screen_priv(screen);
 
-    DebugPresent(("\tn %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
-                  vblank->event_id, vblank, vblank->target_msc,
+    DebugPresent(("\tn %" PRIu64 " %p %" PRIu64 " %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
+                  vblank->event_id, vblank, vblank->exec_msc, vblank->target_msc,
                   vblank->pixmap ? vblank->pixmap->drawable.id : 0,
                   vblank->window ? vblank->window->drawable.id : 0));
 
@@ -456,7 +456,7 @@ present_check_flip_window (WindowPtr window)
             vblank->flip = FALSE;
             vblank->reason = reason;
             if (vblank->sync_flip)
-                vblank->requeue = TRUE;
+                vblank->exec_msc = vblank->target_msc;
         }
     }
 }
@@ -582,6 +582,7 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
               */
             screen_priv->flip_pending = NULL;
             vblank->flip = FALSE;
+            vblank->exec_msc = vblank->target_msc;
         }
         DebugPresent(("\tc %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
                       vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id));
@@ -739,12 +740,12 @@ present_scmd_pixmap(WindowPtr window,
         return BadAlloc;
 
     if (vblank->flip && vblank->sync_flip)
-        target_msc--;
+        vblank->exec_msc--;
 
     xorg_list_append(&vblank->event_queue, &present_exec_queue);
     vblank->queued = TRUE;
-    if (msc_is_after(target_msc, crtc_msc)) {
-        ret = present_queue_vblank(screen, window, target_crtc, vblank->event_id, target_msc);
+    if (msc_is_after(vblank->exec_msc, crtc_msc)) {
+        ret = present_queue_vblank(screen, window, target_crtc, vblank->event_id, vblank->exec_msc);
         if (ret == Success)
             return Success;
 
diff --git a/present/present_vblank.c b/present/present_vblank.c
index a4b70c0d9..af14fe134 100644
--- a/present/present_vblank.c
+++ b/present/present_vblank.c
@@ -101,6 +101,7 @@ present_vblank_create(WindowPtr window,
     vblank->x_off = x_off;
     vblank->y_off = y_off;
     vblank->target_msc = target_msc;
+    vblank->exec_msc = target_msc;
     vblank->crtc = target_crtc;
     vblank->msc_offset = window_priv->msc_offset;
     vblank->notifies = notifies;
@@ -152,8 +153,8 @@ no_mem:
 void
 present_vblank_scrap(present_vblank_ptr vblank)
 {
-    DebugPresent(("\tx %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 " (crtc %p)\n",
-                  vblank->event_id, vblank, vblank->target_msc,
+    DebugPresent(("\tx %" PRIu64 " %p %" PRIu64 " %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 " (crtc %p)\n",
+                  vblank->event_id, vblank, vblank->exec_msc, vblank->target_msc,
                   vblank->pixmap->drawable.id, vblank->window->drawable.id,
                   vblank->crtc));
 
@@ -174,8 +175,8 @@ present_vblank_destroy(present_vblank_ptr vblank)
     /* Also make sure vblank is removed from event queue (wnmd) */
     xorg_list_del(&vblank->event_queue);
 
-    DebugPresent(("\td %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
-                  vblank->event_id, vblank, vblank->target_msc,
+    DebugPresent(("\td %" PRIu64 " %p %" PRIu64 " %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
+                  vblank->event_id, vblank, vblank->exec_msc, vblank->target_msc,
                   vblank->pixmap ? vblank->pixmap->drawable.id : 0,
                   vblank->window ? vblank->window->drawable.id : 0));
 
diff --git a/present/present_wnmd.c b/present/present_wnmd.c
index 922b877e7..f97083f7b 100644
--- a/present/present_wnmd.c
+++ b/present/present_wnmd.c
@@ -158,8 +158,8 @@ present_wnmd_flip_notify_vblank(present_vblank_ptr vblank, uint64_t ust, uint64_
     WindowPtr                   window = vblank->window;
     present_window_priv_ptr     window_priv = present_window_priv(window);
 
-    DebugPresent(("\tn %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
-                  vblank->event_id, vblank, vblank->target_msc,
+    DebugPresent(("\tn %" PRIu64 " %p %" PRIu64 " %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
+                  vblank->event_id, vblank, vblank->exec_msc, vblank->target_msc,
                   vblank->pixmap ? vblank->pixmap->drawable.id : 0,
                   vblank->window ? vblank->window->drawable.id : 0));
 
@@ -359,7 +359,7 @@ present_wnmd_check_flip_window (WindowPtr window)
             vblank->flip = FALSE;
             vblank->reason = reason;
             if (vblank->sync_flip)
-                vblank->requeue = TRUE;
+                vblank->exec_msc = vblank->target_msc;
         }
     }
 }
@@ -507,6 +507,7 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
               */
             window_priv->flip_pending = NULL;
             vblank->flip = FALSE;
+            vblank->exec_msc = vblank->target_msc;
         }
         DebugPresent(("\tc %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
                       vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id));
@@ -651,12 +652,12 @@ present_wnmd_pixmap(WindowPtr window,
         return BadAlloc;
 
     if (vblank->flip && vblank->sync_flip)
-        target_msc--;
+        vblank->exec_msc--;
 
     xorg_list_append(&vblank->event_queue, &window_priv->exec_queue);
     vblank->queued = TRUE;
-    if (crtc_msc < target_msc) {
-        if (present_wnmd_queue_vblank(screen, window, target_crtc, vblank->event_id, target_msc) == Success) {
+    if (crtc_msc < vblank->exec_msc) {
+        if (present_wnmd_queue_vblank(screen, window, target_crtc, vblank->event_id, vblank->exec_msc) == Success) {
             return Success;
         }
         DebugPresent(("present_queue_vblank failed\n"));
commit 4c92dea952f7fed19857904f0f552900257ef4b9
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Tue Jul 28 18:48:42 2020 +0200

    present: Move flip target_msc adjustment out of present_vblank_create
    
    Preparation for different handling between SCMD & WNMD. No functional
    change intended.
    
    Reviewed-by: Roman Gilg <subdiff at gmail.com>
    Tested-by: Roman Gilg <subdiff at gmail.com>

diff --git a/present/present_priv.h b/present/present_priv.h
index dabf4c9d0..7f9d82d8d 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -469,7 +469,7 @@ present_vblank_create(WindowPtr window,
                       const uint32_t *capabilities,
                       present_notify_ptr notifies,
                       int num_notifies,
-                      uint64_t *target_msc,
+                      uint64_t target_msc,
                       uint64_t crtc_msc);
 
 void
diff --git a/present/present_scmd.c b/present/present_scmd.c
index fa800e99c..a5a36f2a2 100644
--- a/present/present_scmd.c
+++ b/present/present_scmd.c
@@ -732,12 +732,15 @@ present_scmd_pixmap(WindowPtr window,
                                    screen_priv->info ? &screen_priv->info->capabilities : NULL,
                                    notifies,
                                    num_notifies,
-                                   &target_msc,
+                                   target_msc,
                                    crtc_msc);
 
     if (!vblank)
         return BadAlloc;
 
+    if (vblank->flip && vblank->sync_flip)
+        target_msc--;
+
     xorg_list_append(&vblank->event_queue, &present_exec_queue);
     vblank->queued = TRUE;
     if (msc_is_after(target_msc, crtc_msc)) {
diff --git a/present/present_vblank.c b/present/present_vblank.c
index 2c124f4bb..a4b70c0d9 100644
--- a/present/present_vblank.c
+++ b/present/present_vblank.c
@@ -57,7 +57,7 @@ present_vblank_create(WindowPtr window,
                       const uint32_t *capabilities,
                       present_notify_ptr notifies,
                       int num_notifies,
-                      uint64_t *target_msc,
+                      uint64_t target_msc,
                       uint64_t crtc_msc)
 {
     ScreenPtr                   screen = window->drawable.pScreen;
@@ -100,7 +100,7 @@ present_vblank_create(WindowPtr window,
 
     vblank->x_off = x_off;
     vblank->y_off = y_off;
-    vblank->target_msc = *target_msc;
+    vblank->target_msc = target_msc;
     vblank->crtc = target_crtc;
     vblank->msc_offset = window_priv->msc_offset;
     vblank->notifies = notifies;
@@ -111,12 +111,11 @@ present_vblank_create(WindowPtr window,
     if (pixmap != NULL &&
         !(options & PresentOptionCopy) &&
         capabilities) {
-        if (msc_is_after(*target_msc, crtc_msc) &&
+        if (msc_is_after(target_msc, crtc_msc) &&
             screen_priv->check_flip (target_crtc, window, pixmap, TRUE, valid, x_off, y_off, &reason))
         {
             vblank->flip = TRUE;
             vblank->sync_flip = TRUE;
-            *target_msc = *target_msc - 1;
         } else if ((*capabilities & PresentCapabilityAsync) &&
             screen_priv->check_flip (target_crtc, window, pixmap, FALSE, valid, x_off, y_off, &reason))
         {
@@ -139,7 +138,7 @@ present_vblank_create(WindowPtr window,
 
     if (pixmap)
         DebugPresent(("q %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 " (crtc %p) flip %d vsync %d serial %d\n",
-                      vblank->event_id, vblank, *target_msc,
+                      vblank->event_id, vblank, target_msc,
                       vblank->pixmap->drawable.id, vblank->window->drawable.id,
                       target_crtc, vblank->flip, vblank->sync_flip, vblank->serial));
     return vblank;
diff --git a/present/present_wnmd.c b/present/present_wnmd.c
index b0d79b80f..922b877e7 100644
--- a/present/present_wnmd.c
+++ b/present/present_wnmd.c
@@ -645,11 +645,14 @@ present_wnmd_pixmap(WindowPtr window,
                                    &screen_priv->wnmd_info->capabilities,
                                    notifies,
                                    num_notifies,
-                                   &target_msc,
+                                   target_msc,
                                    crtc_msc);
     if (!vblank)
         return BadAlloc;
 
+    if (vblank->flip && vblank->sync_flip)
+        target_msc--;
+
     xorg_list_append(&vblank->event_queue, &window_priv->exec_queue);
     vblank->queued = TRUE;
     if (crtc_msc < target_msc) {


More information about the xorg-commit mailing list