xserver: Branch 'master' - 35 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jul 9 15:22:29 UTC 2021


 hw/xwayland/xwayland-present.c |  687 +++++++++++++++++++++++++++++++---------
 hw/xwayland/xwayland-present.h |   17 
 present/Makefile.am            |    3 
 present/meson.build            |    1 
 present/present.h              |   37 --
 present/present_priv.h         |   49 +-
 present/present_scmd.c         |   38 +-
 present/present_screen.c       |   78 ----
 present/present_vblank.c       |   86 +++--
 present/present_wnmd.c         |  702 -----------------------------------------
 10 files changed, 669 insertions(+), 1029 deletions(-)

New commits:
commit f6f2f203bcde47c334836191982d77bbbbbf533c
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Thu May 20 19:00:10 2021 +0200

    present: Drop flip_idler member from present_vblank_rec
    
    It's redundant with the pixmap member of struct xwl_present_event.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index f7b042c6d..c9cf8c2f5 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -279,8 +279,11 @@ xwl_present_flip_notify_vblank(present_vblank_ptr vblank, uint64_t ust, uint64_t
     xorg_list_del(&vblank->event_queue);
 
     if (xwl_present_window->flip_active) {
-        if (xwl_present_window->flip_active->flip_idler)
-            xwl_present_free_idle_vblank(xwl_present_window->flip_active);
+        struct xwl_present_event *event =
+            xwl_present_event_from_id((uintptr_t)xwl_present_window->flip_active);
+
+        if (!event->pixmap)
+            xwl_present_free_event(event);
         else
             /* Put the previous flip in the idle_queue and wait for further notice from
              * the Wayland compositor
@@ -358,21 +361,20 @@ xwl_present_buffer_release(void *data)
 {
     struct xwl_present_window *xwl_present_window;
     struct xwl_present_event *event = data;
+    present_vblank_ptr vblank;
 
     if (!event)
         return;
 
-    xwl_present_window = xwl_present_window_priv(event->vblank.window);
-    if (xwl_present_window->flip_active == &event->vblank ||
-        xwl_present_get_pending_flip(xwl_present_window) == &event->vblank) {
-        event->vblank.flip_idler = TRUE;
+    vblank = &event->vblank;
+    present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
 
+    xwl_present_window = xwl_present_window_priv(vblank->window);
+    if (xwl_present_window->flip_active == vblank ||
+        xwl_present_get_pending_flip(xwl_present_window) == vblank)
         xwl_present_release_pixmap(event);
-
-        return;
-    }
-
-    xwl_present_free_idle_vblank(&event->vblank);
+    else
+        xwl_present_free_event(event);
 }
 
 static void
diff --git a/present/present_priv.h b/present/present_priv.h
index e75ef6f9d..6ebd009a2 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -81,7 +81,6 @@ struct present_vblank {
     Bool                queued;         /* on present_exec_queue */
     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 */
     Bool                sync_flip;      /* do flip synchronous to vblank */
     Bool                abort_flip;     /* aborting this flip */
     PresentFlipReason   reason;         /* reason for which flip is not possible */
diff --git a/present/present_vblank.c b/present/present_vblank.c
index beca01982..a9f17d4b2 100644
--- a/present/present_vblank.c
+++ b/present/present_vblank.c
@@ -106,7 +106,6 @@ present_vblank_init(present_vblank_ptr vblank,
     vblank->notifies = notifies;
     vblank->num_notifies = num_notifies;
     vblank->has_suboptimal = (options & PresentOptionSuboptimal);
-    vblank->flip_idler = FALSE;
 
     if (pixmap != NULL &&
         !(options & PresentOptionCopy) &&
commit 212cfbcf68d279f2b3494e79fe8e3fbaabeba77c
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Wed May 12 15:25:51 2021 +0200

    xwayland/present: Use present_vblank_ptr instead of xwl_present_event*
    
    Where the latter isn't really needed.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 1beba69bd..f7b042c6d 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -380,21 +380,19 @@ xwl_present_msc_bump(struct xwl_present_window *xwl_present_window)
 {
     present_vblank_ptr flip_pending = xwl_present_get_pending_flip(xwl_present_window);
     uint64_t msc = ++xwl_present_window->msc;
-    struct xwl_present_event    *event, *tmp;
+    present_vblank_ptr vblank, tmp;
 
     xwl_present_window->ust = GetTimeInMicros();
 
     if (flip_pending && flip_pending->sync_flip)
         xwl_present_flip_notify_vblank(flip_pending, xwl_present_window->ust, msc);
 
-    xorg_list_for_each_entry_safe(event, tmp,
-                                  &xwl_present_window->wait_list,
-                                  vblank.event_queue) {
-        if (event->vblank.exec_msc <= msc) {
+    xorg_list_for_each_entry_safe(vblank, tmp, &xwl_present_window->wait_list, event_queue) {
+        if (vblank->exec_msc <= msc) {
             DebugPresent(("\te %" PRIu64 " ust %" PRIu64 " msc %" PRIu64 "\n",
-                          event->vblank.event_id, xwl_present_window->ust, msc));
+                          vblank->event_id, xwl_present_window->ust, msc));
 
-            xwl_present_execute(&event->vblank, xwl_present_window->ust, msc);
+            xwl_present_execute(vblank, xwl_present_window->ust, msc);
         }
     }
 }
@@ -435,14 +433,13 @@ xwl_present_sync_callback(void *data,
                struct wl_callback *callback,
                uint32_t time)
 {
-    struct xwl_present_event *event = data;
-    struct xwl_present_window *xwl_present_window =
-        xwl_present_window_get_priv(event->vblank.window);
+    present_vblank_ptr vblank = data;
+    struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(vblank->window);
 
     wl_callback_destroy(xwl_present_window->sync_callback);
     xwl_present_window->sync_callback = NULL;
 
-    xwl_present_flip_notify_vblank(&event->vblank, xwl_present_window->ust, xwl_present_window->msc);
+    xwl_present_flip_notify_vblank(vblank, xwl_present_window->ust, xwl_present_window->msc);
 }
 
 static const struct wl_callback_listener xwl_present_sync_listener = {
@@ -706,7 +703,7 @@ xwl_present_flip(WindowPtr present_window,
             wl_display_sync(xwl_window->xwl_screen->display);
         wl_callback_add_listener(xwl_present_window->sync_callback,
                                  &xwl_present_sync_listener,
-                                 event);
+                                 &event->vblank);
     }
 
     wl_display_flush(xwl_window->xwl_screen->display);
commit fe8c7855f3a85f156c792a3f18a175138407054b
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Wed May 12 12:51:32 2021 +0200

    xwayland/present: Fold xwl_present_release_event into _free_event
    
    The only difference was unhooking from the vblank.event_queue list,
    which is already done by xwl_present_flip_notify_vblank in
    xwl_present_msc_bump.

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index a5b0f9c46..1beba69bd 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -210,16 +210,10 @@ xwl_present_release_pixmap(struct xwl_present_event *event)
 }
 
 static void
-xwl_present_release_event(struct xwl_present_event *event)
+xwl_present_free_event(struct xwl_present_event *event)
 {
     xwl_present_release_pixmap(event);
     xorg_list_del(&event->vblank.event_queue);
-}
-
-static void
-xwl_present_free_event(struct xwl_present_event *event)
-{
-    xwl_present_release_event(event);
     present_vblank_destroy(&event->vblank);
 }
 
@@ -390,16 +384,9 @@ xwl_present_msc_bump(struct xwl_present_window *xwl_present_window)
 
     xwl_present_window->ust = GetTimeInMicros();
 
-    if (flip_pending && flip_pending->sync_flip) {
-        event = xwl_present_event_from_id((uintptr_t)flip_pending);
+    if (flip_pending && flip_pending->sync_flip)
         xwl_present_flip_notify_vblank(flip_pending, xwl_present_window->ust, msc);
 
-        if (!event->pixmap) {
-            /* If the buffer was already released, clean up now */
-            xwl_present_release_event(event);
-        }
-    }
-
     xorg_list_for_each_entry_safe(event, tmp,
                                   &xwl_present_window->wait_list,
                                   vblank.event_queue) {
commit 31d2ebca77fcabec81194ae6dcd724c699b1b513
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Mon May 10 18:33:43 2021 +0200

    xwayland/present: Drop target_msc member from struct xwl_present_event
    
    Use present_vblank_rec::exec_msc instead.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index e1e83dee9..a5b0f9c46 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -403,7 +403,7 @@ xwl_present_msc_bump(struct xwl_present_window *xwl_present_window)
     xorg_list_for_each_entry_safe(event, tmp,
                                   &xwl_present_window->wait_list,
                                   vblank.event_queue) {
-        if (event->target_msc <= msc) {
+        if (event->vblank.exec_msc <= msc) {
             DebugPresent(("\te %" PRIu64 " ust %" PRIu64 " msc %" PRIu64 "\n",
                           event->vblank.event_id, xwl_present_window->ust, msc));
 
@@ -495,7 +495,7 @@ xwl_present_queue_vblank(ScreenPtr screen,
     struct xwl_window *xwl_window = xwl_window_from_window(present_window);
     struct xwl_present_event *event = xwl_present_event_from_id(event_id);
 
-    event->target_msc = msc;
+    event->vblank.exec_msc = msc;
 
     xorg_list_del(&event->vblank.event_queue);
     xorg_list_append(&event->vblank.event_queue, &xwl_present_window->wait_list);
@@ -665,7 +665,6 @@ static Bool
 xwl_present_flip(WindowPtr present_window,
                  RRCrtcPtr crtc,
                  uint64_t event_id,
-                 uint64_t target_msc,
                  PixmapPtr pixmap,
                  Bool sync_flip,
                  RegionPtr damage)
@@ -690,7 +689,6 @@ xwl_present_flip(WindowPtr present_window,
     pixmap->refcnt++;
 
     event->pixmap = pixmap;
-    event->target_msc = target_msc;
 
     xwl_pixmap_set_buffer_release_cb(pixmap, xwl_present_buffer_release, event);
 
@@ -781,7 +779,7 @@ xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
                 damage = RegionDuplicate(&window->clipList);
 
             if (xwl_present_flip(vblank->window, vblank->crtc, vblank->event_id,
-                                 vblank->target_msc, vblank->pixmap, vblank->sync_flip, damage)) {
+                                 vblank->pixmap, vblank->sync_flip, damage)) {
                 WindowPtr toplvl_window = xwl_present_toplvl_pixmap_window(vblank->window);
                 PixmapPtr old_pixmap = screen->GetWindowPixmap(window);
 
diff --git a/hw/xwayland/xwayland-present.h b/hw/xwayland/xwayland-present.h
index da24abab5..d3eff73f4 100644
--- a/hw/xwayland/xwayland-present.h
+++ b/hw/xwayland/xwayland-present.h
@@ -53,7 +53,6 @@ struct xwl_present_window {
 
 struct xwl_present_event {
     present_vblank_rec vblank;
-    uint64_t target_msc;
 
     PixmapPtr pixmap;
 };
commit 495ec596640e26b6995c93eedc922d2702ad64ad
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Mon May 10 19:04:07 2021 +0200

    xwayland/present: Drop pending member from struct xwl_present_event
    
    We are handling two cases here: the active flip or the pending flip.
    
    For the pending flip (event->pending == TRUE), we called
    xwl_present_release_pixmap.
    
    For the active flip (event->pending == FALSE), we called
    xwl_present_release_event. However, xwl_present_flip_notify_vblank
    already unhooked event->vblank.event_queue. So this was effectively the
    same as calling xwl_present_release_pixmap.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 07f1ed5e9..e1e83dee9 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -373,10 +373,7 @@ xwl_present_buffer_release(void *data)
         xwl_present_get_pending_flip(xwl_present_window) == &event->vblank) {
         event->vblank.flip_idler = TRUE;
 
-        if (event->pending)
-            xwl_present_release_pixmap(event);
-        else
-            xwl_present_release_event(event);
+        xwl_present_release_pixmap(event);
 
         return;
     }
@@ -395,8 +392,6 @@ xwl_present_msc_bump(struct xwl_present_window *xwl_present_window)
 
     if (flip_pending && flip_pending->sync_flip) {
         event = xwl_present_event_from_id((uintptr_t)flip_pending);
-        event->pending = FALSE;
-
         xwl_present_flip_notify_vblank(flip_pending, xwl_present_window->ust, msc);
 
         if (!event->pixmap) {
@@ -460,8 +455,6 @@ xwl_present_sync_callback(void *data,
     wl_callback_destroy(xwl_present_window->sync_callback);
     xwl_present_window->sync_callback = NULL;
 
-    event->pending = FALSE;
-
     xwl_present_flip_notify_vblank(&event->vblank, xwl_present_window->ust, xwl_present_window->msc);
 }
 
@@ -698,7 +691,6 @@ xwl_present_flip(WindowPtr present_window,
 
     event->pixmap = pixmap;
     event->target_msc = target_msc;
-    event->pending = TRUE;
 
     xwl_pixmap_set_buffer_release_cb(pixmap, xwl_present_buffer_release, event);
 
diff --git a/hw/xwayland/xwayland-present.h b/hw/xwayland/xwayland-present.h
index 545fbb586..da24abab5 100644
--- a/hw/xwayland/xwayland-present.h
+++ b/hw/xwayland/xwayland-present.h
@@ -55,8 +55,6 @@ struct xwl_present_event {
     present_vblank_rec vblank;
     uint64_t target_msc;
 
-    Bool pending;
-
     PixmapPtr pixmap;
 };
 
commit f73340445fe1da9ae9bc3197eb2ef41589aa2a4e
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Fri May 7 18:16:23 2021 +0200

    xwayland/present: Drop list member from struct xwl_present_event
    
    Use present_vblank_rec::event_queue instead.
    
    The changes in xwl_present_execute shouldn't really be needed, since
    we should never hit queue_vblank in present_execute_wait. But let's be
    safe rather than sorry, plus this simplifies the code.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index d1eb0dfd3..07f1ed5e9 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -213,7 +213,7 @@ static void
 xwl_present_release_event(struct xwl_present_event *event)
 {
     xwl_present_release_pixmap(event);
-    xorg_list_del(&event->list);
+    xorg_list_del(&event->vblank.event_queue);
 }
 
 static void
@@ -407,10 +407,8 @@ xwl_present_msc_bump(struct xwl_present_window *xwl_present_window)
 
     xorg_list_for_each_entry_safe(event, tmp,
                                   &xwl_present_window->wait_list,
-                                  list) {
+                                  vblank.event_queue) {
         if (event->target_msc <= msc) {
-            xorg_list_del(&event->list);
-
             DebugPresent(("\te %" PRIu64 " ust %" PRIu64 " msc %" PRIu64 "\n",
                           event->vblank.event_id, xwl_present_window->ust, msc));
 
@@ -506,8 +504,8 @@ xwl_present_queue_vblank(ScreenPtr screen,
 
     event->target_msc = msc;
 
-    xorg_list_del(&event->list);
-    xorg_list_append(&event->list, &xwl_present_window->wait_list);
+    xorg_list_del(&event->vblank.event_queue);
+    xorg_list_append(&event->vblank.event_queue, &xwl_present_window->wait_list);
 
     /* If there's a pending frame callback, use that */
     if (xwl_window && xwl_window->frame_callback &&
@@ -702,8 +700,6 @@ xwl_present_flip(WindowPtr present_window,
     event->target_msc = target_msc;
     event->pending = TRUE;
 
-    xorg_list_init(&event->list);
-
     xwl_pixmap_set_buffer_release_cb(pixmap, xwl_present_buffer_release, event);
 
     /* We can flip directly to the main surface (full screen window without clips) */
@@ -757,19 +753,19 @@ xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
     struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
     present_vblank_ptr flip_pending = xwl_present_get_pending_flip(xwl_present_window);
 
+    xorg_list_del(&vblank->event_queue);
+
     if (present_execute_wait(vblank, crtc_msc))
         return;
 
     if (flip_pending && vblank->flip && vblank->pixmap && vblank->window) {
         DebugPresent(("\tr %" PRIu64 " %p (pending %p)\n",
                       vblank->event_id, vblank, flip_pending));
-        xorg_list_del(&vblank->event_queue);
         xorg_list_append(&vblank->event_queue, &xwl_present_window->flip_queue);
         vblank->flip_ready = TRUE;
         return;
     }
 
-    xorg_list_del(&vblank->event_queue);
     vblank->queued = FALSE;
 
     if (vblank->pixmap && vblank->window) {
@@ -926,8 +922,6 @@ xwl_present_pixmap(WindowPtr window,
 
     vblank->event_id = (uintptr_t)event;
 
-    xorg_list_init(&event->list);
-
     /* Xwayland presentations always complete (at least) one frame after they
      * are executed
      */
diff --git a/hw/xwayland/xwayland-present.h b/hw/xwayland/xwayland-present.h
index 9999e8cd8..545fbb586 100644
--- a/hw/xwayland/xwayland-present.h
+++ b/hw/xwayland/xwayland-present.h
@@ -58,8 +58,6 @@ struct xwl_present_event {
     Bool pending;
 
     PixmapPtr pixmap;
-
-    struct xorg_list list;
 };
 
 void xwl_present_frame_callback(struct xwl_present_window *xwl_present_window);
commit aac31d2758d4e84774b633ec108d18f0bad6ef64
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Fri May 7 17:58:27 2021 +0200

    xwayland/present: Drop exec_queue member from struct xwl_present_window
    
    Doesn't serve any purpose anymore.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index b199ac889..d1eb0dfd3 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -71,7 +71,6 @@ xwl_present_window_get_priv(WindowPtr window)
 
         xorg_list_init(&xwl_present_window->frame_callback_list);
         xorg_list_init(&xwl_present_window->wait_list);
-        xorg_list_init(&xwl_present_window->exec_queue);
         xorg_list_init(&xwl_present_window->flip_queue);
         xorg_list_init(&xwl_present_window->idle_queue);
 
@@ -835,8 +834,6 @@ xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
             /* Clear the pixmap field, so this will fall through to present_execute_post next time */
             dixDestroyPixmap(vblank->pixmap, vblank->pixmap->drawable.id);
             vblank->pixmap = NULL;
-
-            xorg_list_add(&vblank->event_queue, &xwl_present_window->exec_queue);
             return;
         }
     }
@@ -868,7 +865,6 @@ xwl_present_pixmap(WindowPtr window,
     int                         ret;
     present_vblank_ptr          vblank, tmp;
     ScreenPtr                   screen = window->drawable.pScreen;
-    struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
     present_window_priv_ptr     window_priv = present_get_window_priv(window, TRUE);
     present_screen_priv_ptr     screen_priv = present_screen_priv(screen);
     struct xwl_present_event *event;
@@ -937,7 +933,6 @@ xwl_present_pixmap(WindowPtr window,
      */
     vblank->exec_msc = vblank->target_msc - 1;
 
-    xorg_list_append(&vblank->event_queue, &xwl_present_window->exec_queue);
     vblank->queued = TRUE;
     if (crtc_msc < vblank->exec_msc) {
         if (xwl_present_queue_vblank(screen, window, target_crtc, vblank->event_id, vblank->exec_msc) == Success)
diff --git a/hw/xwayland/xwayland-present.h b/hw/xwayland/xwayland-present.h
index e3aaf933d..9999e8cd8 100644
--- a/hw/xwayland/xwayland-present.h
+++ b/hw/xwayland/xwayland-present.h
@@ -45,7 +45,6 @@ struct xwl_present_window {
     struct wl_callback *sync_callback;
 
     struct xorg_list wait_list;
-    struct xorg_list exec_queue;
     struct xorg_list flip_queue;
     struct xorg_list idle_queue;
 
commit f8c086b2145d1c9364e9b43ff4d796791d8af169
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Fri May 7 17:55:13 2021 +0200

    xwayland/present: Fold xwl_present_event_notify into its caller
    
    Can just call xwl_present_execute directly.
    
    This allows dropping the window member from struct xwl_present_window as
    well.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 8cd3a169a..b199ac889 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -66,7 +66,6 @@ xwl_present_window_get_priv(WindowPtr window)
         if (!xwl_present_window)
             return NULL;
 
-        xwl_present_window->window = window;
         xwl_present_window->msc = 1;
         xwl_present_window->ust = GetTimeInMicros();
 
@@ -306,34 +305,6 @@ xwl_present_flip_notify_vblank(present_vblank_ptr vblank, uint64_t ust, uint64_t
     xwl_present_flip_try_ready(xwl_present_window);
 }
 
-static void
-xwl_present_event_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uint64_t msc)
-{
-    struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
-    present_window_priv_ptr     window_priv = present_window_priv(window);
-    present_vblank_ptr          vblank;
-
-    if (!window_priv)
-        return;
-    if (!event_id)
-        return;
-
-    DebugPresent(("\te %" PRIu64 " ust %" PRIu64 " msc %" PRIu64 "\n", event_id, ust, msc));
-    xorg_list_for_each_entry(vblank, &xwl_present_window->exec_queue, event_queue) {
-        if (event_id == vblank->event_id) {
-            xwl_present_execute(vblank, ust, msc);
-            return;
-        }
-    }
-    xorg_list_for_each_entry(vblank, &xwl_present_window->flip_queue, event_queue) {
-        if (vblank->event_id == event_id) {
-            assert(vblank->queued);
-            xwl_present_execute(vblank, ust, msc);
-            return;
-        }
-    }
-}
-
 static void
 xwl_present_update_window_crtc(present_window_priv_ptr window_priv, RRCrtcPtr crtc, uint64_t new_msc)
 {
@@ -440,10 +411,11 @@ xwl_present_msc_bump(struct xwl_present_window *xwl_present_window)
                                   list) {
         if (event->target_msc <= msc) {
             xorg_list_del(&event->list);
-            xwl_present_event_notify(xwl_present_window->window,
-                                     (uintptr_t)event,
-                                     xwl_present_window->ust,
-                                     msc);
+
+            DebugPresent(("\te %" PRIu64 " ust %" PRIu64 " msc %" PRIu64 "\n",
+                          event->vblank.event_id, xwl_present_window->ust, msc));
+
+            xwl_present_execute(&event->vblank, xwl_present_window->ust, msc);
         }
     }
 }
diff --git a/hw/xwayland/xwayland-present.h b/hw/xwayland/xwayland-present.h
index 98c2d0dfb..e3aaf933d 100644
--- a/hw/xwayland/xwayland-present.h
+++ b/hw/xwayland/xwayland-present.h
@@ -35,7 +35,6 @@
 
 #ifdef GLAMOR_HAS_GBM
 struct xwl_present_window {
-    WindowPtr window;
     struct xorg_list frame_callback_list;
 
     uint64_t msc;
commit c30f3d08acb01a41df0fe7176f237137f3039480
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Fri May 7 17:49:07 2021 +0200

    xwayland/present: Use exec_queue for deferring completion events
    
    We clear the vblank->pixmap field, so next time xwl_present_execute
    falls through to present_execute_post.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 07d9d23bb..8cd3a169a 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -332,14 +332,6 @@ xwl_present_event_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uint
             return;
         }
     }
-
-    /* Copies which were executed but need their completion event sent */
-    xorg_list_for_each_entry(vblank, &xwl_present_window->idle_queue, event_queue) {
-        if (vblank->event_id == event_id) {
-            present_execute_post(vblank, ust, msc);
-            return;
-        }
-    }
 }
 
 static void
@@ -868,7 +860,11 @@ xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
         if (xwl_present_queue_vblank(screen, window, vblank->crtc,
                                      vblank->event_id, crtc_msc + 1)
             == Success) {
-            xorg_list_add(&vblank->event_queue, &xwl_present_window->idle_queue);
+            /* Clear the pixmap field, so this will fall through to present_execute_post next time */
+            dixDestroyPixmap(vblank->pixmap, vblank->pixmap->drawable.id);
+            vblank->pixmap = NULL;
+
+            xorg_list_add(&vblank->event_queue, &xwl_present_window->exec_queue);
             return;
         }
     }
commit 4503c8d9ea7df5bda470501e638a730d91d718c9
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Fri May 7 12:56:30 2021 +0200

    xwayland/present: Fold xwl_present_idle_notify into its caller
    
    Allows simplification by avoiding indirection.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 4aef3c5c8..07d9d23bb 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -342,33 +342,6 @@ xwl_present_event_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uint
     }
 }
 
-static void
-xwl_present_idle_notify(WindowPtr window, uint64_t event_id)
-{
-    struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
-    present_vblank_ptr          vblank;
-
-    if (xwl_present_window->flip_active && xwl_present_window->flip_active->event_id == event_id) {
-        /* Active flip is allowed to become idle directly when it becomes unactive again. */
-        xwl_present_window->flip_active->flip_idler = TRUE;
-        return;
-    }
-
-    xorg_list_for_each_entry(vblank, &xwl_present_window->idle_queue, event_queue) {
-        if (vblank->event_id == event_id) {
-            xwl_present_free_idle_vblank(vblank);
-            return;
-        }
-    }
-
-    xorg_list_for_each_entry(vblank, &xwl_present_window->flip_queue, event_queue) {
-        if (vblank->event_id == event_id) {
-            vblank->flip_idler = TRUE;
-            return;
-        }
-    }
-}
-
 static void
 xwl_present_update_window_crtc(present_window_priv_ptr window_priv, RRCrtcPtr crtc, uint64_t new_msc)
 {
@@ -427,18 +400,26 @@ xwl_present_cleanup(WindowPtr window)
 static void
 xwl_present_buffer_release(void *data)
 {
+    struct xwl_present_window *xwl_present_window;
     struct xwl_present_event *event = data;
 
     if (!event)
         return;
 
-    if (event->pending)
-        xwl_present_release_pixmap(event);
-    else
-        xwl_present_release_event(event);
+    xwl_present_window = xwl_present_window_priv(event->vblank.window);
+    if (xwl_present_window->flip_active == &event->vblank ||
+        xwl_present_get_pending_flip(xwl_present_window) == &event->vblank) {
+        event->vblank.flip_idler = TRUE;
+
+        if (event->pending)
+            xwl_present_release_pixmap(event);
+        else
+            xwl_present_release_event(event);
+
+        return;
+    }
 
-    /* event/vblank memory will be freed in xwl_present_free_idle_vblank */
-    xwl_present_idle_notify(event->vblank.window, (uintptr_t)event);
+    xwl_present_free_idle_vblank(&event->vblank);
 }
 
 static void
commit b2a06e0700fa48c1e77fc687e6af39a4bb7c2ceb
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Fri May 7 12:34:49 2021 +0200

    xwayland/present: Drop sync_flip member of struct xwl_present_window
    
    The same information can be determined from the flip queue.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 0e61e855e..4aef3c5c8 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -122,7 +122,9 @@ xwl_present_get_pending_flip(struct xwl_present_window *xwl_present_window)
 static inline Bool
 xwl_present_has_pending_events(struct xwl_present_window *xwl_present_window)
 {
-    return !!xwl_present_window->sync_flip ||
+    present_vblank_ptr flip_pending = xwl_present_get_pending_flip(xwl_present_window);
+
+    return (flip_pending && flip_pending->sync_flip) ||
            !xorg_list_is_empty(&xwl_present_window->wait_list);
 }
 
@@ -442,17 +444,17 @@ xwl_present_buffer_release(void *data)
 static void
 xwl_present_msc_bump(struct xwl_present_window *xwl_present_window)
 {
+    present_vblank_ptr flip_pending = xwl_present_get_pending_flip(xwl_present_window);
     uint64_t msc = ++xwl_present_window->msc;
     struct xwl_present_event    *event, *tmp;
 
     xwl_present_window->ust = GetTimeInMicros();
 
-    event = xwl_present_window->sync_flip;
-    xwl_present_window->sync_flip = NULL;
-    if (event) {
+    if (flip_pending && flip_pending->sync_flip) {
+        event = xwl_present_event_from_id((uintptr_t)flip_pending);
         event->pending = FALSE;
 
-        xwl_present_flip_notify_vblank(&event->vblank, xwl_present_window->ust, msc);
+        xwl_present_flip_notify_vblank(flip_pending, xwl_present_window->ust, msc);
 
         if (!event->pixmap) {
             /* If the buffer was already released, clean up now */
@@ -757,8 +759,6 @@ xwl_present_flip(WindowPtr present_window,
     event->pending = TRUE;
 
     xorg_list_init(&event->list);
-    if (sync_flip)
-        xwl_present_window->sync_flip = event;
 
     xwl_pixmap_set_buffer_release_cb(pixmap, xwl_present_buffer_release, event);
 
diff --git a/hw/xwayland/xwayland-present.h b/hw/xwayland/xwayland-present.h
index 8c6a14575..98c2d0dfb 100644
--- a/hw/xwayland/xwayland-present.h
+++ b/hw/xwayland/xwayland-present.h
@@ -35,7 +35,6 @@
 
 #ifdef GLAMOR_HAS_GBM
 struct xwl_present_window {
-    struct xwl_present_event *sync_flip;
     WindowPtr window;
     struct xorg_list frame_callback_list;
 
commit fc53e3c536b5a338c595b5724c7d0b4734e45871
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Thu May 6 18:42:46 2021 +0200

    xwaland/present: Drop flip_pending member of struct xwl_present_window
    
    Use the first element of the flip_queue list for the same purpose.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index c525a89ca..0e61e855e 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -102,6 +102,23 @@ xwl_present_timer_callback(OsTimerPtr timer,
                            CARD32 time,
                            void *arg);
 
+static present_vblank_ptr
+xwl_present_get_pending_flip(struct xwl_present_window *xwl_present_window)
+{
+    present_vblank_ptr flip_pending;
+
+    if (xorg_list_is_empty(&xwl_present_window->flip_queue))
+        return NULL;
+
+    flip_pending = xorg_list_first_entry(&xwl_present_window->flip_queue, present_vblank_rec,
+                                         event_queue);
+
+    if (flip_pending->queued)
+        return NULL;
+
+    return flip_pending;
+}
+
 static inline Bool
 xwl_present_has_pending_events(struct xwl_present_window *xwl_present_window)
 {
@@ -237,8 +254,6 @@ xwl_present_flips_stop(WindowPtr window)
     struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
     present_vblank_ptr vblank, tmp;
 
-    assert (!xwl_present_window->flip_pending);
-
     /* Change back to the fast refresh rate */
     xwl_present_reset_timer(xwl_present_window);
 
@@ -265,7 +280,7 @@ xwl_present_flip_notify_vblank(present_vblank_ptr vblank, uint64_t ust, uint64_t
                   vblank->pixmap ? vblank->pixmap->drawable.id : 0,
                   vblank->window ? vblank->window->drawable.id : 0));
 
-    assert (vblank == xwl_present_window->flip_pending);
+    assert (&vblank->event_queue == xwl_present_window->flip_queue.next);
 
     xorg_list_del(&vblank->event_queue);
 
@@ -280,7 +295,6 @@ xwl_present_flip_notify_vblank(present_vblank_ptr vblank, uint64_t ust, uint64_t
     }
 
     xwl_present_window->flip_active = vblank;
-    xwl_present_window->flip_pending = NULL;
 
     present_vblank_notify(vblank, PresentCompleteKindPixmap, PresentCompleteModeFlip, ust, crtc_msc);
 
@@ -677,13 +691,13 @@ xwl_present_check_flip_window (WindowPtr window)
     if (!xwl_present_window || !window_priv)
         return;
 
-    flip_pending = xwl_present_window->flip_pending;
+    flip_pending = xwl_present_get_pending_flip(xwl_present_window);
     flip_active = xwl_present_window->flip_active;
 
     if (flip_pending) {
         if (!xwl_present_check_flip(flip_pending->crtc, flip_pending->window, flip_pending->pixmap,
                                     flip_pending->sync_flip, flip_pending->valid, 0, 0, NULL))
-            xwl_present_window->flip_pending->abort_flip = TRUE;
+            flip_pending->abort_flip = TRUE;
     } else if (flip_active) {
         if (!xwl_present_check_flip(flip_active->crtc, flip_active->window, flip_active->pixmap,
                                     flip_active->sync_flip, flip_active->valid, 0, 0, NULL))
@@ -797,20 +811,18 @@ xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
 {
     WindowPtr               window = vblank->window;
     struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
+    present_vblank_ptr flip_pending = xwl_present_get_pending_flip(xwl_present_window);
 
     if (present_execute_wait(vblank, crtc_msc))
         return;
 
-    if (vblank->flip && vblank->pixmap && vblank->window) {
-        if (xwl_present_window->flip_pending) {
-            DebugPresent(("\tr %" PRIu64 " %p (pending %p)\n",
-                          vblank->event_id, vblank,
-                          xwl_present_window->flip_pending));
-            xorg_list_del(&vblank->event_queue);
-            xorg_list_append(&vblank->event_queue, &xwl_present_window->flip_queue);
-            vblank->flip_ready = TRUE;
-            return;
-        }
+    if (flip_pending && vblank->flip && vblank->pixmap && vblank->window) {
+        DebugPresent(("\tr %" PRIu64 " %p (pending %p)\n",
+                      vblank->event_id, vblank, flip_pending));
+        xorg_list_del(&vblank->event_queue);
+        xorg_list_append(&vblank->event_queue, &xwl_present_window->flip_queue);
+        vblank->flip_ready = TRUE;
+        return;
     }
 
     xorg_list_del(&vblank->event_queue);
@@ -826,10 +838,6 @@ xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
                           vblank->event_id, vblank, crtc_msc,
                           vblank->pixmap->drawable.id, vblank->window->drawable.id));
 
-            /* Prepare to flip by placing it in the flip queue
-             */
-            xorg_list_add(&vblank->event_queue, &xwl_present_window->flip_queue);
-
             /* Set update region as damaged */
             if (vblank->update) {
                 damage = RegionDuplicate(vblank->update);
@@ -840,9 +848,6 @@ xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
             } else
                 damage = RegionDuplicate(&window->clipList);
 
-            /* Try to flip - the vblank is now pending
-             */
-            xwl_present_window->flip_pending = vblank;
             if (xwl_present_flip(vblank->window, vblank->crtc, vblank->event_id,
                                  vblank->target_msc, vblank->pixmap, vblank->sync_flip, damage)) {
                 WindowPtr toplvl_window = xwl_present_toplvl_pixmap_window(vblank->window);
@@ -860,20 +865,19 @@ xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
                 /* Report damage */
                 DamageDamageRegion(&vblank->window->drawable, damage);
                 RegionDestroy(damage);
+
+                /* Put pending flip at the flip queue head */
+                xorg_list_add(&vblank->event_queue, &xwl_present_window->flip_queue);
                 return;
             }
 
-            xorg_list_del(&vblank->event_queue);
-            /* Flip failed. Clear the flip_pending field
-              */
-            xwl_present_window->flip_pending = NULL;
             vblank->flip = FALSE;
         }
         DebugPresent(("\tc %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
                       vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id));
 
-        if (xwl_present_window->flip_pending)
-            xwl_present_window->flip_pending->abort_flip = TRUE;
+        if (flip_pending)
+            flip_pending->abort_flip = TRUE;
         else if (xwl_present_window->flip_active)
             xwl_present_flips_stop(window);
 
diff --git a/hw/xwayland/xwayland-present.h b/hw/xwayland/xwayland-present.h
index af7ded2bb..8c6a14575 100644
--- a/hw/xwayland/xwayland-present.h
+++ b/hw/xwayland/xwayland-present.h
@@ -51,7 +51,6 @@ struct xwl_present_window {
     struct xorg_list flip_queue;
     struct xorg_list idle_queue;
 
-    present_vblank_ptr flip_pending;
     present_vblank_ptr flip_active;
 };
 
commit c592c66625d964e8ed1f3fcfc01a245e4c8a8015
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Fri May 7 12:21:44 2021 +0200

    xwayland/present: Fold xwl_present_flip_notify into its callers
    
    No need for them to be separate anymore.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index b41f11859..c525a89ca 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -326,22 +326,6 @@ xwl_present_event_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uint
     }
 }
 
-static void
-xwl_present_flip_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uint64_t msc)
-{
-    struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
-    present_vblank_ptr          vblank;
-
-    xorg_list_for_each_entry(vblank, &xwl_present_window->flip_queue, event_queue) {
-        if (vblank->event_id == event_id) {
-            assert(!vblank->queued);
-            assert(vblank->window);
-            xwl_present_flip_notify_vblank(vblank, ust, msc);
-            return;
-        }
-    }
-}
-
 static void
 xwl_present_idle_notify(WindowPtr window, uint64_t event_id)
 {
@@ -454,8 +438,7 @@ xwl_present_msc_bump(struct xwl_present_window *xwl_present_window)
     if (event) {
         event->pending = FALSE;
 
-        xwl_present_flip_notify(xwl_present_window->window, (uintptr_t)event,
-                                xwl_present_window->ust, msc);
+        xwl_present_flip_notify_vblank(&event->vblank, xwl_present_window->ust, msc);
 
         if (!event->pixmap) {
             /* If the buffer was already released, clean up now */
@@ -521,8 +504,7 @@ xwl_present_sync_callback(void *data,
 
     event->pending = FALSE;
 
-    xwl_present_flip_notify(xwl_present_window->window, (uintptr_t)event,
-                            xwl_present_window->ust, xwl_present_window->msc);
+    xwl_present_flip_notify_vblank(&event->vblank, xwl_present_window->ust, xwl_present_window->msc);
 }
 
 static const struct wl_callback_listener xwl_present_sync_listener = {
commit 42301760802ea1cbe3698797c2bfb3a91ee02430
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Fri Apr 23 12:59:55 2021 +0200

    xwayland/present: Embed present_vblank_rec in xwl_present_event
    
    This allows for various simplifications.
    
    Use the pointer to the struct memory as the event ID. In contrast to
    the SCMD code for Xorg (where pending DRM events cannot be cancelled),
    this is safe here, because we can destroy pending Wayland callbacks. So
    we can't get a callback with a stale pointer to freed memory.
    
    Remove xwl_present_window::release_list in favour of
    present_vblank_rec::window_list.
    
    Remove xwl_present_event::xwl_present_window in favour of
    present_vblank_rec::window.
    
    xwl_present_free_event is never called for a NULL pointer anymore, no
    need to check.
    
    v2:
    * Restore DestroyWindow wrapping order to make sure
      present_destroy_window doesn't call xwl_present_abort_vblank.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index c7566ab94..b41f11859 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -47,8 +47,6 @@
 #define TIMER_LEN_COPY      17  // ~60fps
 #define TIMER_LEN_FLIP    1000  // 1fps
 
-static uint64_t xwl_present_event_id;
-
 static DevPrivateKeyRec xwl_present_window_private_key;
 
 static struct xwl_present_window *
@@ -74,7 +72,6 @@ xwl_present_window_get_priv(WindowPtr window)
 
         xorg_list_init(&xwl_present_window->frame_callback_list);
         xorg_list_init(&xwl_present_window->wait_list);
-        xorg_list_init(&xwl_present_window->release_list);
         xorg_list_init(&xwl_present_window->exec_queue);
         xorg_list_init(&xwl_present_window->flip_queue);
         xorg_list_init(&xwl_present_window->idle_queue);
@@ -87,6 +84,12 @@ xwl_present_window_get_priv(WindowPtr window)
     return xwl_present_window;
 }
 
+static struct xwl_present_event *
+xwl_present_event_from_id(uint64_t event_id)
+{
+    return (struct xwl_present_event*)(uintptr_t)event_id;
+}
+
 static void
 xwl_present_free_timer(struct xwl_present_window *xwl_present_window)
 {
@@ -178,11 +181,36 @@ xwl_present_flip_try_ready(struct xwl_present_window *xwl_present_window)
     }
 }
 
+static void
+xwl_present_release_pixmap(struct xwl_present_event *event)
+{
+    if (!event->pixmap)
+        return;
+
+    xwl_pixmap_del_buffer_release_cb(event->pixmap);
+    dixDestroyPixmap(event->pixmap, event->pixmap->drawable.id);
+    event->pixmap = NULL;
+}
+
+static void
+xwl_present_release_event(struct xwl_present_event *event)
+{
+    xwl_present_release_pixmap(event);
+    xorg_list_del(&event->list);
+}
+
+static void
+xwl_present_free_event(struct xwl_present_event *event)
+{
+    xwl_present_release_event(event);
+    present_vblank_destroy(&event->vblank);
+}
+
 static void
 xwl_present_free_idle_vblank(present_vblank_ptr vblank)
 {
     present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
-    present_vblank_destroy(vblank);
+    xwl_present_free_event(xwl_present_event_from_id((uintptr_t)vblank));
 }
 
 static WindowPtr
@@ -341,33 +369,6 @@ xwl_present_idle_notify(WindowPtr window, uint64_t event_id)
     }
 }
 
-/*
- * Clean up any pending or current flips for this window
- */
-static void
-xwl_present_clear_window_flip(WindowPtr window)
-{
-    struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
-    present_vblank_ptr          vblank, tmp;
-
-    xorg_list_for_each_entry_safe(vblank, tmp, &xwl_present_window->flip_queue, event_queue) {
-        present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
-        present_vblank_destroy(vblank);
-    }
-
-    xorg_list_for_each_entry_safe(vblank, tmp, &xwl_present_window->idle_queue, event_queue) {
-        present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
-        present_vblank_destroy(vblank);
-    }
-
-    vblank = xwl_present_window->flip_active;
-    if (vblank) {
-        present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
-        present_vblank_destroy(vblank);
-    }
-    xwl_present_window->flip_active = NULL;
-}
-
 static void
 xwl_present_update_window_crtc(present_window_priv_ptr window_priv, RRCrtcPtr crtc, uint64_t new_msc)
 {
@@ -391,32 +392,11 @@ xwl_present_update_window_crtc(present_window_priv_ptr window_priv, RRCrtcPtr cr
 }
 
 
-static void
-xwl_present_release_pixmap(struct xwl_present_event *event)
-{
-    if (!event->pixmap)
-        return;
-
-    xwl_pixmap_del_buffer_release_cb(event->pixmap);
-    dixDestroyPixmap(event->pixmap, event->pixmap->drawable.id);
-    event->pixmap = NULL;
-}
-
-static void
-xwl_present_free_event(struct xwl_present_event *event)
-{
-    if (!event)
-        return;
-
-    xwl_present_release_pixmap(event);
-    xorg_list_del(&event->list);
-    free(event);
-}
-
 void
 xwl_present_cleanup(WindowPtr window)
 {
     struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
+    present_window_priv_ptr window_priv = present_window_priv(window);
     struct xwl_present_event *event, *tmp;
 
     if (!xwl_present_window)
@@ -430,12 +410,7 @@ xwl_present_cleanup(WindowPtr window)
     }
 
     /* Clear remaining events */
-    xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->wait_list, list)
-        xwl_present_free_event(event);
-
-    xwl_present_free_event(xwl_present_window->sync_flip);
-
-    xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->release_list, list)
+    xorg_list_for_each_entry_safe(event, tmp, &window_priv->vblank, vblank.window_list)
         xwl_present_free_event(event);
 
     /* Clear timer */
@@ -457,12 +432,13 @@ xwl_present_buffer_release(void *data)
     if (!event)
         return;
 
-    xwl_present_release_pixmap(event);
-
-    xwl_present_idle_notify(event->xwl_present_window->window, event->event_id);
+    if (event->pending)
+        xwl_present_release_pixmap(event);
+    else
+        xwl_present_release_event(event);
 
-    if (!event->pending)
-        xwl_present_free_event(event);
+    /* event/vblank memory will be freed in xwl_present_free_idle_vblank */
+    xwl_present_idle_notify(event->vblank.window, (uintptr_t)event);
 }
 
 static void
@@ -478,14 +454,12 @@ xwl_present_msc_bump(struct xwl_present_window *xwl_present_window)
     if (event) {
         event->pending = FALSE;
 
-        xwl_present_flip_notify(xwl_present_window->window, event->event_id,
+        xwl_present_flip_notify(xwl_present_window->window, (uintptr_t)event,
                                 xwl_present_window->ust, msc);
 
         if (!event->pixmap) {
             /* If the buffer was already released, clean up now */
-            xwl_present_free_event(event);
-        } else {
-            xorg_list_add(&event->list, &xwl_present_window->release_list);
+            xwl_present_release_event(event);
         }
     }
 
@@ -493,11 +467,11 @@ xwl_present_msc_bump(struct xwl_present_window *xwl_present_window)
                                   &xwl_present_window->wait_list,
                                   list) {
         if (event->target_msc <= msc) {
+            xorg_list_del(&event->list);
             xwl_present_event_notify(xwl_present_window->window,
-                                     event->event_id,
+                                     (uintptr_t)event,
                                      xwl_present_window->ust,
                                      msc);
-            xwl_present_free_event(event);
         }
     }
 }
@@ -539,18 +513,16 @@ xwl_present_sync_callback(void *data,
                uint32_t time)
 {
     struct xwl_present_event *event = data;
-    struct xwl_present_window *xwl_present_window = event->xwl_present_window;
+    struct xwl_present_window *xwl_present_window =
+        xwl_present_window_get_priv(event->vblank.window);
 
     wl_callback_destroy(xwl_present_window->sync_callback);
     xwl_present_window->sync_callback = NULL;
 
     event->pending = FALSE;
 
-    xwl_present_flip_notify(xwl_present_window->window, event->event_id,
+    xwl_present_flip_notify(xwl_present_window->window, (uintptr_t)event,
                             xwl_present_window->ust, xwl_present_window->msc);
-
-    if (!event->pixmap)
-        xwl_present_free_event(event);
 }
 
 static const struct wl_callback_listener xwl_present_sync_listener = {
@@ -588,17 +560,11 @@ xwl_present_queue_vblank(ScreenPtr screen,
 {
     struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window);
     struct xwl_window *xwl_window = xwl_window_from_window(present_window);
-    struct xwl_present_event *event;
-
-    event = malloc(sizeof *event);
-    if (!event)
-        return BadAlloc;
+    struct xwl_present_event *event = xwl_present_event_from_id(event_id);
 
-    event->event_id = event_id;
-    event->pixmap = NULL;
-    event->xwl_present_window = xwl_present_window;
     event->target_msc = msc;
 
+    xorg_list_del(&event->list);
     xorg_list_append(&event->list, &xwl_present_window->wait_list);
 
     /* If there's a pending frame callback, use that */
@@ -626,40 +592,16 @@ xwl_present_abort_vblank(ScreenPtr screen,
                          uint64_t event_id,
                          uint64_t msc)
 {
-    struct xwl_present_window *xwl_present_window = xwl_present_window_priv(present_window);
-    struct xwl_present_event *event, *tmp;
-    present_vblank_ptr vblank;
-
-    if (xwl_present_window) {
-        xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->wait_list, list) {
-            if (event->event_id == event_id) {
-                xwl_present_free_event(event);
-                break;
-            }
-        }
+    static Bool called;
 
-        xorg_list_for_each_entry(event, &xwl_present_window->release_list, list) {
-            if (event->event_id == event_id) {
-                xwl_present_free_event(event);
-                break;
-            }
-        }
-    }
+    if (called)
+        return;
 
-    xorg_list_for_each_entry(vblank, &xwl_present_window->exec_queue, event_queue) {
-        if (vblank->event_id == event_id) {
-            xorg_list_del(&vblank->event_queue);
-            vblank->queued = FALSE;
-            return;
-        }
-    }
-    xorg_list_for_each_entry(vblank, &xwl_present_window->flip_queue, event_queue) {
-        if (vblank->event_id == event_id) {
-            xorg_list_del(&vblank->event_queue);
-            vblank->queued = FALSE;
-            return;
-        }
-    }
+    /* xwl_present_cleanup should have cleaned up everything,
+     * present_free_window_vblank shouldn't need to call this.
+     */
+    ErrorF("Unexpected call to %s:\n", __func__);
+    xorg_backtrace();
 }
 
 static void
@@ -777,6 +719,15 @@ xwl_present_check_flip_window (WindowPtr window)
     }
 }
 
+/*
+ * Clean up any pending or current flips for this window
+ */
+static void
+xwl_present_clear_window_flip(WindowPtr window)
+{
+    /* xwl_present_cleanup cleaned up everything */
+}
+
 static Bool
 xwl_present_flip(WindowPtr present_window,
                  RRCrtcPtr crtc,
@@ -790,7 +741,7 @@ xwl_present_flip(WindowPtr present_window,
     struct xwl_present_window   *xwl_present_window = xwl_present_window_priv(present_window);
     BoxPtr                      damage_box;
     struct wl_buffer            *buffer;
-    struct xwl_present_event    *event;
+    struct xwl_present_event    *event = xwl_present_event_from_id(event_id);
 
     if (!xwl_window)
         return FALSE;
@@ -803,24 +754,15 @@ xwl_present_flip(WindowPtr present_window,
 
     damage_box = RegionExtents(damage);
 
-    event = malloc(sizeof *event);
-    if (!event)
-        return FALSE;
-
     pixmap->refcnt++;
 
-    event->event_id = event_id;
-    event->xwl_present_window = xwl_present_window;
     event->pixmap = pixmap;
     event->target_msc = target_msc;
     event->pending = TRUE;
 
-    if (sync_flip) {
-        xorg_list_init(&event->list);
+    xorg_list_init(&event->list);
+    if (sync_flip)
         xwl_present_window->sync_flip = event;
-    } else {
-        xorg_list_add(&event->list, &xwl_present_window->release_list);
-    }
 
     xwl_pixmap_set_buffer_release_cb(pixmap, xwl_present_buffer_release, event);
 
@@ -873,7 +815,6 @@ xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
 {
     WindowPtr               window = vblank->window;
     struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
-    present_window_priv_ptr window_priv = present_window_priv(window);
 
     if (present_execute_wait(vblank, crtc_msc))
         return;
@@ -891,7 +832,6 @@ xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
     }
 
     xorg_list_del(&vblank->event_queue);
-    xorg_list_del(&vblank->window_list);
     vblank->queued = FALSE;
 
     if (vblank->pixmap && vblank->window) {
@@ -962,8 +902,6 @@ xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
                                      vblank->event_id, crtc_msc + 1)
             == Success) {
             xorg_list_add(&vblank->event_queue, &xwl_present_window->idle_queue);
-            xorg_list_append(&vblank->window_list, &window_priv->vblank);
-
             return;
         }
     }
@@ -998,6 +936,7 @@ xwl_present_pixmap(WindowPtr window,
     struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
     present_window_priv_ptr     window_priv = present_get_window_priv(window, TRUE);
     present_screen_priv_ptr     screen_priv = present_screen_priv(screen);
+    struct xwl_present_event *event;
 
     if (!window_priv)
         return BadAlloc;
@@ -1042,26 +981,21 @@ xwl_present_pixmap(WindowPtr window,
         }
     }
 
-    vblank = present_vblank_create(window,
-                                   pixmap,
-                                   serial,
-                                   valid,
-                                   update,
-                                   x_off,
-                                   y_off,
-                                   target_crtc,
-                                   wait_fence,
-                                   idle_fence,
-                                   options,
-                                   XWL_PRESENT_CAPS,
-                                   notifies,
-                                   num_notifies,
-                                   target_msc,
-                                   crtc_msc);
-    if (!vblank)
+    event = calloc(1, sizeof(*event));
+    if (!event)
         return BadAlloc;
 
-    vblank->event_id = ++xwl_present_event_id;
+    vblank = &event->vblank;
+    if (!present_vblank_init(vblank, window, pixmap, serial, valid, update, x_off, y_off,
+                             target_crtc, wait_fence, idle_fence, options, XWL_PRESENT_CAPS,
+                             notifies, num_notifies, target_msc, crtc_msc)) {
+        present_vblank_destroy(vblank);
+        return BadAlloc;
+    }
+
+    vblank->event_id = (uintptr_t)event;
+
+    xorg_list_init(&event->list);
 
     /* Xwayland presentations always complete (at least) one frame after they
      * are executed
diff --git a/hw/xwayland/xwayland-present.h b/hw/xwayland/xwayland-present.h
index 2b789f53a..af7ded2bb 100644
--- a/hw/xwayland/xwayland-present.h
+++ b/hw/xwayland/xwayland-present.h
@@ -47,7 +47,6 @@ struct xwl_present_window {
     struct wl_callback *sync_callback;
 
     struct xorg_list wait_list;
-    struct xorg_list release_list;
     struct xorg_list exec_queue;
     struct xorg_list flip_queue;
     struct xorg_list idle_queue;
@@ -57,12 +56,11 @@ struct xwl_present_window {
 };
 
 struct xwl_present_event {
-    uint64_t event_id;
+    present_vblank_rec vblank;
     uint64_t target_msc;
 
     Bool pending;
 
-    struct xwl_present_window *xwl_present_window;
     PixmapPtr pixmap;
 
     struct xorg_list list;
diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c
index 3fe5d82a7..bb18e5c94 100644
--- a/hw/xwayland/xwayland-screen.c
+++ b/hw/xwayland/xwayland-screen.c
@@ -687,9 +687,6 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
     if (!xwl_screen_init_cursor(xwl_screen))
         return FALSE;
 
-    xwl_screen->DestroyWindow = pScreen->DestroyWindow;
-    pScreen->DestroyWindow = xwl_destroy_window;
-
 #ifdef XWL_HAS_GLAMOR
     if (xwl_screen->glamor) {
         xwl_glamor_select_backend(xwl_screen, use_eglstreams);
@@ -717,6 +714,9 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
     xwl_screen->UnrealizeWindow = pScreen->UnrealizeWindow;
     pScreen->UnrealizeWindow = xwl_unrealize_window;
 
+    xwl_screen->DestroyWindow = pScreen->DestroyWindow;
+    pScreen->DestroyWindow = xwl_destroy_window;
+
     xwl_screen->CloseScreen = pScreen->CloseScreen;
     pScreen->CloseScreen = xwl_close_screen;
 
commit 61cc5d96ed281a082d8dd414506dea0084e446fd
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Wed May 5 15:02:25 2021 +0200

    present: Refactor present_vblank_init helper ouf of _vblank_create
    
    Allows embedding into another struct.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/present/present_priv.h b/present/present_priv.h
index 99fe37f0f..e75ef6f9d 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -448,6 +448,25 @@ present_screen_priv_init(ScreenPtr screen);
 void
 present_vblank_notify(present_vblank_ptr vblank, CARD8 kind, CARD8 mode, uint64_t ust, uint64_t crtc_msc);
 
+Bool
+present_vblank_init(present_vblank_ptr vblank,
+                    WindowPtr window,
+                    PixmapPtr pixmap,
+                    CARD32 serial,
+                    RegionPtr valid,
+                    RegionPtr update,
+                    int16_t x_off,
+                    int16_t y_off,
+                    RRCrtcPtr target_crtc,
+                    SyncFence *wait_fence,
+                    SyncFence *idle_fence,
+                    uint32_t options,
+                    const uint32_t capabilities,
+                    present_notify_ptr notifies,
+                    int num_notifies,
+                    uint64_t target_msc,
+                    uint64_t crtc_msc);
+
 present_vblank_ptr
 present_vblank_create(WindowPtr window,
                       PixmapPtr pixmap,
diff --git a/present/present_vblank.c b/present/present_vblank.c
index 4401395d7..beca01982 100644
--- a/present/present_vblank.c
+++ b/present/present_vblank.c
@@ -38,38 +38,39 @@ present_vblank_notify(present_vblank_ptr vblank, CARD8 kind, CARD8 mode, uint64_
     }
 }
 
-present_vblank_ptr
-present_vblank_create(WindowPtr window,
-                      PixmapPtr pixmap,
-                      CARD32 serial,
-                      RegionPtr valid,
-                      RegionPtr update,
-                      int16_t x_off,
-                      int16_t y_off,
-                      RRCrtcPtr target_crtc,
-                      SyncFence *wait_fence,
-                      SyncFence *idle_fence,
-                      uint32_t options,
-                      const uint32_t capabilities,
-                      present_notify_ptr notifies,
-                      int num_notifies,
-                      uint64_t target_msc,
-                      uint64_t crtc_msc)
+/* The memory vblank points to must be 0-initialized before calling this function.
+ *
+ * If this function returns FALSE, present_vblank_destroy must be called to clean
+ * up.
+ */
+Bool
+present_vblank_init(present_vblank_ptr vblank,
+                    WindowPtr window,
+                    PixmapPtr pixmap,
+                    CARD32 serial,
+                    RegionPtr valid,
+                    RegionPtr update,
+                    int16_t x_off,
+                    int16_t y_off,
+                    RRCrtcPtr target_crtc,
+                    SyncFence *wait_fence,
+                    SyncFence *idle_fence,
+                    uint32_t options,
+                    const uint32_t capabilities,
+                    present_notify_ptr notifies,
+                    int num_notifies,
+                    uint64_t target_msc,
+                    uint64_t crtc_msc)
 {
     ScreenPtr                   screen = window->drawable.pScreen;
     present_window_priv_ptr     window_priv = present_get_window_priv(window, TRUE);
     present_screen_priv_ptr     screen_priv = present_screen_priv(screen);
-    present_vblank_ptr          vblank;
     PresentFlipReason           reason = PRESENT_FLIP_REASON_UNKNOWN;
 
     if (target_crtc) {
         screen_priv = present_screen_priv(target_crtc->pScreen);
     }
 
-    vblank = calloc (1, sizeof (present_vblank_rec));
-    if (!vblank)
-        return NULL;
-
     xorg_list_append(&vblank->window_list, &window_priv->vblank);
     xorg_list_init(&vblank->event_queue);
 
@@ -140,10 +141,42 @@ present_vblank_create(WindowPtr window,
                       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;
+    return TRUE;
 
 no_mem:
     vblank->notifies = NULL;
+    return FALSE;
+}
+
+present_vblank_ptr
+present_vblank_create(WindowPtr window,
+                      PixmapPtr pixmap,
+                      CARD32 serial,
+                      RegionPtr valid,
+                      RegionPtr update,
+                      int16_t x_off,
+                      int16_t y_off,
+                      RRCrtcPtr target_crtc,
+                      SyncFence *wait_fence,
+                      SyncFence *idle_fence,
+                      uint32_t options,
+                      const uint32_t capabilities,
+                      present_notify_ptr notifies,
+                      int num_notifies,
+                      uint64_t target_msc,
+                      uint64_t crtc_msc)
+{
+    present_vblank_ptr vblank = calloc(1, sizeof(present_vblank_rec));
+
+    if (!vblank)
+        return NULL;
+
+    if (present_vblank_init(vblank, window, pixmap, serial, valid, update,
+                            x_off, y_off, target_crtc, wait_fence, idle_fence,
+                            options, capabilities, notifies, num_notifies,
+                            target_msc, crtc_msc))
+        return vblank;
+
     present_vblank_destroy(vblank);
     return NULL;
 }
commit 35f173ddb606f9fbac7957e427fe28a377204cfe
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Thu Apr 29 18:44:04 2021 +0200

    xwayland/present: Drop abort member of struct xwl_present_event
    
    We can call xwl_present_free_event unconditionally from
    xwl_present_abort_vblank, since the sync_callback is already destroyed
    in xwl_present_cleanup.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index f5e3593ad..c7566ab94 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -459,8 +459,7 @@ xwl_present_buffer_release(void *data)
 
     xwl_present_release_pixmap(event);
 
-    if (!event->abort)
-        xwl_present_idle_notify(event->xwl_present_window->window, event->event_id);
+    xwl_present_idle_notify(event->xwl_present_window->window, event->event_id);
 
     if (!event->pending)
         xwl_present_free_event(event);
@@ -547,9 +546,8 @@ xwl_present_sync_callback(void *data,
 
     event->pending = FALSE;
 
-    if (!event->abort)
-        xwl_present_flip_notify(xwl_present_window->window, event->event_id,
-                                xwl_present_window->ust, xwl_present_window->msc);
+    xwl_present_flip_notify(xwl_present_window->window, event->event_id,
+                            xwl_present_window->ust, xwl_present_window->msc);
 
     if (!event->pixmap)
         xwl_present_free_event(event);
@@ -642,7 +640,7 @@ xwl_present_abort_vblank(ScreenPtr screen,
 
         xorg_list_for_each_entry(event, &xwl_present_window->release_list, list) {
             if (event->event_id == event_id) {
-                event->abort = TRUE;
+                xwl_present_free_event(event);
                 break;
             }
         }
@@ -816,7 +814,6 @@ xwl_present_flip(WindowPtr present_window,
     event->pixmap = pixmap;
     event->target_msc = target_msc;
     event->pending = TRUE;
-    event->abort = FALSE;
 
     if (sync_flip) {
         xorg_list_init(&event->list);
diff --git a/hw/xwayland/xwayland-present.h b/hw/xwayland/xwayland-present.h
index e595f4de2..2b789f53a 100644
--- a/hw/xwayland/xwayland-present.h
+++ b/hw/xwayland/xwayland-present.h
@@ -60,7 +60,6 @@ struct xwl_present_event {
     uint64_t event_id;
     uint64_t target_msc;
 
-    Bool abort;
     Bool pending;
 
     struct xwl_present_window *xwl_present_window;
commit 0517460301cbf9c6ed3020ef1dd0cd1df94ea178
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Tue May 11 12:56:53 2021 +0200

    xwayland/present: Simplify calls to Xwayland-private functions
    
    Change parameter types to what's really needed, or just fold the
    function into its only caller.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 0a6a54115..f5e3593ad 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -166,10 +166,9 @@ xwl_present_re_execute(present_vblank_ptr vblank)
 }
 
 static void
-xwl_present_flip_try_ready(WindowPtr window)
+xwl_present_flip_try_ready(struct xwl_present_window *xwl_present_window)
 {
-    struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
-    present_vblank_ptr      vblank;
+    present_vblank_ptr vblank;
 
     xorg_list_for_each_entry(vblank, &xwl_present_window->flip_queue, event_queue) {
         if (vblank->queued) {
@@ -186,25 +185,6 @@ xwl_present_free_idle_vblank(present_vblank_ptr vblank)
     present_vblank_destroy(vblank);
 }
 
-/*
- * Free any left over idle vblanks
- */
-static void
-xwl_present_free_idle_vblanks(WindowPtr window)
-{
-    struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
-    present_vblank_ptr              vblank, tmp;
-
-    xorg_list_for_each_entry_safe(vblank, tmp, &xwl_present_window->idle_queue, event_queue) {
-        xwl_present_free_idle_vblank(vblank);
-    }
-
-    if (xwl_present_window->flip_active) {
-        xwl_present_free_idle_vblank(xwl_present_window->flip_active);
-        xwl_present_window->flip_active = NULL;
-    }
-}
-
 static WindowPtr
 xwl_present_toplvl_pixmap_window(WindowPtr window)
 {
@@ -227,14 +207,23 @@ static void
 xwl_present_flips_stop(WindowPtr window)
 {
     struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
+    present_vblank_ptr vblank, tmp;
 
     assert (!xwl_present_window->flip_pending);
 
     /* Change back to the fast refresh rate */
     xwl_present_reset_timer(xwl_present_window);
 
-    xwl_present_free_idle_vblanks(window);
-    xwl_present_flip_try_ready(window);
+    /* Free any left over idle vblanks */
+    xorg_list_for_each_entry_safe(vblank, tmp, &xwl_present_window->idle_queue, event_queue)
+        xwl_present_free_idle_vblank(vblank);
+
+    if (xwl_present_window->flip_active) {
+        xwl_present_free_idle_vblank(xwl_present_window->flip_active);
+        xwl_present_window->flip_active = NULL;
+    }
+
+    xwl_present_flip_try_ready(xwl_present_window);
 }
 
 static void
@@ -270,7 +259,7 @@ xwl_present_flip_notify_vblank(present_vblank_ptr vblank, uint64_t ust, uint64_t
     if (vblank->abort_flip)
         xwl_present_flips_stop(window);
 
-    xwl_present_flip_try_ready(window);
+    xwl_present_flip_try_ready(xwl_present_window);
 }
 
 static void
@@ -380,21 +369,8 @@ xwl_present_clear_window_flip(WindowPtr window)
 }
 
 static void
-xwl_present_cancel_flip(WindowPtr window)
-{
-    struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
-
-    if (xwl_present_window->flip_pending)
-        xwl_present_window->flip_pending->abort_flip = TRUE;
-    else if (xwl_present_window->flip_active)
-        xwl_present_flips_stop(window);
-}
-
-static void
-xwl_present_update_window_crtc(WindowPtr window, RRCrtcPtr crtc, uint64_t new_msc)
+xwl_present_update_window_crtc(present_window_priv_ptr window_priv, RRCrtcPtr crtc, uint64_t new_msc)
 {
-    present_window_priv_ptr window_priv = present_get_window_priv(window, TRUE);
-
     /* Crtc unchanged, no offset. */
     if (crtc == window_priv->crtc)
         return;
@@ -977,7 +953,10 @@ xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
         DebugPresent(("\tc %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
                       vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id));
 
-        xwl_present_cancel_flip(window);
+        if (xwl_present_window->flip_pending)
+            xwl_present_window->flip_pending->abort_flip = TRUE;
+        else if (xwl_present_window->flip_active)
+            xwl_present_flips_stop(window);
 
         present_execute_copy(vblank, crtc_msc);
         assert(!vblank->queued);
@@ -1030,7 +1009,7 @@ xwl_present_pixmap(WindowPtr window,
 
     ret = xwl_present_get_ust_msc(screen, window, &ust, &crtc_msc);
 
-    xwl_present_update_window_crtc(window, target_crtc, crtc_msc);
+    xwl_present_update_window_crtc(window_priv, target_crtc, crtc_msc);
 
     if (ret == Success) {
         /* Stash the current MSC away in case we need it later
commit 490248ea70d3fe923446e17312880ae63590d45c
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Mon Apr 19 12:59:56 2021 +0200

    xwayland/present: Rename present_wnmd_* functions to xwl_present_*
    
    The WNMD indirection is gone.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 262376486..0a6a54115 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -47,7 +47,7 @@
 #define TIMER_LEN_COPY      17  // ~60fps
 #define TIMER_LEN_FLIP    1000  // 1fps
 
-static uint64_t present_wnmd_event_id;
+static uint64_t xwl_present_event_id;
 
 static DevPrivateKeyRec xwl_present_window_private_key;
 
@@ -128,7 +128,7 @@ xwl_present_reset_timer(struct xwl_present_window *xwl_present_window)
 
 
 static void
-present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc);
+xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc);
 
 static uint32_t
 xwl_present_query_capabilities(present_screen_priv_ptr screen_priv)
@@ -157,30 +157,30 @@ xwl_present_get_ust_msc(ScreenPtr screen,
  * to re-try the request
  */
 static void
-present_wnmd_re_execute(present_vblank_ptr vblank)
+xwl_present_re_execute(present_vblank_ptr vblank)
 {
     uint64_t ust = 0, crtc_msc = 0;
 
     (void) xwl_present_get_ust_msc(vblank->screen, vblank->window, &ust, &crtc_msc);
-    present_wnmd_execute(vblank, ust, crtc_msc);
+    xwl_present_execute(vblank, ust, crtc_msc);
 }
 
 static void
-present_wnmd_flip_try_ready(WindowPtr window)
+xwl_present_flip_try_ready(WindowPtr window)
 {
     struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
     present_vblank_ptr      vblank;
 
     xorg_list_for_each_entry(vblank, &xwl_present_window->flip_queue, event_queue) {
         if (vblank->queued) {
-            present_wnmd_re_execute(vblank);
+            xwl_present_re_execute(vblank);
             return;
         }
     }
 }
 
 static void
-present_wnmd_free_idle_vblank(present_vblank_ptr vblank)
+xwl_present_free_idle_vblank(present_vblank_ptr vblank)
 {
     present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
     present_vblank_destroy(vblank);
@@ -190,23 +190,23 @@ present_wnmd_free_idle_vblank(present_vblank_ptr vblank)
  * Free any left over idle vblanks
  */
 static void
-present_wnmd_free_idle_vblanks(WindowPtr window)
+xwl_present_free_idle_vblanks(WindowPtr window)
 {
     struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
     present_vblank_ptr              vblank, tmp;
 
     xorg_list_for_each_entry_safe(vblank, tmp, &xwl_present_window->idle_queue, event_queue) {
-        present_wnmd_free_idle_vblank(vblank);
+        xwl_present_free_idle_vblank(vblank);
     }
 
     if (xwl_present_window->flip_active) {
-        present_wnmd_free_idle_vblank(xwl_present_window->flip_active);
+        xwl_present_free_idle_vblank(xwl_present_window->flip_active);
         xwl_present_window->flip_active = NULL;
     }
 }
 
 static WindowPtr
-present_wnmd_toplvl_pixmap_window(WindowPtr window)
+xwl_present_toplvl_pixmap_window(WindowPtr window)
 {
     ScreenPtr       screen = window->drawable.pScreen;
     PixmapPtr       pixmap = (*screen->GetWindowPixmap)(window);
@@ -233,12 +233,12 @@ xwl_present_flips_stop(WindowPtr window)
     /* Change back to the fast refresh rate */
     xwl_present_reset_timer(xwl_present_window);
 
-    present_wnmd_free_idle_vblanks(window);
-    present_wnmd_flip_try_ready(window);
+    xwl_present_free_idle_vblanks(window);
+    xwl_present_flip_try_ready(window);
 }
 
 static void
-present_wnmd_flip_notify_vblank(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
+xwl_present_flip_notify_vblank(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
 {
     WindowPtr                   window = vblank->window;
     struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
@@ -254,7 +254,7 @@ present_wnmd_flip_notify_vblank(present_vblank_ptr vblank, uint64_t ust, uint64_
 
     if (xwl_present_window->flip_active) {
         if (xwl_present_window->flip_active->flip_idler)
-            present_wnmd_free_idle_vblank(xwl_present_window->flip_active);
+            xwl_present_free_idle_vblank(xwl_present_window->flip_active);
         else
             /* Put the previous flip in the idle_queue and wait for further notice from
              * the Wayland compositor
@@ -270,11 +270,11 @@ present_wnmd_flip_notify_vblank(present_vblank_ptr vblank, uint64_t ust, uint64_
     if (vblank->abort_flip)
         xwl_present_flips_stop(window);
 
-    present_wnmd_flip_try_ready(window);
+    xwl_present_flip_try_ready(window);
 }
 
 static void
-present_wnmd_event_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uint64_t msc)
+xwl_present_event_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uint64_t msc)
 {
     struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
     present_window_priv_ptr     window_priv = present_window_priv(window);
@@ -288,14 +288,14 @@ present_wnmd_event_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uin
     DebugPresent(("\te %" PRIu64 " ust %" PRIu64 " msc %" PRIu64 "\n", event_id, ust, msc));
     xorg_list_for_each_entry(vblank, &xwl_present_window->exec_queue, event_queue) {
         if (event_id == vblank->event_id) {
-            present_wnmd_execute(vblank, ust, msc);
+            xwl_present_execute(vblank, ust, msc);
             return;
         }
     }
     xorg_list_for_each_entry(vblank, &xwl_present_window->flip_queue, event_queue) {
         if (vblank->event_id == event_id) {
             assert(vblank->queued);
-            present_wnmd_execute(vblank, ust, msc);
+            xwl_present_execute(vblank, ust, msc);
             return;
         }
     }
@@ -310,7 +310,7 @@ present_wnmd_event_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uin
 }
 
 static void
-present_wnmd_flip_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uint64_t msc)
+xwl_present_flip_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uint64_t msc)
 {
     struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
     present_vblank_ptr          vblank;
@@ -319,14 +319,14 @@ present_wnmd_flip_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uint
         if (vblank->event_id == event_id) {
             assert(!vblank->queued);
             assert(vblank->window);
-            present_wnmd_flip_notify_vblank(vblank, ust, msc);
+            xwl_present_flip_notify_vblank(vblank, ust, msc);
             return;
         }
     }
 }
 
 static void
-present_wnmd_idle_notify(WindowPtr window, uint64_t event_id)
+xwl_present_idle_notify(WindowPtr window, uint64_t event_id)
 {
     struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
     present_vblank_ptr          vblank;
@@ -339,7 +339,7 @@ present_wnmd_idle_notify(WindowPtr window, uint64_t event_id)
 
     xorg_list_for_each_entry(vblank, &xwl_present_window->idle_queue, event_queue) {
         if (vblank->event_id == event_id) {
-            present_wnmd_free_idle_vblank(vblank);
+            xwl_present_free_idle_vblank(vblank);
             return;
         }
     }
@@ -356,7 +356,7 @@ present_wnmd_idle_notify(WindowPtr window, uint64_t event_id)
  * Clean up any pending or current flips for this window
  */
 static void
-present_wnmd_clear_window_flip(WindowPtr window)
+xwl_present_clear_window_flip(WindowPtr window)
 {
     struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
     present_vblank_ptr          vblank, tmp;
@@ -380,7 +380,7 @@ present_wnmd_clear_window_flip(WindowPtr window)
 }
 
 static void
-present_wnmd_cancel_flip(WindowPtr window)
+xwl_present_cancel_flip(WindowPtr window)
 {
     struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
 
@@ -391,7 +391,7 @@ present_wnmd_cancel_flip(WindowPtr window)
 }
 
 static void
-present_wnmd_update_window_crtc(WindowPtr window, RRCrtcPtr crtc, uint64_t new_msc)
+xwl_present_update_window_crtc(WindowPtr window, RRCrtcPtr crtc, uint64_t new_msc)
 {
     present_window_priv_ptr window_priv = present_get_window_priv(window, TRUE);
 
@@ -484,7 +484,7 @@ xwl_present_buffer_release(void *data)
     xwl_present_release_pixmap(event);
 
     if (!event->abort)
-        present_wnmd_idle_notify(event->xwl_present_window->window, event->event_id);
+        xwl_present_idle_notify(event->xwl_present_window->window, event->event_id);
 
     if (!event->pending)
         xwl_present_free_event(event);
@@ -503,8 +503,8 @@ xwl_present_msc_bump(struct xwl_present_window *xwl_present_window)
     if (event) {
         event->pending = FALSE;
 
-        present_wnmd_flip_notify(xwl_present_window->window, event->event_id,
-                                 xwl_present_window->ust, msc);
+        xwl_present_flip_notify(xwl_present_window->window, event->event_id,
+                                xwl_present_window->ust, msc);
 
         if (!event->pixmap) {
             /* If the buffer was already released, clean up now */
@@ -518,10 +518,10 @@ xwl_present_msc_bump(struct xwl_present_window *xwl_present_window)
                                   &xwl_present_window->wait_list,
                                   list) {
         if (event->target_msc <= msc) {
-            present_wnmd_event_notify(xwl_present_window->window,
-                                      event->event_id,
-                                      xwl_present_window->ust,
-                                      msc);
+            xwl_present_event_notify(xwl_present_window->window,
+                                     event->event_id,
+                                     xwl_present_window->ust,
+                                     msc);
             xwl_present_free_event(event);
         }
     }
@@ -572,8 +572,8 @@ xwl_present_sync_callback(void *data,
     event->pending = FALSE;
 
     if (!event->abort)
-        present_wnmd_flip_notify(xwl_present_window->window, event->event_id,
-                                 xwl_present_window->ust, xwl_present_window->msc);
+        xwl_present_flip_notify(xwl_present_window->window, event->event_id,
+                                xwl_present_window->ust, xwl_present_window->msc);
 
     if (!event->pixmap)
         xwl_present_free_event(event);
@@ -704,7 +704,7 @@ xwl_present_check_flip(RRCrtcPtr crtc,
                        int16_t y_off,
                        PresentFlipReason *reason)
 {
-    WindowPtr toplvl_window = present_wnmd_toplvl_pixmap_window(present_window);
+    WindowPtr toplvl_window = xwl_present_toplvl_pixmap_window(present_window);
     struct xwl_window *xwl_window = xwl_window_from_window(present_window);
     ScreenPtr screen = pixmap->drawable.pScreen;
 
@@ -764,7 +764,7 @@ xwl_present_check_flip(RRCrtcPtr crtc,
  * in flipping and clean up as necessary.
  */
 static void
-present_wnmd_check_flip_window (WindowPtr window)
+xwl_present_check_flip_window (WindowPtr window)
 {
     struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
     present_window_priv_ptr window_priv = present_window_priv(window);
@@ -896,7 +896,7 @@ xwl_present_flip(WindowPtr present_window,
  * go straight to event delivery.
  */
 static void
-present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
+xwl_present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
 {
     WindowPtr               window = vblank->window;
     struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
@@ -950,7 +950,7 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
             xwl_present_window->flip_pending = vblank;
             if (xwl_present_flip(vblank->window, vblank->crtc, vblank->event_id,
                                  vblank->target_msc, vblank->pixmap, vblank->sync_flip, damage)) {
-                WindowPtr toplvl_window = present_wnmd_toplvl_pixmap_window(vblank->window);
+                WindowPtr toplvl_window = xwl_present_toplvl_pixmap_window(vblank->window);
                 PixmapPtr old_pixmap = screen->GetWindowPixmap(window);
 
                 /* Replace window pixmap with flip pixmap */
@@ -977,7 +977,7 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
         DebugPresent(("\tc %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
                       vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id));
 
-        present_wnmd_cancel_flip(window);
+        xwl_present_cancel_flip(window);
 
         present_execute_copy(vblank, crtc_msc);
         assert(!vblank->queued);
@@ -996,22 +996,22 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
 }
 
 static int
-present_wnmd_pixmap(WindowPtr window,
-                    PixmapPtr pixmap,
-                    CARD32 serial,
-                    RegionPtr valid,
-                    RegionPtr update,
-                    int16_t x_off,
-                    int16_t y_off,
-                    RRCrtcPtr target_crtc,
-                    SyncFence *wait_fence,
-                    SyncFence *idle_fence,
-                    uint32_t options,
-                    uint64_t target_window_msc,
-                    uint64_t divisor,
-                    uint64_t remainder,
-                    present_notify_ptr notifies,
-                    int num_notifies)
+xwl_present_pixmap(WindowPtr window,
+                   PixmapPtr pixmap,
+                   CARD32 serial,
+                   RegionPtr valid,
+                   RegionPtr update,
+                   int16_t x_off,
+                   int16_t y_off,
+                   RRCrtcPtr target_crtc,
+                   SyncFence *wait_fence,
+                   SyncFence *idle_fence,
+                   uint32_t options,
+                   uint64_t target_window_msc,
+                   uint64_t divisor,
+                   uint64_t remainder,
+                   present_notify_ptr notifies,
+                   int num_notifies)
 {
     uint64_t                    ust = 0;
     uint64_t                    target_msc;
@@ -1030,7 +1030,7 @@ present_wnmd_pixmap(WindowPtr window,
 
     ret = xwl_present_get_ust_msc(screen, window, &ust, &crtc_msc);
 
-    present_wnmd_update_window_crtc(window, target_crtc, crtc_msc);
+    xwl_present_update_window_crtc(window, target_crtc, crtc_msc);
 
     if (ret == Success) {
         /* Stash the current MSC away in case we need it later
@@ -1062,7 +1062,7 @@ present_wnmd_pixmap(WindowPtr window,
 
             present_vblank_scrap(vblank);
             if (vblank->flip_ready)
-                present_wnmd_re_execute(vblank);
+                xwl_present_re_execute(vblank);
         }
     }
 
@@ -1085,9 +1085,9 @@ present_wnmd_pixmap(WindowPtr window,
     if (!vblank)
         return BadAlloc;
 
-    vblank->event_id = ++present_wnmd_event_id;
+    vblank->event_id = ++xwl_present_event_id;
 
-    /* WNMD presentations always complete (at least) one frame after they
+    /* Xwayland presentations always complete (at least) one frame after they
      * are executed
      */
     vblank->exec_msc = vblank->target_msc - 1;
@@ -1101,7 +1101,7 @@ present_wnmd_pixmap(WindowPtr window,
         DebugPresent(("present_queue_vblank failed\n"));
     }
 
-    present_wnmd_execute(vblank, ust, crtc_msc);
+    xwl_present_execute(vblank, ust, crtc_msc);
     return Success;
 }
 
@@ -1141,13 +1141,13 @@ xwl_present_init(ScreenPtr screen)
     screen_priv->get_crtc = xwl_present_get_crtc;
 
     screen_priv->check_flip = xwl_present_check_flip;
-    screen_priv->check_flip_window = present_wnmd_check_flip_window;
-    screen_priv->clear_window_flip = present_wnmd_clear_window_flip;
+    screen_priv->check_flip_window = xwl_present_check_flip_window;
+    screen_priv->clear_window_flip = xwl_present_clear_window_flip;
 
-    screen_priv->present_pixmap = present_wnmd_pixmap;
+    screen_priv->present_pixmap = xwl_present_pixmap;
     screen_priv->queue_vblank = xwl_present_queue_vblank;
     screen_priv->flush = xwl_present_flush;
-    screen_priv->re_execute = present_wnmd_re_execute;
+    screen_priv->re_execute = xwl_present_re_execute;
 
     screen_priv->abort_vblank = xwl_present_abort_vblank;
 
commit 0c0cbbc7cb4fa917a2b33494efb6dc03e5de9051
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Wed Apr 21 17:15:27 2021 +0200

    present: Remove present_wnmd_info_rec
    
    Doesn't serve any purpose anymore.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 403bf8733..262376486 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -1115,10 +1115,6 @@ xwl_present_unrealize_window(struct xwl_present_window *xwl_present_window)
     xwl_present_reset_timer(xwl_present_window);
 }
 
-static present_wnmd_info_rec xwl_present_info = {
-    .version = PRESENT_SCREEN_INFO_VERSION,
-};
-
 Bool
 xwl_present_init(ScreenPtr screen)
 {
@@ -1141,8 +1137,6 @@ xwl_present_init(ScreenPtr screen)
     if (!dixRegisterPrivateKey(&xwl_present_window_private_key, PRIVATE_WINDOW, 0))
         return FALSE;
 
-    screen_priv->wnmd_info = &xwl_present_info;
-
     screen_priv->query_capabilities = xwl_present_query_capabilities;
     screen_priv->get_crtc = xwl_present_get_crtc;
 
diff --git a/present/present.h b/present/present.h
index a09b3846a..389069195 100644
--- a/present/present.h
+++ b/present/present.h
@@ -139,21 +139,6 @@ typedef struct present_screen_info {
 
 } present_screen_info_rec, *present_screen_info_ptr;
 
-typedef struct present_wnmd_info {
-    uint32_t                            version;
-
-    present_get_crtc_ptr                get_crtc;
-    present_wnmd_get_ust_msc_ptr        get_ust_msc;
-    present_wnmd_queue_vblank_ptr       queue_vblank;
-    present_wnmd_abort_vblank_ptr       abort_vblank;
-    present_flush_ptr                   flush;
-    uint32_t                            capabilities;
-    present_check_flip2_ptr             check_flip2;
-    present_wnmd_flip_ptr               flip;
-    present_wnmd_flips_stop_ptr         flips_stop;
-
-} present_wnmd_info_rec, *present_wnmd_info_ptr;
-
 /*
  * Called when 'event_id' occurs. 'ust' and 'msc' indicate when the
  * event actually happened
diff --git a/present/present_priv.h b/present/present_priv.h
index 5f62dd43d..99fe37f0f 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -162,7 +162,6 @@ struct present_screen_priv {
     Bool                        flip_sync;
 
     present_screen_info_ptr     info;
-    present_wnmd_info_ptr       wnmd_info;
 
     /* Mode hooks */
     present_priv_query_capabilities_ptr query_capabilities;
commit 561c63d0f13a8c6379ed05338172570f93dbce37
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Mon Apr 19 18:41:59 2021 +0200

    xwayland/present: Merge present_wnmd_flips_stop & xwl_present_flips_stop
    
    Just use the latter instead of the former elsewhere. No need for them
    to be separate anymore.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index ca0ad3a94..403bf8733 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -224,14 +224,14 @@ present_wnmd_toplvl_pixmap_window(WindowPtr window)
 }
 
 static void
-present_wnmd_flips_stop(WindowPtr window)
+xwl_present_flips_stop(WindowPtr window)
 {
     struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
-    present_screen_priv_ptr screen_priv = present_screen_priv(window->drawable.pScreen);
 
     assert (!xwl_present_window->flip_pending);
 
-    (*screen_priv->wnmd_info->flips_stop) (window);
+    /* Change back to the fast refresh rate */
+    xwl_present_reset_timer(xwl_present_window);
 
     present_wnmd_free_idle_vblanks(window);
     present_wnmd_flip_try_ready(window);
@@ -268,7 +268,7 @@ present_wnmd_flip_notify_vblank(present_vblank_ptr vblank, uint64_t ust, uint64_
     present_vblank_notify(vblank, PresentCompleteKindPixmap, PresentCompleteModeFlip, ust, crtc_msc);
 
     if (vblank->abort_flip)
-        present_wnmd_flips_stop(window);
+        xwl_present_flips_stop(window);
 
     present_wnmd_flip_try_ready(window);
 }
@@ -387,7 +387,7 @@ present_wnmd_cancel_flip(WindowPtr window)
     if (xwl_present_window->flip_pending)
         xwl_present_window->flip_pending->abort_flip = TRUE;
     else if (xwl_present_window->flip_active)
-        present_wnmd_flips_stop(window);
+        xwl_present_flips_stop(window);
 }
 
 static void
@@ -789,7 +789,7 @@ present_wnmd_check_flip_window (WindowPtr window)
     } else if (flip_active) {
         if (!xwl_present_check_flip(flip_active->crtc, flip_active->window, flip_active->pixmap,
                                     flip_active->sync_flip, flip_active->valid, 0, 0, NULL))
-            present_wnmd_flips_stop(window);
+            xwl_present_flips_stop(window);
     }
 
     /* Now check any queued vblanks */
@@ -886,15 +886,6 @@ xwl_present_flip(WindowPtr present_window,
     return TRUE;
 }
 
-static void
-xwl_present_flips_stop(WindowPtr window)
-{
-    struct xwl_present_window   *xwl_present_window = xwl_present_window_priv(window);
-
-    /* Change back to the fast refresh rate */
-    xwl_present_reset_timer(xwl_present_window);
-}
-
 /*
  * Once the required MSC has been reached, execute the pending request.
  *
@@ -1126,8 +1117,6 @@ xwl_present_unrealize_window(struct xwl_present_window *xwl_present_window)
 
 static present_wnmd_info_rec xwl_present_info = {
     .version = PRESENT_SCREEN_INFO_VERSION,
-
-    .flips_stop = xwl_present_flips_stop
 };
 
 Bool
commit a67f16fde1ff094c3ec4fffe8a7269b30c7b8668
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Mon Apr 19 18:53:36 2021 +0200

    xwayland/present: Fold present_wnmd_get_ust_msc into its callers
    
    Just use xwl_present_get_ust_msc directly. No need for the indirection
    anymore.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 38c278831..ca0ad3a94 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -137,10 +137,19 @@ xwl_present_query_capabilities(present_screen_priv_ptr screen_priv)
 }
 
 static int
-present_wnmd_get_ust_msc(ScreenPtr screen, WindowPtr window, uint64_t *ust, uint64_t *msc)
+xwl_present_get_ust_msc(ScreenPtr screen,
+                        WindowPtr present_window,
+                        uint64_t *ust,
+                        uint64_t *msc)
 {
-    present_screen_priv_ptr screen_priv = present_screen_priv(screen);
-    return (*screen_priv->wnmd_info->get_ust_msc)(window, ust, msc);
+    struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window);
+    if (!xwl_present_window)
+        return BadAlloc;
+
+    *ust = xwl_present_window->ust;
+    *msc = xwl_present_window->msc;
+
+    return Success;
 }
 
 /*
@@ -152,7 +161,7 @@ present_wnmd_re_execute(present_vblank_ptr vblank)
 {
     uint64_t ust = 0, crtc_msc = 0;
 
-    (void) present_wnmd_get_ust_msc(vblank->screen, vblank->window, &ust, &crtc_msc);
+    (void) xwl_present_get_ust_msc(vblank->screen, vblank->window, &ust, &crtc_msc);
     present_wnmd_execute(vblank, ust, crtc_msc);
 }
 
@@ -592,19 +601,6 @@ xwl_present_get_crtc(present_screen_priv_ptr screen_priv,
     return rr_private->crtcs[0];
 }
 
-static int
-xwl_present_get_ust_msc(WindowPtr present_window, uint64_t *ust, uint64_t *msc)
-{
-    struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window);
-    if (!xwl_present_window)
-        return BadAlloc;
-
-    *ust = xwl_present_window->ust;
-    *msc = xwl_present_window->msc;
-
-    return Success;
-}
-
 /*
  * Queue an event to report back to the Present extension when the specified
  * MSC has passed
@@ -1041,7 +1037,7 @@ present_wnmd_pixmap(WindowPtr window,
 
     target_crtc = xwl_present_get_crtc(screen_priv, window);
 
-    ret = present_wnmd_get_ust_msc(screen, window, &ust, &crtc_msc);
+    ret = xwl_present_get_ust_msc(screen, window, &ust, &crtc_msc);
 
     present_wnmd_update_window_crtc(window, target_crtc, crtc_msc);
 
@@ -1131,8 +1127,6 @@ xwl_present_unrealize_window(struct xwl_present_window *xwl_present_window)
 static present_wnmd_info_rec xwl_present_info = {
     .version = PRESENT_SCREEN_INFO_VERSION,
 
-    .get_ust_msc = xwl_present_get_ust_msc,
-
     .flips_stop = xwl_present_flips_stop
 };
 
commit 080c1ca3f57b4226f34624b0cd2171ffbbc2be4f
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Mon Apr 19 18:46:23 2021 +0200

    xwayland/present: Fold present_wnmd_queue_vblank into its callers
    
    Just use xwl_present_queue_vblank directly. No need for the indirection
    anymore.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index e05b3ce68..38c278831 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -130,17 +130,6 @@ xwl_present_reset_timer(struct xwl_present_window *xwl_present_window)
 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 uint32_t
 xwl_present_query_capabilities(present_screen_priv_ptr screen_priv)
 {
@@ -618,10 +607,11 @@ xwl_present_get_ust_msc(WindowPtr present_window, uint64_t *ust, uint64_t *msc)
 
 /*
  * Queue an event to report back to the Present extension when the specified
- * MSC has past
+ * MSC has passed
  */
 static int
-xwl_present_queue_vblank(WindowPtr present_window,
+xwl_present_queue_vblank(ScreenPtr screen,
+                         WindowPtr present_window,
                          RRCrtcPtr crtc,
                          uint64_t event_id,
                          uint64_t msc)
@@ -1005,8 +995,8 @@ present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
         present_execute_copy(vblank, crtc_msc);
         assert(!vblank->queued);
 
-        if (present_wnmd_queue_vblank(screen, window, vblank->crtc,
-                                      vblank->event_id, crtc_msc + 1)
+        if (xwl_present_queue_vblank(screen, window, vblank->crtc,
+                                     vblank->event_id, crtc_msc + 1)
             == Success) {
             xorg_list_add(&vblank->event_queue, &xwl_present_window->idle_queue);
             xorg_list_append(&vblank->window_list, &window_priv->vblank);
@@ -1118,9 +1108,9 @@ present_wnmd_pixmap(WindowPtr window,
     xorg_list_append(&vblank->event_queue, &xwl_present_window->exec_queue);
     vblank->queued = TRUE;
     if (crtc_msc < vblank->exec_msc) {
-        if (present_wnmd_queue_vblank(screen, window, target_crtc, vblank->event_id, vblank->exec_msc) == Success) {
+        if (xwl_present_queue_vblank(screen, window, target_crtc, vblank->event_id, vblank->exec_msc) == Success)
             return Success;
-        }
+
         DebugPresent(("present_queue_vblank failed\n"));
     }
 
@@ -1142,7 +1132,6 @@ static present_wnmd_info_rec xwl_present_info = {
     .version = PRESENT_SCREEN_INFO_VERSION,
 
     .get_ust_msc = xwl_present_get_ust_msc,
-    .queue_vblank = xwl_present_queue_vblank,
 
     .flips_stop = xwl_present_flips_stop
 };
@@ -1179,7 +1168,7 @@ xwl_present_init(ScreenPtr screen)
     screen_priv->clear_window_flip = present_wnmd_clear_window_flip;
 
     screen_priv->present_pixmap = present_wnmd_pixmap;
-    screen_priv->queue_vblank = present_wnmd_queue_vblank;
+    screen_priv->queue_vblank = xwl_present_queue_vblank;
     screen_priv->flush = xwl_present_flush;
     screen_priv->re_execute = present_wnmd_re_execute;
 
commit c22887bc7a83e9b8ad112aadaec069b0366fc38e
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Mon Apr 19 18:51:06 2021 +0200

    xwayland/present: Fold present_wnmd_get_crtc into present_wnmd_pixmap
    
    And use xwl_present_get_crtc directly.
    
    No need for them to be separate anymore.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index c6bd93b06..e05b3ce68 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -147,12 +147,6 @@ xwl_present_query_capabilities(present_screen_priv_ptr screen_priv)
     return XWL_PRESENT_CAPS;
 }
 
-static RRCrtcPtr
-present_wnmd_get_crtc(present_screen_priv_ptr screen_priv, WindowPtr window)
-{
-    return (*screen_priv->wnmd_info->get_crtc)(window);
-}
-
 static int
 present_wnmd_get_ust_msc(ScreenPtr screen, WindowPtr window, uint64_t *ust, uint64_t *msc)
 {
@@ -422,116 +416,6 @@ present_wnmd_update_window_crtc(WindowPtr window, RRCrtcPtr crtc, uint64_t new_m
     window_priv->crtc = crtc;
 }
 
-static int
-present_wnmd_pixmap(WindowPtr window,
-                    PixmapPtr pixmap,
-                    CARD32 serial,
-                    RegionPtr valid,
-                    RegionPtr update,
-                    int16_t x_off,
-                    int16_t y_off,
-                    RRCrtcPtr target_crtc,
-                    SyncFence *wait_fence,
-                    SyncFence *idle_fence,
-                    uint32_t options,
-                    uint64_t target_window_msc,
-                    uint64_t divisor,
-                    uint64_t remainder,
-                    present_notify_ptr notifies,
-                    int num_notifies)
-{
-    uint64_t                    ust = 0;
-    uint64_t                    target_msc;
-    uint64_t                    crtc_msc = 0;
-    int                         ret;
-    present_vblank_ptr          vblank, tmp;
-    ScreenPtr                   screen = window->drawable.pScreen;
-    struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
-    present_window_priv_ptr     window_priv = present_get_window_priv(window, TRUE);
-    present_screen_priv_ptr     screen_priv = present_screen_priv(screen);
-
-    if (!window_priv)
-        return BadAlloc;
-
-    target_crtc = present_wnmd_get_crtc(screen_priv, window);
-
-    ret = present_wnmd_get_ust_msc(screen, window, &ust, &crtc_msc);
-
-    present_wnmd_update_window_crtc(window, target_crtc, crtc_msc);
-
-    if (ret == Success) {
-        /* Stash the current MSC away in case we need it later
-         */
-        window_priv->msc = crtc_msc;
-    }
-
-    target_msc = present_get_target_msc(target_window_msc + window_priv->msc_offset,
-                                        crtc_msc,
-                                        divisor,
-                                        remainder,
-                                        options);
-
-    /*
-     * Look for a matching presentation already on the list...
-     */
-
-    if (!update && pixmap) {
-        xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->vblank, window_list) {
-
-            if (!vblank->pixmap)
-                continue;
-
-            if (!vblank->queued)
-                continue;
-
-            if (vblank->target_msc != target_msc)
-                continue;
-
-            present_vblank_scrap(vblank);
-            if (vblank->flip_ready)
-                present_wnmd_re_execute(vblank);
-        }
-    }
-
-    vblank = present_vblank_create(window,
-                                   pixmap,
-                                   serial,
-                                   valid,
-                                   update,
-                                   x_off,
-                                   y_off,
-                                   target_crtc,
-                                   wait_fence,
-                                   idle_fence,
-                                   options,
-                                   XWL_PRESENT_CAPS,
-                                   notifies,
-                                   num_notifies,
-                                   target_msc,
-                                   crtc_msc);
-    if (!vblank)
-        return BadAlloc;
-
-    vblank->event_id = ++present_wnmd_event_id;
-
-    /* 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, &xwl_present_window->exec_queue);
-    vblank->queued = TRUE;
-    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"));
-    }
-
-    present_wnmd_execute(vblank, ust, crtc_msc);
-    return Success;
-}
-
 
 static void
 xwl_present_release_pixmap(struct xwl_present_event *event)
@@ -702,7 +586,8 @@ static const struct wl_callback_listener xwl_present_sync_listener = {
 };
 
 static RRCrtcPtr
-xwl_present_get_crtc(WindowPtr present_window)
+xwl_present_get_crtc(present_screen_priv_ptr screen_priv,
+                     WindowPtr present_window)
 {
     struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(present_window);
     rrScrPrivPtr rr_private;
@@ -1133,6 +1018,116 @@ 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_pixmap(WindowPtr window,
+                    PixmapPtr pixmap,
+                    CARD32 serial,
+                    RegionPtr valid,
+                    RegionPtr update,
+                    int16_t x_off,
+                    int16_t y_off,
+                    RRCrtcPtr target_crtc,
+                    SyncFence *wait_fence,
+                    SyncFence *idle_fence,
+                    uint32_t options,
+                    uint64_t target_window_msc,
+                    uint64_t divisor,
+                    uint64_t remainder,
+                    present_notify_ptr notifies,
+                    int num_notifies)
+{
+    uint64_t                    ust = 0;
+    uint64_t                    target_msc;
+    uint64_t                    crtc_msc = 0;
+    int                         ret;
+    present_vblank_ptr          vblank, tmp;
+    ScreenPtr                   screen = window->drawable.pScreen;
+    struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
+    present_window_priv_ptr     window_priv = present_get_window_priv(window, TRUE);
+    present_screen_priv_ptr     screen_priv = present_screen_priv(screen);
+
+    if (!window_priv)
+        return BadAlloc;
+
+    target_crtc = xwl_present_get_crtc(screen_priv, window);
+
+    ret = present_wnmd_get_ust_msc(screen, window, &ust, &crtc_msc);
+
+    present_wnmd_update_window_crtc(window, target_crtc, crtc_msc);
+
+    if (ret == Success) {
+        /* Stash the current MSC away in case we need it later
+         */
+        window_priv->msc = crtc_msc;
+    }
+
+    target_msc = present_get_target_msc(target_window_msc + window_priv->msc_offset,
+                                        crtc_msc,
+                                        divisor,
+                                        remainder,
+                                        options);
+
+    /*
+     * Look for a matching presentation already on the list...
+     */
+
+    if (!update && pixmap) {
+        xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->vblank, window_list) {
+
+            if (!vblank->pixmap)
+                continue;
+
+            if (!vblank->queued)
+                continue;
+
+            if (vblank->target_msc != target_msc)
+                continue;
+
+            present_vblank_scrap(vblank);
+            if (vblank->flip_ready)
+                present_wnmd_re_execute(vblank);
+        }
+    }
+
+    vblank = present_vblank_create(window,
+                                   pixmap,
+                                   serial,
+                                   valid,
+                                   update,
+                                   x_off,
+                                   y_off,
+                                   target_crtc,
+                                   wait_fence,
+                                   idle_fence,
+                                   options,
+                                   XWL_PRESENT_CAPS,
+                                   notifies,
+                                   num_notifies,
+                                   target_msc,
+                                   crtc_msc);
+    if (!vblank)
+        return BadAlloc;
+
+    vblank->event_id = ++present_wnmd_event_id;
+
+    /* 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, &xwl_present_window->exec_queue);
+    vblank->queued = TRUE;
+    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"));
+    }
+
+    present_wnmd_execute(vblank, ust, crtc_msc);
+    return Success;
+}
+
 void
 xwl_present_unrealize_window(struct xwl_present_window *xwl_present_window)
 {
@@ -1145,7 +1140,6 @@ xwl_present_unrealize_window(struct xwl_present_window *xwl_present_window)
 
 static present_wnmd_info_rec xwl_present_info = {
     .version = PRESENT_SCREEN_INFO_VERSION,
-    .get_crtc = xwl_present_get_crtc,
 
     .get_ust_msc = xwl_present_get_ust_msc,
     .queue_vblank = xwl_present_queue_vblank,
@@ -1178,7 +1172,7 @@ xwl_present_init(ScreenPtr screen)
     screen_priv->wnmd_info = &xwl_present_info;
 
     screen_priv->query_capabilities = xwl_present_query_capabilities;
-    screen_priv->get_crtc = present_wnmd_get_crtc;
+    screen_priv->get_crtc = xwl_present_get_crtc;
 
     screen_priv->check_flip = xwl_present_check_flip;
     screen_priv->check_flip_window = present_wnmd_check_flip_window;
commit cb35ff596ec4e4fc6a4e96d55e280cdf399791e1
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Mon Apr 19 18:34:07 2021 +0200

    xwayland/present: Fold present_wnmd_check_flip into its callers
    
    Mainly into xwl_present_check_flip, and call that from
    present_wnmd_check_flip_window.
    
    No need for them to be separate anymore.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index fa47fbcda..c6bd93b06 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -360,113 +360,6 @@ present_wnmd_idle_notify(WindowPtr window, uint64_t event_id)
     }
 }
 
-static Bool
-present_wnmd_check_flip(RRCrtcPtr           crtc,
-                        WindowPtr           window,
-                        PixmapPtr           pixmap,
-                        Bool                sync_flip,
-                        RegionPtr           valid,
-                        int16_t             x_off,
-                        int16_t             y_off,
-                        PresentFlipReason   *reason)
-{
-    ScreenPtr               screen = window->drawable.pScreen;
-    present_screen_priv_ptr screen_priv = present_screen_priv(screen);
-    WindowPtr               toplvl_window = present_wnmd_toplvl_pixmap_window(window);
-
-    if (reason)
-        *reason = PRESENT_FLIP_REASON_UNKNOWN;
-
-    if (!screen_priv)
-        return FALSE;
-
-    if (!screen_priv->wnmd_info)
-        return FALSE;
-
-    if (!crtc)
-        return FALSE;
-
-    /* Check to see if the driver supports flips at all */
-    if (!screen_priv->wnmd_info->flip)
-        return FALSE;
-
-    /* Source pixmap must align with window exactly */
-    if (x_off || y_off)
-        return FALSE;
-
-    /* Valid area must contain window (for simplicity for now just never flip when one is set). */
-    if (valid)
-        return FALSE;
-
-    /* Flip pixmap must have same dimensions as window */
-    if (window->drawable.width != pixmap->drawable.width ||
-            window->drawable.height != pixmap->drawable.height)
-        return FALSE;
-
-    /* Window must be same region as toplevel window */
-    if ( !RegionEqual(&window->winSize, &toplvl_window->winSize) )
-        return FALSE;
-
-    /* Can't flip if window clipped by children */
-    if (!RegionEqual(&window->clipList, &window->winSize))
-        return FALSE;
-
-    /* Ask the driver for permission */
-    if (screen_priv->wnmd_info->check_flip2) {
-        if (!(*screen_priv->wnmd_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;
-        }
-    }
-
-    return TRUE;
-}
-
-/*
- * 'window' is being reconfigured. Check to see if it is involved
- * in flipping and clean up as necessary.
- */
-static void
-present_wnmd_check_flip_window (WindowPtr window)
-{
-    struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
-    present_window_priv_ptr window_priv = present_window_priv(window);
-    present_vblank_ptr      flip_pending;
-    present_vblank_ptr      flip_active;
-    present_vblank_ptr      vblank;
-    PresentFlipReason       reason;
-
-    /* If this window hasn't ever been used with Present, it can't be
-     * flipping
-     */
-    if (!xwl_present_window || !window_priv)
-        return;
-
-    flip_pending = xwl_present_window->flip_pending;
-    flip_active = xwl_present_window->flip_active;
-
-    if (flip_pending) {
-        if (!present_wnmd_check_flip(flip_pending->crtc, flip_pending->window, flip_pending->pixmap,
-                                flip_pending->sync_flip, flip_pending->valid, 0, 0, NULL))
-            xwl_present_window->flip_pending->abort_flip = TRUE;
-    } else if (flip_active) {
-        if (!present_wnmd_check_flip(flip_active->crtc, flip_active->window, flip_active->pixmap,
-                                     flip_active->sync_flip, flip_active->valid, 0, 0, NULL))
-            present_wnmd_flips_stop(window);
-    }
-
-    /* Now check any queued vblanks */
-    xorg_list_for_each_entry(vblank, &window_priv->vblank, window_list) {
-        if (vblank->queued && vblank->flip &&
-                !present_wnmd_check_flip(vblank->crtc, window, vblank->pixmap,
-                                         vblank->sync_flip, vblank->valid, 0, 0, &reason)) {
-            vblank->flip = FALSE;
-            vblank->reason = reason;
-        }
-    }
-}
-
 /*
  * Clean up any pending or current flips for this window
  */
@@ -931,18 +824,49 @@ xwl_present_flush(WindowPtr window)
 }
 
 static Bool
-xwl_present_check_flip2(RRCrtcPtr crtc,
-                        WindowPtr present_window,
-                        PixmapPtr pixmap,
-                        Bool sync_flip,
-                        PresentFlipReason *reason)
+xwl_present_check_flip(RRCrtcPtr crtc,
+                       WindowPtr present_window,
+                       PixmapPtr pixmap,
+                       Bool sync_flip,
+                       RegionPtr valid,
+                       int16_t x_off,
+                       int16_t y_off,
+                       PresentFlipReason *reason)
 {
+    WindowPtr toplvl_window = present_wnmd_toplvl_pixmap_window(present_window);
     struct xwl_window *xwl_window = xwl_window_from_window(present_window);
     ScreenPtr screen = pixmap->drawable.pScreen;
 
+    if (reason)
+        *reason = PRESENT_FLIP_REASON_UNKNOWN;
+
     if (!xwl_window)
         return FALSE;
 
+    if (!crtc)
+        return FALSE;
+
+    /* Source pixmap must align with window exactly */
+    if (x_off || y_off)
+        return FALSE;
+
+    /* Valid area must contain window (for simplicity for now just never flip when one is set). */
+    if (valid)
+        return FALSE;
+
+    /* Flip pixmap must have same dimensions as window */
+    if (present_window->drawable.width != pixmap->drawable.width ||
+            present_window->drawable.height != pixmap->drawable.height)
+        return FALSE;
+
+    /* Window must be same region as toplevel window */
+    if ( !RegionEqual(&present_window->winSize, &toplvl_window->winSize) )
+        return FALSE;
+
+    /* Can't flip if window clipped by children */
+    if (!RegionEqual(&present_window->clipList, &present_window->winSize))
+        return FALSE;
+
     if (!xwl_glamor_check_flip(pixmap))
         return FALSE;
 
@@ -964,6 +888,50 @@ xwl_present_check_flip2(RRCrtcPtr crtc,
     return TRUE;
 }
 
+/*
+ * 'window' is being reconfigured. Check to see if it is involved
+ * in flipping and clean up as necessary.
+ */
+static void
+present_wnmd_check_flip_window (WindowPtr window)
+{
+    struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
+    present_window_priv_ptr window_priv = present_window_priv(window);
+    present_vblank_ptr      flip_pending;
+    present_vblank_ptr      flip_active;
+    present_vblank_ptr      vblank;
+    PresentFlipReason       reason;
+
+    /* If this window hasn't ever been used with Present, it can't be
+     * flipping
+     */
+    if (!xwl_present_window || !window_priv)
+        return;
+
+    flip_pending = xwl_present_window->flip_pending;
+    flip_active = xwl_present_window->flip_active;
+
+    if (flip_pending) {
+        if (!xwl_present_check_flip(flip_pending->crtc, flip_pending->window, flip_pending->pixmap,
+                                    flip_pending->sync_flip, flip_pending->valid, 0, 0, NULL))
+            xwl_present_window->flip_pending->abort_flip = TRUE;
+    } else if (flip_active) {
+        if (!xwl_present_check_flip(flip_active->crtc, flip_active->window, flip_active->pixmap,
+                                    flip_active->sync_flip, flip_active->valid, 0, 0, NULL))
+            present_wnmd_flips_stop(window);
+    }
+
+    /* Now check any queued vblanks */
+    xorg_list_for_each_entry(vblank, &window_priv->vblank, window_list) {
+        if (vblank->queued && vblank->flip &&
+                !xwl_present_check_flip(vblank->crtc, window, vblank->pixmap,
+                                        vblank->sync_flip, vblank->valid, 0, 0, &reason)) {
+            vblank->flip = FALSE;
+            vblank->reason = reason;
+        }
+    }
+}
+
 static Bool
 xwl_present_flip(WindowPtr present_window,
                  RRCrtcPtr crtc,
@@ -1182,7 +1150,6 @@ static present_wnmd_info_rec xwl_present_info = {
     .get_ust_msc = xwl_present_get_ust_msc,
     .queue_vblank = xwl_present_queue_vblank,
 
-    .check_flip2 = xwl_present_check_flip2,
     .flips_stop = xwl_present_flips_stop
 };
 
@@ -1213,7 +1180,7 @@ xwl_present_init(ScreenPtr screen)
     screen_priv->query_capabilities = xwl_present_query_capabilities;
     screen_priv->get_crtc = present_wnmd_get_crtc;
 
-    screen_priv->check_flip = present_wnmd_check_flip;
+    screen_priv->check_flip = xwl_present_check_flip;
     screen_priv->check_flip_window = present_wnmd_check_flip_window;
     screen_priv->clear_window_flip = present_wnmd_clear_window_flip;
 
commit 7b78cf6b3ae386b9df2483692041dfa38a91bedb
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Mon Apr 19 18:26:55 2021 +0200

    xwayland/present: Simplify query_capabilities
    
    No need for the WNMD indirection anymore.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 6adff2a60..fa47fbcda 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -34,6 +34,10 @@
 #include "xwayland-pixmap.h"
 #include "glamor.h"
 
+
+#define XWL_PRESENT_CAPS PresentCapabilityAsync
+
+
 /*
  * When not flipping let Present copy with 60fps.
  * When flipping wait on frame_callback, otherwise
@@ -138,9 +142,9 @@ present_wnmd_queue_vblank(ScreenPtr screen,
 }
 
 static uint32_t
-present_wnmd_query_capabilities(present_screen_priv_ptr screen_priv)
+xwl_present_query_capabilities(present_screen_priv_ptr screen_priv)
 {
-    return screen_priv->wnmd_info->capabilities;
+    return XWL_PRESENT_CAPS;
 }
 
 static RRCrtcPtr
@@ -607,7 +611,7 @@ present_wnmd_pixmap(WindowPtr window,
                                    wait_fence,
                                    idle_fence,
                                    options,
-                                   screen_priv->wnmd_info->capabilities,
+                                   XWL_PRESENT_CAPS,
                                    notifies,
                                    num_notifies,
                                    target_msc,
@@ -1178,7 +1182,6 @@ static present_wnmd_info_rec xwl_present_info = {
     .get_ust_msc = xwl_present_get_ust_msc,
     .queue_vblank = xwl_present_queue_vblank,
 
-    .capabilities = PresentCapabilityAsync,
     .check_flip2 = xwl_present_check_flip2,
     .flips_stop = xwl_present_flips_stop
 };
@@ -1207,7 +1210,7 @@ xwl_present_init(ScreenPtr screen)
 
     screen_priv->wnmd_info = &xwl_present_info;
 
-    screen_priv->query_capabilities = present_wnmd_query_capabilities;
+    screen_priv->query_capabilities = xwl_present_query_capabilities;
     screen_priv->get_crtc = present_wnmd_get_crtc;
 
     screen_priv->check_flip = present_wnmd_check_flip;
commit 244403ec8718d782d57a830ece9357a75a0dd70b
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Mon Apr 19 18:01:52 2021 +0200

    xwayland/present: Fold present_wnmd_abort_vblank into its only caller
    
    No need for them to be separate anymore.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index b24dff9a2..6adff2a60 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -635,31 +635,6 @@ present_wnmd_pixmap(WindowPtr window,
     return Success;
 }
 
-static void
-present_wnmd_abort_vblank(ScreenPtr screen, WindowPtr window, RRCrtcPtr crtc, uint64_t event_id, uint64_t msc)
-{
-    struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
-    present_screen_priv_ptr screen_priv = present_screen_priv(screen);
-    present_vblank_ptr      vblank;
-
-    (*screen_priv->wnmd_info->abort_vblank) (window, crtc, event_id, msc);
-
-    xorg_list_for_each_entry(vblank, &xwl_present_window->exec_queue, event_queue) {
-        if (vblank->event_id == event_id) {
-            xorg_list_del(&vblank->event_queue);
-            vblank->queued = FALSE;
-            return;
-        }
-    }
-    xorg_list_for_each_entry(vblank, &xwl_present_window->flip_queue, event_queue) {
-        if (vblank->event_id == event_id) {
-            xorg_list_del(&vblank->event_queue);
-            vblank->queued = FALSE;
-            return;
-        }
-    }
-}
-
 
 static void
 xwl_present_release_pixmap(struct xwl_present_event *event)
@@ -903,27 +878,43 @@ xwl_present_queue_vblank(WindowPtr present_window,
  * to the extension
  */
 static void
-xwl_present_abort_vblank(WindowPtr present_window,
+xwl_present_abort_vblank(ScreenPtr screen,
+                         WindowPtr present_window,
                          RRCrtcPtr crtc,
                          uint64_t event_id,
                          uint64_t msc)
 {
     struct xwl_present_window *xwl_present_window = xwl_present_window_priv(present_window);
     struct xwl_present_event *event, *tmp;
+    present_vblank_ptr vblank;
 
-    if (!xwl_present_window)
-        return;
+    if (xwl_present_window) {
+        xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->wait_list, list) {
+            if (event->event_id == event_id) {
+                xwl_present_free_event(event);
+                break;
+            }
+        }
 
-    xorg_list_for_each_entry_safe(event, tmp, &xwl_present_window->wait_list, list) {
-        if (event->event_id == event_id) {
-            xwl_present_free_event(event);
-            return;
+        xorg_list_for_each_entry(event, &xwl_present_window->release_list, list) {
+            if (event->event_id == event_id) {
+                event->abort = TRUE;
+                break;
+            }
         }
     }
 
-    xorg_list_for_each_entry(event, &xwl_present_window->release_list, list) {
-        if (event->event_id == event_id) {
-            event->abort = TRUE;
+    xorg_list_for_each_entry(vblank, &xwl_present_window->exec_queue, event_queue) {
+        if (vblank->event_id == event_id) {
+            xorg_list_del(&vblank->event_queue);
+            vblank->queued = FALSE;
+            return;
+        }
+    }
+    xorg_list_for_each_entry(vblank, &xwl_present_window->flip_queue, event_queue) {
+        if (vblank->event_id == event_id) {
+            xorg_list_del(&vblank->event_queue);
+            vblank->queued = FALSE;
             return;
         }
     }
@@ -1186,7 +1177,6 @@ static present_wnmd_info_rec xwl_present_info = {
 
     .get_ust_msc = xwl_present_get_ust_msc,
     .queue_vblank = xwl_present_queue_vblank,
-    .abort_vblank = xwl_present_abort_vblank,
 
     .capabilities = PresentCapabilityAsync,
     .check_flip2 = xwl_present_check_flip2,
@@ -1229,7 +1219,7 @@ xwl_present_init(ScreenPtr screen)
     screen_priv->flush = xwl_present_flush;
     screen_priv->re_execute = present_wnmd_re_execute;
 
-    screen_priv->abort_vblank = present_wnmd_abort_vblank;
+    screen_priv->abort_vblank = xwl_present_abort_vblank;
 
     return TRUE;
 }
commit f7adbc2166b7a4662cbd69507d8cbac11034c87e
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Mon Apr 19 18:06:22 2021 +0200

    xwayland/present: Drop present_wnmd_flush in favour of xwl_present_flush
    
    No need for the indirection anymore.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 396599336..b24dff9a2 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -660,15 +660,6 @@ present_wnmd_abort_vblank(ScreenPtr screen, WindowPtr window, RRCrtcPtr crtc, ui
     }
 }
 
-static void
-present_wnmd_flush(WindowPtr window)
-{
-    ScreenPtr               screen = window->drawable.pScreen;
-    present_screen_priv_ptr screen_priv = present_screen_priv(screen);
-
-    (*screen_priv->wnmd_info->flush) (window);
-}
-
 
 static void
 xwl_present_release_pixmap(struct xwl_present_event *event)
@@ -1197,8 +1188,6 @@ static present_wnmd_info_rec xwl_present_info = {
     .queue_vblank = xwl_present_queue_vblank,
     .abort_vblank = xwl_present_abort_vblank,
 
-    .flush = xwl_present_flush,
-
     .capabilities = PresentCapabilityAsync,
     .check_flip2 = xwl_present_check_flip2,
     .flips_stop = xwl_present_flips_stop
@@ -1237,7 +1226,7 @@ xwl_present_init(ScreenPtr screen)
 
     screen_priv->present_pixmap = present_wnmd_pixmap;
     screen_priv->queue_vblank = present_wnmd_queue_vblank;
-    screen_priv->flush = present_wnmd_flush;
+    screen_priv->flush = xwl_present_flush;
     screen_priv->re_execute = present_wnmd_re_execute;
 
     screen_priv->abort_vblank = present_wnmd_abort_vblank;
commit 7fd114365d694360540bc46cd615aa47373be0a8
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Mon Apr 19 19:02:32 2021 +0200

    xwayland/present: Fold present_wnmd_flip into present_wnmd_execute
    
    No need for the indirection anymore.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 8ac5cfad8..396599336 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -490,27 +490,6 @@ present_wnmd_clear_window_flip(WindowPtr window)
     xwl_present_window->flip_active = NULL;
 }
 
-static Bool
-present_wnmd_flip(WindowPtr window,
-                  RRCrtcPtr crtc,
-                  uint64_t event_id,
-                  uint64_t target_msc,
-                  PixmapPtr pixmap,
-                  Bool sync_flip,
-                  RegionPtr damage)
-{
-    ScreenPtr                   screen = window->drawable.pScreen;
-    present_screen_priv_ptr     screen_priv = present_screen_priv(screen);
-
-    return (*screen_priv->wnmd_info->flip) (window,
-                                            crtc,
-                                            event_id,
-                                            target_msc,
-                                            pixmap,
-                                            sync_flip,
-                                            damage);
-}
-
 static void
 present_wnmd_cancel_flip(WindowPtr window)
 {
@@ -522,116 +501,6 @@ present_wnmd_cancel_flip(WindowPtr window)
         present_wnmd_flips_stop(window);
 }
 
-/*
- * Once the required MSC has been reached, execute the pending request.
- *
- * For requests to actually present something, either blt contents to
- * the window pixmap or queue a window buffer swap on the backend.
- *
- * For requests to just get the current MSC/UST combo, skip that part and
- * go straight to event delivery.
- */
-static void
-present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
-{
-    WindowPtr               window = vblank->window;
-    struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
-    present_window_priv_ptr window_priv = present_window_priv(window);
-
-    if (present_execute_wait(vblank, crtc_msc))
-        return;
-
-    if (vblank->flip && vblank->pixmap && vblank->window) {
-        if (xwl_present_window->flip_pending) {
-            DebugPresent(("\tr %" PRIu64 " %p (pending %p)\n",
-                          vblank->event_id, vblank,
-                          xwl_present_window->flip_pending));
-            xorg_list_del(&vblank->event_queue);
-            xorg_list_append(&vblank->event_queue, &xwl_present_window->flip_queue);
-            vblank->flip_ready = TRUE;
-            return;
-        }
-    }
-
-    xorg_list_del(&vblank->event_queue);
-    xorg_list_del(&vblank->window_list);
-    vblank->queued = FALSE;
-
-    if (vblank->pixmap && vblank->window) {
-        ScreenPtr screen = window->drawable.pScreen;
-
-        if (vblank->flip) {
-            RegionPtr damage;
-
-            DebugPresent(("\tf %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
-                          vblank->event_id, vblank, crtc_msc,
-                          vblank->pixmap->drawable.id, vblank->window->drawable.id));
-
-            /* Prepare to flip by placing it in the flip queue
-             */
-            xorg_list_add(&vblank->event_queue, &xwl_present_window->flip_queue);
-
-            /* Set update region as damaged */
-            if (vblank->update) {
-                damage = RegionDuplicate(vblank->update);
-                /* Translate update region to screen space */
-                assert(vblank->x_off == 0 && vblank->y_off == 0);
-                RegionTranslate(damage, window->drawable.x, window->drawable.y);
-                RegionIntersect(damage, damage, &window->clipList);
-            } else
-                damage = RegionDuplicate(&window->clipList);
-
-            /* Try to flip - the vblank is now pending
-             */
-            xwl_present_window->flip_pending = vblank;
-            // ask the driver
-            if (present_wnmd_flip(vblank->window, vblank->crtc, vblank->event_id,
-                                     vblank->target_msc, vblank->pixmap, vblank->sync_flip, damage)) {
-                WindowPtr toplvl_window = present_wnmd_toplvl_pixmap_window(vblank->window);
-                PixmapPtr old_pixmap = screen->GetWindowPixmap(window);
-
-                /* Replace window pixmap with flip pixmap */
-#ifdef COMPOSITE
-                vblank->pixmap->screen_x = old_pixmap->screen_x;
-                vblank->pixmap->screen_y = old_pixmap->screen_y;
-#endif
-                present_set_tree_pixmap(toplvl_window, old_pixmap, vblank->pixmap);
-                vblank->pixmap->refcnt++;
-                dixDestroyPixmap(old_pixmap, old_pixmap->drawable.id);
-
-                /* Report damage */
-                DamageDamageRegion(&vblank->window->drawable, damage);
-                RegionDestroy(damage);
-                return;
-            }
-
-            xorg_list_del(&vblank->event_queue);
-            /* Flip failed. Clear the flip_pending field
-              */
-            xwl_present_window->flip_pending = NULL;
-            vblank->flip = FALSE;
-        }
-        DebugPresent(("\tc %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
-                      vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id));
-
-        present_wnmd_cancel_flip(window);
-
-        present_execute_copy(vblank, crtc_msc);
-        assert(!vblank->queued);
-
-        if (present_wnmd_queue_vblank(screen, window, vblank->crtc,
-                                      vblank->event_id, crtc_msc + 1)
-            == Success) {
-            xorg_list_add(&vblank->event_queue, &xwl_present_window->idle_queue);
-            xorg_list_append(&vblank->window_list, &window_priv->vblank);
-
-            return;
-        }
-    }
-
-    present_execute_post(vblank, ust, crtc_msc);
-}
-
 static void
 present_wnmd_update_window_crtc(WindowPtr window, RRCrtcPtr crtc, uint64_t new_msc)
 {
@@ -1201,6 +1070,115 @@ xwl_present_flips_stop(WindowPtr window)
     xwl_present_reset_timer(xwl_present_window);
 }
 
+/*
+ * Once the required MSC has been reached, execute the pending request.
+ *
+ * For requests to actually present something, either blt contents to
+ * the window pixmap or queue a window buffer swap on the backend.
+ *
+ * For requests to just get the current MSC/UST combo, skip that part and
+ * go straight to event delivery.
+ */
+static void
+present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
+{
+    WindowPtr               window = vblank->window;
+    struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
+    present_window_priv_ptr window_priv = present_window_priv(window);
+
+    if (present_execute_wait(vblank, crtc_msc))
+        return;
+
+    if (vblank->flip && vblank->pixmap && vblank->window) {
+        if (xwl_present_window->flip_pending) {
+            DebugPresent(("\tr %" PRIu64 " %p (pending %p)\n",
+                          vblank->event_id, vblank,
+                          xwl_present_window->flip_pending));
+            xorg_list_del(&vblank->event_queue);
+            xorg_list_append(&vblank->event_queue, &xwl_present_window->flip_queue);
+            vblank->flip_ready = TRUE;
+            return;
+        }
+    }
+
+    xorg_list_del(&vblank->event_queue);
+    xorg_list_del(&vblank->window_list);
+    vblank->queued = FALSE;
+
+    if (vblank->pixmap && vblank->window) {
+        ScreenPtr screen = window->drawable.pScreen;
+
+        if (vblank->flip) {
+            RegionPtr damage;
+
+            DebugPresent(("\tf %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
+                          vblank->event_id, vblank, crtc_msc,
+                          vblank->pixmap->drawable.id, vblank->window->drawable.id));
+
+            /* Prepare to flip by placing it in the flip queue
+             */
+            xorg_list_add(&vblank->event_queue, &xwl_present_window->flip_queue);
+
+            /* Set update region as damaged */
+            if (vblank->update) {
+                damage = RegionDuplicate(vblank->update);
+                /* Translate update region to screen space */
+                assert(vblank->x_off == 0 && vblank->y_off == 0);
+                RegionTranslate(damage, window->drawable.x, window->drawable.y);
+                RegionIntersect(damage, damage, &window->clipList);
+            } else
+                damage = RegionDuplicate(&window->clipList);
+
+            /* Try to flip - the vblank is now pending
+             */
+            xwl_present_window->flip_pending = vblank;
+            if (xwl_present_flip(vblank->window, vblank->crtc, vblank->event_id,
+                                 vblank->target_msc, vblank->pixmap, vblank->sync_flip, damage)) {
+                WindowPtr toplvl_window = present_wnmd_toplvl_pixmap_window(vblank->window);
+                PixmapPtr old_pixmap = screen->GetWindowPixmap(window);
+
+                /* Replace window pixmap with flip pixmap */
+#ifdef COMPOSITE
+                vblank->pixmap->screen_x = old_pixmap->screen_x;
+                vblank->pixmap->screen_y = old_pixmap->screen_y;
+#endif
+                present_set_tree_pixmap(toplvl_window, old_pixmap, vblank->pixmap);
+                vblank->pixmap->refcnt++;
+                dixDestroyPixmap(old_pixmap, old_pixmap->drawable.id);
+
+                /* Report damage */
+                DamageDamageRegion(&vblank->window->drawable, damage);
+                RegionDestroy(damage);
+                return;
+            }
+
+            xorg_list_del(&vblank->event_queue);
+            /* Flip failed. Clear the flip_pending field
+              */
+            xwl_present_window->flip_pending = NULL;
+            vblank->flip = FALSE;
+        }
+        DebugPresent(("\tc %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
+                      vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id));
+
+        present_wnmd_cancel_flip(window);
+
+        present_execute_copy(vblank, crtc_msc);
+        assert(!vblank->queued);
+
+        if (present_wnmd_queue_vblank(screen, window, vblank->crtc,
+                                      vblank->event_id, crtc_msc + 1)
+            == Success) {
+            xorg_list_add(&vblank->event_queue, &xwl_present_window->idle_queue);
+            xorg_list_append(&vblank->window_list, &window_priv->vblank);
+
+            return;
+        }
+    }
+
+    present_execute_post(vblank, ust, crtc_msc);
+}
+
 void
 xwl_present_unrealize_window(struct xwl_present_window *xwl_present_window)
 {
@@ -1223,7 +1201,6 @@ static present_wnmd_info_rec xwl_present_info = {
 
     .capabilities = PresentCapabilityAsync,
     .check_flip2 = xwl_present_check_flip2,
-    .flip = xwl_present_flip,
     .flips_stop = xwl_present_flips_stop
 };
 
commit 2e1dcd731f98a8beceee699cc57b7082f98916c4
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Tue Apr 20 19:01:12 2021 +0200

    xwayland/present: Fold present_wnmd_screen_init into xwl_present_init
    
    No need for them to be separate anymore.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index ca0de1516..8ac5cfad8 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -800,43 +800,6 @@ present_wnmd_flush(WindowPtr window)
     (*screen_priv->wnmd_info->flush) (window);
 }
 
-/*
- * Initialize a screen for use with present in window flip mode (wnmd)
- */
-static int
-present_wnmd_screen_init(ScreenPtr screen, present_wnmd_info_ptr info)
-{
-    present_screen_priv_ptr screen_priv;
-
-    if (!present_screen_register_priv_keys())
-        return FALSE;
-
-    if (present_screen_priv(screen))
-        return TRUE;
-
-    screen_priv = present_screen_priv_init(screen);
-    if (!screen_priv)
-        return FALSE;
-
-    screen_priv->wnmd_info = info;
-
-    screen_priv->query_capabilities =   &present_wnmd_query_capabilities;
-    screen_priv->get_crtc           =   &present_wnmd_get_crtc;
-
-    screen_priv->check_flip         =   &present_wnmd_check_flip;
-    screen_priv->check_flip_window  =   &present_wnmd_check_flip_window;
-    screen_priv->clear_window_flip  =   &present_wnmd_clear_window_flip;
-
-    screen_priv->present_pixmap     =   &present_wnmd_pixmap;
-    screen_priv->queue_vblank       =   &present_wnmd_queue_vblank;
-    screen_priv->flush              =   &present_wnmd_flush;
-    screen_priv->re_execute         =   &present_wnmd_re_execute;
-
-    screen_priv->abort_vblank       =   &present_wnmd_abort_vblank;
-
-    return TRUE;
-}
-
 
 static void
 xwl_present_release_pixmap(struct xwl_present_event *event)
@@ -1268,12 +1231,39 @@ Bool
 xwl_present_init(ScreenPtr screen)
 {
     struct xwl_screen *xwl_screen = xwl_screen_get(screen);
+    present_screen_priv_ptr screen_priv;
 
     if (!xwl_screen->glamor || !xwl_screen->egl_backend)
         return FALSE;
 
+    if (!present_screen_register_priv_keys())
+        return FALSE;
+
+    if (present_screen_priv(screen))
+        return TRUE;
+
+    screen_priv = present_screen_priv_init(screen);
+    if (!screen_priv)
+        return FALSE;
+
     if (!dixRegisterPrivateKey(&xwl_present_window_private_key, PRIVATE_WINDOW, 0))
         return FALSE;
 
-    return present_wnmd_screen_init(screen, &xwl_present_info);
+    screen_priv->wnmd_info = &xwl_present_info;
+
+    screen_priv->query_capabilities = present_wnmd_query_capabilities;
+    screen_priv->get_crtc = present_wnmd_get_crtc;
+
+    screen_priv->check_flip = present_wnmd_check_flip;
+    screen_priv->check_flip_window = present_wnmd_check_flip_window;
+    screen_priv->clear_window_flip = present_wnmd_clear_window_flip;
+
+    screen_priv->present_pixmap = present_wnmd_pixmap;
+    screen_priv->queue_vblank = present_wnmd_queue_vblank;
+    screen_priv->flush = present_wnmd_flush;
+    screen_priv->re_execute = present_wnmd_re_execute;
+
+    screen_priv->abort_vblank = present_wnmd_abort_vblank;
+
+    return TRUE;
 }
commit b6419359b6b11ec659f59cc74075fcf049591425
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Wed Apr 21 12:50:02 2021 +0200

    present: Move present_wnmd.c contents to hw/xwayland/xwayland-present.c
    
    This will allow eliminating indirections and making the Xwayland Present
    code more efficient and easier to follow.
    
    While this technically changes the Xorg video driver ABI, I don't know
    of any drivers using the dropped present_wnmd_* symbols, and I doubt a
    Xorg driver could make use of them as is anyway.
    
    (As a bonus, Xorg no longer links any Xwayland specific Present code)
    
    v2:
    * Wrap DestroyWindow before initializing Present, so that
      present_destroy_window runs before xwl_present_cleanup. Avoids crash
      due to present_destroy_window calling xwl_present_* functions when
      xwl_present_window was already freed. (Olivier Fourdan)
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 83d67517a..ca0de1516 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -43,6 +43,8 @@
 #define TIMER_LEN_COPY      17  // ~60fps
 #define TIMER_LEN_FLIP    1000  // 1fps
 
+static uint64_t present_wnmd_event_id;
+
 static DevPrivateKeyRec xwl_present_window_private_key;
 
 static struct xwl_present_window *
@@ -69,6 +71,9 @@ xwl_present_window_get_priv(WindowPtr window)
         xorg_list_init(&xwl_present_window->frame_callback_list);
         xorg_list_init(&xwl_present_window->wait_list);
         xorg_list_init(&xwl_present_window->release_list);
+        xorg_list_init(&xwl_present_window->exec_queue);
+        xorg_list_init(&xwl_present_window->flip_queue);
+        xorg_list_init(&xwl_present_window->idle_queue);
 
         dixSetPrivate(&window->devPrivates,
                       &xwl_present_window_private_key,
@@ -117,6 +122,722 @@ xwl_present_reset_timer(struct xwl_present_window *xwl_present_window)
     }
 }
 
+
+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 uint32_t
+present_wnmd_query_capabilities(present_screen_priv_ptr screen_priv)
+{
+    return screen_priv->wnmd_info->capabilities;
+}
+
+static RRCrtcPtr
+present_wnmd_get_crtc(present_screen_priv_ptr screen_priv, WindowPtr window)
+{
+    return (*screen_priv->wnmd_info->get_crtc)(window);
+}
+
+static int
+present_wnmd_get_ust_msc(ScreenPtr screen, WindowPtr window, uint64_t *ust, uint64_t *msc)
+{
+    present_screen_priv_ptr screen_priv = present_screen_priv(screen);
+    return (*screen_priv->wnmd_info->get_ust_msc)(window, ust, msc);
+}
+
+/*
+ * When the wait fence or previous flip is completed, it's time
+ * to re-try the request
+ */
+static void
+present_wnmd_re_execute(present_vblank_ptr vblank)
+{
+    uint64_t ust = 0, crtc_msc = 0;
+
+    (void) present_wnmd_get_ust_msc(vblank->screen, vblank->window, &ust, &crtc_msc);
+    present_wnmd_execute(vblank, ust, crtc_msc);
+}
+
+static void
+present_wnmd_flip_try_ready(WindowPtr window)
+{
+    struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
+    present_vblank_ptr      vblank;
+
+    xorg_list_for_each_entry(vblank, &xwl_present_window->flip_queue, event_queue) {
+        if (vblank->queued) {
+            present_wnmd_re_execute(vblank);
+            return;
+        }
+    }
+}
+
+static void
+present_wnmd_free_idle_vblank(present_vblank_ptr vblank)
+{
+    present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
+    present_vblank_destroy(vblank);
+}
+
+/*
+ * Free any left over idle vblanks
+ */
+static void
+present_wnmd_free_idle_vblanks(WindowPtr window)
+{
+    struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
+    present_vblank_ptr              vblank, tmp;
+
+    xorg_list_for_each_entry_safe(vblank, tmp, &xwl_present_window->idle_queue, event_queue) {
+        present_wnmd_free_idle_vblank(vblank);
+    }
+
+    if (xwl_present_window->flip_active) {
+        present_wnmd_free_idle_vblank(xwl_present_window->flip_active);
+        xwl_present_window->flip_active = NULL;
+    }
+}
+
+static WindowPtr
+present_wnmd_toplvl_pixmap_window(WindowPtr window)
+{
+    ScreenPtr       screen = window->drawable.pScreen;
+    PixmapPtr       pixmap = (*screen->GetWindowPixmap)(window);
+    WindowPtr       w = window;
+    WindowPtr       next_w;
+
+    while(w->parent) {
+        next_w = w->parent;
+        if ( (*screen->GetWindowPixmap)(next_w) != pixmap) {
+            break;
+        }
+        w = next_w;
+    }
+    return w;
+}
+
+static void
+present_wnmd_flips_stop(WindowPtr window)
+{
+    struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
+    present_screen_priv_ptr screen_priv = present_screen_priv(window->drawable.pScreen);
+
+    assert (!xwl_present_window->flip_pending);
+
+    (*screen_priv->wnmd_info->flips_stop) (window);
+
+    present_wnmd_free_idle_vblanks(window);
+    present_wnmd_flip_try_ready(window);
+}
+
+static void
+present_wnmd_flip_notify_vblank(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
+{
+    WindowPtr                   window = vblank->window;
+    struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
+
+    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));
+
+    assert (vblank == xwl_present_window->flip_pending);
+
+    xorg_list_del(&vblank->event_queue);
+
+    if (xwl_present_window->flip_active) {
+        if (xwl_present_window->flip_active->flip_idler)
+            present_wnmd_free_idle_vblank(xwl_present_window->flip_active);
+        else
+            /* Put the previous flip in the idle_queue and wait for further notice from
+             * the Wayland compositor
+             */
+            xorg_list_append(&xwl_present_window->flip_active->event_queue, &xwl_present_window->idle_queue);
+    }
+
+    xwl_present_window->flip_active = vblank;
+    xwl_present_window->flip_pending = NULL;
+
+    present_vblank_notify(vblank, PresentCompleteKindPixmap, PresentCompleteModeFlip, ust, crtc_msc);
+
+    if (vblank->abort_flip)
+        present_wnmd_flips_stop(window);
+
+    present_wnmd_flip_try_ready(window);
+}
+
+static void
+present_wnmd_event_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uint64_t msc)
+{
+    struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
+    present_window_priv_ptr     window_priv = present_window_priv(window);
+    present_vblank_ptr          vblank;
+
+    if (!window_priv)
+        return;
+    if (!event_id)
+        return;
+
+    DebugPresent(("\te %" PRIu64 " ust %" PRIu64 " msc %" PRIu64 "\n", event_id, ust, msc));
+    xorg_list_for_each_entry(vblank, &xwl_present_window->exec_queue, event_queue) {
+        if (event_id == vblank->event_id) {
+            present_wnmd_execute(vblank, ust, msc);
+            return;
+        }
+    }
+    xorg_list_for_each_entry(vblank, &xwl_present_window->flip_queue, event_queue) {
+        if (vblank->event_id == event_id) {
+            assert(vblank->queued);
+            present_wnmd_execute(vblank, ust, msc);
+            return;
+        }
+    }
+
+    /* Copies which were executed but need their completion event sent */
+    xorg_list_for_each_entry(vblank, &xwl_present_window->idle_queue, event_queue) {
+        if (vblank->event_id == event_id) {
+            present_execute_post(vblank, ust, msc);
+            return;
+        }
+    }
+}
+
+static void
+present_wnmd_flip_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uint64_t msc)
+{
+    struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
+    present_vblank_ptr          vblank;
+
+    xorg_list_for_each_entry(vblank, &xwl_present_window->flip_queue, event_queue) {
+        if (vblank->event_id == event_id) {
+            assert(!vblank->queued);
+            assert(vblank->window);
+            present_wnmd_flip_notify_vblank(vblank, ust, msc);
+            return;
+        }
+    }
+}
+
+static void
+present_wnmd_idle_notify(WindowPtr window, uint64_t event_id)
+{
+    struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
+    present_vblank_ptr          vblank;
+
+    if (xwl_present_window->flip_active && xwl_present_window->flip_active->event_id == event_id) {
+        /* Active flip is allowed to become idle directly when it becomes unactive again. */
+        xwl_present_window->flip_active->flip_idler = TRUE;
+        return;
+    }
+
+    xorg_list_for_each_entry(vblank, &xwl_present_window->idle_queue, event_queue) {
+        if (vblank->event_id == event_id) {
+            present_wnmd_free_idle_vblank(vblank);
+            return;
+        }
+    }
+
+    xorg_list_for_each_entry(vblank, &xwl_present_window->flip_queue, event_queue) {
+        if (vblank->event_id == event_id) {
+            vblank->flip_idler = TRUE;
+            return;
+        }
+    }
+}
+
+static Bool
+present_wnmd_check_flip(RRCrtcPtr           crtc,
+                        WindowPtr           window,
+                        PixmapPtr           pixmap,
+                        Bool                sync_flip,
+                        RegionPtr           valid,
+                        int16_t             x_off,
+                        int16_t             y_off,
+                        PresentFlipReason   *reason)
+{
+    ScreenPtr               screen = window->drawable.pScreen;
+    present_screen_priv_ptr screen_priv = present_screen_priv(screen);
+    WindowPtr               toplvl_window = present_wnmd_toplvl_pixmap_window(window);
+
+    if (reason)
+        *reason = PRESENT_FLIP_REASON_UNKNOWN;
+
+    if (!screen_priv)
+        return FALSE;
+
+    if (!screen_priv->wnmd_info)
+        return FALSE;
+
+    if (!crtc)
+        return FALSE;
+
+    /* Check to see if the driver supports flips at all */
+    if (!screen_priv->wnmd_info->flip)
+        return FALSE;
+
+    /* Source pixmap must align with window exactly */
+    if (x_off || y_off)
+        return FALSE;
+
+    /* Valid area must contain window (for simplicity for now just never flip when one is set). */
+    if (valid)
+        return FALSE;
+
+    /* Flip pixmap must have same dimensions as window */
+    if (window->drawable.width != pixmap->drawable.width ||
+            window->drawable.height != pixmap->drawable.height)
+        return FALSE;
+
+    /* Window must be same region as toplevel window */
+    if ( !RegionEqual(&window->winSize, &toplvl_window->winSize) )
+        return FALSE;
+
+    /* Can't flip if window clipped by children */
+    if (!RegionEqual(&window->clipList, &window->winSize))
+        return FALSE;
+
+    /* Ask the driver for permission */
+    if (screen_priv->wnmd_info->check_flip2) {
+        if (!(*screen_priv->wnmd_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;
+        }
+    }
+
+    return TRUE;
+}
+
+/*
+ * 'window' is being reconfigured. Check to see if it is involved
+ * in flipping and clean up as necessary.
+ */
+static void
+present_wnmd_check_flip_window (WindowPtr window)
+{
+    struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
+    present_window_priv_ptr window_priv = present_window_priv(window);
+    present_vblank_ptr      flip_pending;
+    present_vblank_ptr      flip_active;
+    present_vblank_ptr      vblank;
+    PresentFlipReason       reason;
+
+    /* If this window hasn't ever been used with Present, it can't be
+     * flipping
+     */
+    if (!xwl_present_window || !window_priv)
+        return;
+
+    flip_pending = xwl_present_window->flip_pending;
+    flip_active = xwl_present_window->flip_active;
+
+    if (flip_pending) {
+        if (!present_wnmd_check_flip(flip_pending->crtc, flip_pending->window, flip_pending->pixmap,
+                                flip_pending->sync_flip, flip_pending->valid, 0, 0, NULL))
+            xwl_present_window->flip_pending->abort_flip = TRUE;
+    } else if (flip_active) {
+        if (!present_wnmd_check_flip(flip_active->crtc, flip_active->window, flip_active->pixmap,
+                                     flip_active->sync_flip, flip_active->valid, 0, 0, NULL))
+            present_wnmd_flips_stop(window);
+    }
+
+    /* Now check any queued vblanks */
+    xorg_list_for_each_entry(vblank, &window_priv->vblank, window_list) {
+        if (vblank->queued && vblank->flip &&
+                !present_wnmd_check_flip(vblank->crtc, window, vblank->pixmap,
+                                         vblank->sync_flip, vblank->valid, 0, 0, &reason)) {
+            vblank->flip = FALSE;
+            vblank->reason = reason;
+        }
+    }
+}
+
+/*
+ * Clean up any pending or current flips for this window
+ */
+static void
+present_wnmd_clear_window_flip(WindowPtr window)
+{
+    struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
+    present_vblank_ptr          vblank, tmp;
+
+    xorg_list_for_each_entry_safe(vblank, tmp, &xwl_present_window->flip_queue, event_queue) {
+        present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
+        present_vblank_destroy(vblank);
+    }
+
+    xorg_list_for_each_entry_safe(vblank, tmp, &xwl_present_window->idle_queue, event_queue) {
+        present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
+        present_vblank_destroy(vblank);
+    }
+
+    vblank = xwl_present_window->flip_active;
+    if (vblank) {
+        present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
+        present_vblank_destroy(vblank);
+    }
+    xwl_present_window->flip_active = NULL;
+}
+
+static Bool
+present_wnmd_flip(WindowPtr window,
+                  RRCrtcPtr crtc,
+                  uint64_t event_id,
+                  uint64_t target_msc,
+                  PixmapPtr pixmap,
+                  Bool sync_flip,
+                  RegionPtr damage)
+{
+    ScreenPtr                   screen = window->drawable.pScreen;
+    present_screen_priv_ptr     screen_priv = present_screen_priv(screen);
+
+    return (*screen_priv->wnmd_info->flip) (window,
+                                            crtc,
+                                            event_id,
+                                            target_msc,
+                                            pixmap,
+                                            sync_flip,
+                                            damage);
+}
+
+static void
+present_wnmd_cancel_flip(WindowPtr window)
+{
+    struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
+
+    if (xwl_present_window->flip_pending)
+        xwl_present_window->flip_pending->abort_flip = TRUE;
+    else if (xwl_present_window->flip_active)
+        present_wnmd_flips_stop(window);
+}
+
+/*
+ * Once the required MSC has been reached, execute the pending request.
+ *
+ * For requests to actually present something, either blt contents to
+ * the window pixmap or queue a window buffer swap on the backend.
+ *
+ * For requests to just get the current MSC/UST combo, skip that part and
+ * go straight to event delivery.
+ */
+static void
+present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
+{
+    WindowPtr               window = vblank->window;
+    struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
+    present_window_priv_ptr window_priv = present_window_priv(window);
+
+    if (present_execute_wait(vblank, crtc_msc))
+        return;
+
+    if (vblank->flip && vblank->pixmap && vblank->window) {
+        if (xwl_present_window->flip_pending) {
+            DebugPresent(("\tr %" PRIu64 " %p (pending %p)\n",
+                          vblank->event_id, vblank,
+                          xwl_present_window->flip_pending));
+            xorg_list_del(&vblank->event_queue);
+            xorg_list_append(&vblank->event_queue, &xwl_present_window->flip_queue);
+            vblank->flip_ready = TRUE;
+            return;
+        }
+    }
+
+    xorg_list_del(&vblank->event_queue);
+    xorg_list_del(&vblank->window_list);
+    vblank->queued = FALSE;
+
+    if (vblank->pixmap && vblank->window) {
+        ScreenPtr screen = window->drawable.pScreen;
+
+        if (vblank->flip) {
+            RegionPtr damage;
+
+            DebugPresent(("\tf %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
+                          vblank->event_id, vblank, crtc_msc,
+                          vblank->pixmap->drawable.id, vblank->window->drawable.id));
+
+            /* Prepare to flip by placing it in the flip queue
+             */
+            xorg_list_add(&vblank->event_queue, &xwl_present_window->flip_queue);
+
+            /* Set update region as damaged */
+            if (vblank->update) {
+                damage = RegionDuplicate(vblank->update);
+                /* Translate update region to screen space */
+                assert(vblank->x_off == 0 && vblank->y_off == 0);
+                RegionTranslate(damage, window->drawable.x, window->drawable.y);
+                RegionIntersect(damage, damage, &window->clipList);
+            } else
+                damage = RegionDuplicate(&window->clipList);
+
+            /* Try to flip - the vblank is now pending
+             */
+            xwl_present_window->flip_pending = vblank;
+            // ask the driver
+            if (present_wnmd_flip(vblank->window, vblank->crtc, vblank->event_id,
+                                     vblank->target_msc, vblank->pixmap, vblank->sync_flip, damage)) {
+                WindowPtr toplvl_window = present_wnmd_toplvl_pixmap_window(vblank->window);
+                PixmapPtr old_pixmap = screen->GetWindowPixmap(window);
+
+                /* Replace window pixmap with flip pixmap */
+#ifdef COMPOSITE
+                vblank->pixmap->screen_x = old_pixmap->screen_x;
+                vblank->pixmap->screen_y = old_pixmap->screen_y;
+#endif
+                present_set_tree_pixmap(toplvl_window, old_pixmap, vblank->pixmap);
+                vblank->pixmap->refcnt++;
+                dixDestroyPixmap(old_pixmap, old_pixmap->drawable.id);
+
+                /* Report damage */
+                DamageDamageRegion(&vblank->window->drawable, damage);
+                RegionDestroy(damage);
+                return;
+            }
+
+            xorg_list_del(&vblank->event_queue);
+            /* Flip failed. Clear the flip_pending field
+              */
+            xwl_present_window->flip_pending = NULL;
+            vblank->flip = FALSE;
+        }
+        DebugPresent(("\tc %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
+                      vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id));
+
+        present_wnmd_cancel_flip(window);
+
+        present_execute_copy(vblank, crtc_msc);
+        assert(!vblank->queued);
+
+        if (present_wnmd_queue_vblank(screen, window, vblank->crtc,
+                                      vblank->event_id, crtc_msc + 1)
+            == Success) {
+            xorg_list_add(&vblank->event_queue, &xwl_present_window->idle_queue);
+            xorg_list_append(&vblank->window_list, &window_priv->vblank);
+
+            return;
+        }
+    }
+
+    present_execute_post(vblank, ust, crtc_msc);
+}
+
+static void
+present_wnmd_update_window_crtc(WindowPtr window, RRCrtcPtr crtc, uint64_t new_msc)
+{
+    present_window_priv_ptr window_priv = present_get_window_priv(window, TRUE);
+
+    /* Crtc unchanged, no offset. */
+    if (crtc == window_priv->crtc)
+        return;
+
+    /* No crtc earlier to offset against, just set the crtc. */
+    if (window_priv->crtc == PresentCrtcNeverSet) {
+        window_priv->msc_offset = 0;
+        window_priv->crtc = crtc;
+        return;
+    }
+
+    /* In window-mode the last correct msc-offset is always kept
+     * in window-priv struct because msc is saved per window and
+     * not per crtc as in screen-mode.
+     */
+    window_priv->msc_offset += new_msc - window_priv->msc;
+    window_priv->crtc = crtc;
+}
+
+static int
+present_wnmd_pixmap(WindowPtr window,
+                    PixmapPtr pixmap,
+                    CARD32 serial,
+                    RegionPtr valid,
+                    RegionPtr update,
+                    int16_t x_off,
+                    int16_t y_off,
+                    RRCrtcPtr target_crtc,
+                    SyncFence *wait_fence,
+                    SyncFence *idle_fence,
+                    uint32_t options,
+                    uint64_t target_window_msc,
+                    uint64_t divisor,
+                    uint64_t remainder,
+                    present_notify_ptr notifies,
+                    int num_notifies)
+{
+    uint64_t                    ust = 0;
+    uint64_t                    target_msc;
+    uint64_t                    crtc_msc = 0;
+    int                         ret;
+    present_vblank_ptr          vblank, tmp;
+    ScreenPtr                   screen = window->drawable.pScreen;
+    struct xwl_present_window *xwl_present_window = xwl_present_window_get_priv(window);
+    present_window_priv_ptr     window_priv = present_get_window_priv(window, TRUE);
+    present_screen_priv_ptr     screen_priv = present_screen_priv(screen);
+
+    if (!window_priv)
+        return BadAlloc;
+
+    target_crtc = present_wnmd_get_crtc(screen_priv, window);
+
+    ret = present_wnmd_get_ust_msc(screen, window, &ust, &crtc_msc);
+
+    present_wnmd_update_window_crtc(window, target_crtc, crtc_msc);
+
+    if (ret == Success) {
+        /* Stash the current MSC away in case we need it later
+         */
+        window_priv->msc = crtc_msc;
+    }
+
+    target_msc = present_get_target_msc(target_window_msc + window_priv->msc_offset,
+                                        crtc_msc,
+                                        divisor,
+                                        remainder,
+                                        options);
+
+    /*
+     * Look for a matching presentation already on the list...
+     */
+
+    if (!update && pixmap) {
+        xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->vblank, window_list) {
+
+            if (!vblank->pixmap)
+                continue;
+
+            if (!vblank->queued)
+                continue;
+
+            if (vblank->target_msc != target_msc)
+                continue;
+
+            present_vblank_scrap(vblank);
+            if (vblank->flip_ready)
+                present_wnmd_re_execute(vblank);
+        }
+    }
+
+    vblank = present_vblank_create(window,
+                                   pixmap,
+                                   serial,
+                                   valid,
+                                   update,
+                                   x_off,
+                                   y_off,
+                                   target_crtc,
+                                   wait_fence,
+                                   idle_fence,
+                                   options,
+                                   screen_priv->wnmd_info->capabilities,
+                                   notifies,
+                                   num_notifies,
+                                   target_msc,
+                                   crtc_msc);
+    if (!vblank)
+        return BadAlloc;
+
+    vblank->event_id = ++present_wnmd_event_id;
+
+    /* 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, &xwl_present_window->exec_queue);
+    vblank->queued = TRUE;
+    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"));
+    }
+
+    present_wnmd_execute(vblank, ust, crtc_msc);
+    return Success;
+}
+
+static void
+present_wnmd_abort_vblank(ScreenPtr screen, WindowPtr window, RRCrtcPtr crtc, uint64_t event_id, uint64_t msc)
+{
+    struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
+    present_screen_priv_ptr screen_priv = present_screen_priv(screen);
+    present_vblank_ptr      vblank;
+
+    (*screen_priv->wnmd_info->abort_vblank) (window, crtc, event_id, msc);
+
+    xorg_list_for_each_entry(vblank, &xwl_present_window->exec_queue, event_queue) {
+        if (vblank->event_id == event_id) {
+            xorg_list_del(&vblank->event_queue);
+            vblank->queued = FALSE;
+            return;
+        }
+    }
+    xorg_list_for_each_entry(vblank, &xwl_present_window->flip_queue, event_queue) {
+        if (vblank->event_id == event_id) {
+            xorg_list_del(&vblank->event_queue);
+            vblank->queued = FALSE;
+            return;
+        }
+    }
+}
+
+static void
+present_wnmd_flush(WindowPtr window)
+{
+    ScreenPtr               screen = window->drawable.pScreen;
+    present_screen_priv_ptr screen_priv = present_screen_priv(screen);
+
+    (*screen_priv->wnmd_info->flush) (window);
+}
+
+/*
+ * Initialize a screen for use with present in window flip mode (wnmd)
+ */
+static int
+present_wnmd_screen_init(ScreenPtr screen, present_wnmd_info_ptr info)
+{
+    present_screen_priv_ptr screen_priv;
+
+    if (!present_screen_register_priv_keys())
+        return FALSE;
+
+    if (present_screen_priv(screen))
+        return TRUE;
+
+    screen_priv = present_screen_priv_init(screen);
+    if (!screen_priv)
+        return FALSE;
+
+    screen_priv->wnmd_info = info;
+
+    screen_priv->query_capabilities =   &present_wnmd_query_capabilities;
+    screen_priv->get_crtc           =   &present_wnmd_get_crtc;
+
+    screen_priv->check_flip         =   &present_wnmd_check_flip;
+    screen_priv->check_flip_window  =   &present_wnmd_check_flip_window;
+    screen_priv->clear_window_flip  =   &present_wnmd_clear_window_flip;
+
+    screen_priv->present_pixmap     =   &present_wnmd_pixmap;
+    screen_priv->queue_vblank       =   &present_wnmd_queue_vblank;
+    screen_priv->flush              =   &present_wnmd_flush;
+    screen_priv->re_execute         =   &present_wnmd_re_execute;
+
+    screen_priv->abort_vblank       =   &present_wnmd_abort_vblank;
+
+    return TRUE;
+}
+
+
 static void
 xwl_present_release_pixmap(struct xwl_present_event *event)
 {
diff --git a/hw/xwayland/xwayland-present.h b/hw/xwayland/xwayland-present.h
index 35b579469..e595f4de2 100644
--- a/hw/xwayland/xwayland-present.h
+++ b/hw/xwayland/xwayland-present.h
@@ -29,6 +29,7 @@
 #include <xwayland-config.h>
 
 #include <dix.h>
+#include <present_priv.h>
 
 #include "xwayland-types.h"
 
@@ -47,6 +48,12 @@ struct xwl_present_window {
 
     struct xorg_list wait_list;
     struct xorg_list release_list;
+    struct xorg_list exec_queue;
+    struct xorg_list flip_queue;
+    struct xorg_list idle_queue;
+
+    present_vblank_ptr flip_pending;
+    present_vblank_ptr flip_active;
 };
 
 struct xwl_present_event {
diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c
index bb18e5c94..3fe5d82a7 100644
--- a/hw/xwayland/xwayland-screen.c
+++ b/hw/xwayland/xwayland-screen.c
@@ -687,6 +687,9 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
     if (!xwl_screen_init_cursor(xwl_screen))
         return FALSE;
 
+    xwl_screen->DestroyWindow = pScreen->DestroyWindow;
+    pScreen->DestroyWindow = xwl_destroy_window;
+
 #ifdef XWL_HAS_GLAMOR
     if (xwl_screen->glamor) {
         xwl_glamor_select_backend(xwl_screen, use_eglstreams);
@@ -714,9 +717,6 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
     xwl_screen->UnrealizeWindow = pScreen->UnrealizeWindow;
     pScreen->UnrealizeWindow = xwl_unrealize_window;
 
-    xwl_screen->DestroyWindow = pScreen->DestroyWindow;
-    pScreen->DestroyWindow = xwl_destroy_window;
-
     xwl_screen->CloseScreen = pScreen->CloseScreen;
     pScreen->CloseScreen = xwl_close_screen;
 
diff --git a/present/Makefile.am b/present/Makefile.am
index 269bd5db5..a2d58212c 100644
--- a/present/Makefile.am
+++ b/present/Makefile.am
@@ -14,7 +14,6 @@ libpresent_la_SOURCES = \
 	present_request.c \
 	present_scmd.c \
 	present_screen.c \
-	present_vblank.c \
-	present_wnmd.c
+	present_vblank.c
 
 sdk_HEADERS = present.h presentext.h
diff --git a/present/meson.build b/present/meson.build
index aa7ce86ff..1a74a9cbc 100644
--- a/present/meson.build
+++ b/present/meson.build
@@ -9,7 +9,6 @@ srcs_present = [
     'present_scmd.c',
     'present_screen.c',
     'present_vblank.c',
-    'present_wnmd.c',
 ]
 
 hdrs_present = [
diff --git a/present/present.h b/present/present.h
index 86744a838..a09b3846a 100644
--- a/present/present.h
+++ b/present/present.h
@@ -161,30 +161,8 @@ typedef struct present_wnmd_info {
 extern _X_EXPORT void
 present_event_notify(uint64_t event_id, uint64_t ust, uint64_t msc);
 
-/*
- * Called when 'event_id' occurs for 'window'.
- * 'ust' and 'msc' indicate when the event actually happened
- */
-extern _X_EXPORT void
-present_wnmd_event_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uint64_t msc);
-
-/*
- * Called when presentation 'event_id' occurs for 'window'.
- * 'ust' and 'msc' indicate when the presentation actually happened.
- */
-extern _X_EXPORT void
-present_wnmd_flip_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uint64_t msc);
-
-/*
- * Called when the flipped Pixmap associated with 'event_id' is not used anymore by the DDX.
- */
-extern _X_EXPORT void
-present_wnmd_idle_notify(WindowPtr window, uint64_t event_id);
-
 extern _X_EXPORT Bool
 present_screen_init(ScreenPtr screen, present_screen_info_ptr info);
-extern _X_EXPORT Bool
-present_wnmd_screen_init(ScreenPtr screen, present_wnmd_info_ptr info);
 
 typedef void (*present_complete_notify_proc)(WindowPtr window,
                                              CARD8 kind,
diff --git a/present/present_priv.h b/present/present_priv.h
index 811250b09..5f62dd43d 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -219,14 +219,6 @@ struct present_window_priv {
     uint64_t               msc;         /* Last reported MSC from the current crtc */
     struct xorg_list       vblank;
     struct xorg_list       notifies;
-
-    /* Used for window flips */
-    struct xorg_list       exec_queue;
-    struct xorg_list       flip_queue;
-    struct xorg_list       idle_queue;
-
-    present_vblank_ptr     flip_pending;
-    present_vblank_ptr     flip_active;
 };
 
 #define PresentCrtcNeverSet     ((RRCrtcPtr) 1)
diff --git a/present/present_screen.c b/present/present_screen.c
index c2ae773a1..15684eda4 100644
--- a/present/present_screen.c
+++ b/present/present_screen.c
@@ -42,10 +42,6 @@ present_get_window_priv(WindowPtr window, Bool create)
     xorg_list_init(&window_priv->vblank);
     xorg_list_init(&window_priv->notifies);
 
-    xorg_list_init(&window_priv->exec_queue);
-    xorg_list_init(&window_priv->flip_queue);
-    xorg_list_init(&window_priv->idle_queue);
-
     window_priv->window = window;
     window_priv->crtc = PresentCrtcNeverSet;
     dixSetPrivate(&window->devPrivates, &present_window_private_key, window_priv);
diff --git a/present/present_wnmd.c b/present/present_wnmd.c
deleted file mode 100644
index 061698209..000000000
--- a/present/present_wnmd.c
+++ /dev/null
@@ -1,746 +0,0 @@
-/*
- * Copyright © 2018 Roman Gilg
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  The copyright holders make no representations
- * about the suitability of this software for any purpose.  It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-#include "present_priv.h"
-
-/*
- * Window flip mode
- *
- * Provides per-window flips. Flips can be processed on windows that
- * have the same size as their parents, which they share their pixmap with.
- *
- * A flip still requires a copy currently, since the original pixmap needs
- * to be updated with the new pixmap content. Just a flip of all windows
- * to the new pixmap is difficult, because the original pixmap might not be
- * controlled by the Xserver.
- *
- */
-
-static uint64_t present_wnmd_event_id;
-
-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 uint32_t
-present_wnmd_query_capabilities(present_screen_priv_ptr screen_priv)
-{
-    return screen_priv->wnmd_info->capabilities;
-}
-
-static RRCrtcPtr
-present_wnmd_get_crtc(present_screen_priv_ptr screen_priv, WindowPtr window)
-{
-    return (*screen_priv->wnmd_info->get_crtc)(window);
-}
-
-static int
-present_wnmd_get_ust_msc(ScreenPtr screen, WindowPtr window, uint64_t *ust, uint64_t *msc)
-{
-    present_screen_priv_ptr screen_priv = present_screen_priv(screen);
-    return (*screen_priv->wnmd_info->get_ust_msc)(window, ust, msc);
-}
-
-/*
- * When the wait fence or previous flip is completed, it's time
- * to re-try the request
- */
-static void
-present_wnmd_re_execute(present_vblank_ptr vblank)
-{
-    uint64_t ust = 0, crtc_msc = 0;
-
-    (void) present_wnmd_get_ust_msc(vblank->screen, vblank->window, &ust, &crtc_msc);
-    present_wnmd_execute(vblank, ust, crtc_msc);
-}
-
-static void
-present_wnmd_flip_try_ready(WindowPtr window)
-{
-    present_window_priv_ptr window_priv = present_window_priv(window);
-    present_vblank_ptr      vblank;
-
-    xorg_list_for_each_entry(vblank, &window_priv->flip_queue, event_queue) {
-        if (vblank->queued) {
-            present_wnmd_re_execute(vblank);
-            return;
-        }
-    }
-}
-
-static void
-present_wnmd_free_idle_vblank(present_vblank_ptr vblank)
-{
-    present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
-    present_vblank_destroy(vblank);
-}
-
-/*
- * Free any left over idle vblanks
- */
-static void
-present_wnmd_free_idle_vblanks(WindowPtr window)
-{
-    present_window_priv_ptr         window_priv = present_window_priv(window);
-    present_vblank_ptr              vblank, tmp;
-
-    xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->idle_queue, event_queue) {
-        present_wnmd_free_idle_vblank(vblank);
-    }
-
-    if (window_priv->flip_active) {
-        present_wnmd_free_idle_vblank(window_priv->flip_active);
-        window_priv->flip_active = NULL;
-    }
-}
-
-static WindowPtr
-present_wnmd_toplvl_pixmap_window(WindowPtr window)
-{
-    ScreenPtr       screen = window->drawable.pScreen;
-    PixmapPtr       pixmap = (*screen->GetWindowPixmap)(window);
-    WindowPtr       w = window;
-    WindowPtr       next_w;
-
-    while(w->parent) {
-        next_w = w->parent;
-        if ( (*screen->GetWindowPixmap)(next_w) != pixmap) {
-            break;
-        }
-        w = next_w;
-    }
-    return w;
-}
-
-static void
-present_wnmd_flips_stop(WindowPtr window)
-{
-    present_window_priv_ptr window_priv = present_window_priv(window);
-    present_screen_priv_ptr screen_priv = present_screen_priv(window->drawable.pScreen);
-
-    assert (!window_priv->flip_pending);
-
-    (*screen_priv->wnmd_info->flips_stop) (window);
-
-    present_wnmd_free_idle_vblanks(window_priv->window);
-    present_wnmd_flip_try_ready(window_priv->window);
-}
-
-static void
-present_wnmd_flip_notify_vblank(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
-{
-    WindowPtr                   window = vblank->window;
-    present_window_priv_ptr     window_priv = present_window_priv(window);
-
-    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));
-
-    assert (vblank == window_priv->flip_pending);
-
-    xorg_list_del(&vblank->event_queue);
-
-    if (window_priv->flip_active) {
-        if (window_priv->flip_active->flip_idler)
-            present_wnmd_free_idle_vblank(window_priv->flip_active);
-        else
-            /* Put the previous flip in the idle_queue and wait for further notice from DDX */
-            xorg_list_append(&window_priv->flip_active->event_queue, &window_priv->idle_queue);
-    }
-
-    window_priv->flip_active = vblank;
-    window_priv->flip_pending = NULL;
-
-    present_vblank_notify(vblank, PresentCompleteKindPixmap, PresentCompleteModeFlip, ust, crtc_msc);
-
-    if (vblank->abort_flip)
-        present_wnmd_flips_stop(window);
-
-    present_wnmd_flip_try_ready(window);
-}
-
-void
-present_wnmd_event_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uint64_t msc)
-{
-    present_window_priv_ptr     window_priv = present_window_priv(window);
-    present_vblank_ptr          vblank;
-
-    if (!window_priv)
-        return;
-    if (!event_id)
-        return;
-
-    DebugPresent(("\te %" PRIu64 " ust %" PRIu64 " msc %" PRIu64 "\n", event_id, ust, msc));
-    xorg_list_for_each_entry(vblank, &window_priv->exec_queue, event_queue) {
-        if (event_id == vblank->event_id) {
-            present_wnmd_execute(vblank, ust, msc);
-            return;
-        }
-    }
-    xorg_list_for_each_entry(vblank, &window_priv->flip_queue, event_queue) {
-        if (vblank->event_id == event_id) {
-            assert(vblank->queued);
-            present_wnmd_execute(vblank, ust, msc);
-            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
-present_wnmd_flip_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uint64_t msc)
-{
-    present_window_priv_ptr     window_priv = present_window_priv(window);
-    present_vblank_ptr          vblank;
-
-    xorg_list_for_each_entry(vblank, &window_priv->flip_queue, event_queue) {
-        if (vblank->event_id == event_id) {
-            assert(!vblank->queued);
-            assert(vblank->window);
-            present_wnmd_flip_notify_vblank(vblank, ust, msc);
-            return;
-        }
-    }
-}
-
-void
-present_wnmd_idle_notify(WindowPtr window, uint64_t event_id)
-{
-    present_window_priv_ptr     window_priv = present_window_priv(window);
-    present_vblank_ptr          vblank;
-
-    if (window_priv->flip_active && window_priv->flip_active->event_id == event_id) {
-        /* Active flip is allowed to become idle directly when it becomes unactive again. */
-        window_priv->flip_active->flip_idler = TRUE;
-        return;
-    }
-
-    xorg_list_for_each_entry(vblank, &window_priv->idle_queue, event_queue) {
-        if (vblank->event_id == event_id) {
-            present_wnmd_free_idle_vblank(vblank);
-            return;
-        }
-    }
-
-    xorg_list_for_each_entry(vblank, &window_priv->flip_queue, event_queue) {
-        if (vblank->event_id == event_id) {
-            vblank->flip_idler = TRUE;
-            return;
-        }
-    }
-}
-
-static Bool
-present_wnmd_check_flip(RRCrtcPtr           crtc,
-                        WindowPtr           window,
-                        PixmapPtr           pixmap,
-                        Bool                sync_flip,
-                        RegionPtr           valid,
-                        int16_t             x_off,
-                        int16_t             y_off,
-                        PresentFlipReason   *reason)
-{
-    ScreenPtr               screen = window->drawable.pScreen;
-    present_screen_priv_ptr screen_priv = present_screen_priv(screen);
-    WindowPtr               toplvl_window = present_wnmd_toplvl_pixmap_window(window);
-
-    if (reason)
-        *reason = PRESENT_FLIP_REASON_UNKNOWN;
-
-    if (!screen_priv)
-        return FALSE;
-
-    if (!screen_priv->wnmd_info)
-        return FALSE;
-
-    if (!crtc)
-        return FALSE;
-
-    /* Check to see if the driver supports flips at all */
-    if (!screen_priv->wnmd_info->flip)
-        return FALSE;
-
-    /* Source pixmap must align with window exactly */
-    if (x_off || y_off)
-        return FALSE;
-
-    /* Valid area must contain window (for simplicity for now just never flip when one is set). */
-    if (valid)
-        return FALSE;
-
-    /* Flip pixmap must have same dimensions as window */
-    if (window->drawable.width != pixmap->drawable.width ||
-            window->drawable.height != pixmap->drawable.height)
-        return FALSE;
-
-    /* Window must be same region as toplevel window */
-    if ( !RegionEqual(&window->winSize, &toplvl_window->winSize) )
-        return FALSE;
-
-    /* Can't flip if window clipped by children */
-    if (!RegionEqual(&window->clipList, &window->winSize))
-        return FALSE;
-
-    /* Ask the driver for permission */
-    if (screen_priv->wnmd_info->check_flip2) {
-        if (!(*screen_priv->wnmd_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;
-        }
-    }
-
-    return TRUE;
-}
-
-/*
- * 'window' is being reconfigured. Check to see if it is involved
- * in flipping and clean up as necessary.
- */
-static void
-present_wnmd_check_flip_window (WindowPtr window)
-{
-    present_window_priv_ptr window_priv = present_window_priv(window);
-    present_vblank_ptr      flip_pending;
-    present_vblank_ptr      flip_active;
-    present_vblank_ptr      vblank;
-    PresentFlipReason       reason;
-
-    /* If this window hasn't ever been used with Present, it can't be
-     * flipping
-     */
-    if (!window_priv)
-        return;
-
-    flip_pending = window_priv->flip_pending;
-    flip_active = window_priv->flip_active;
-
-    if (flip_pending) {
-        if (!present_wnmd_check_flip(flip_pending->crtc, flip_pending->window, flip_pending->pixmap,
-                                flip_pending->sync_flip, flip_pending->valid, 0, 0, NULL))
-            window_priv->flip_pending->abort_flip = TRUE;
-    } else if (flip_active) {
-        if (!present_wnmd_check_flip(flip_active->crtc, flip_active->window, flip_active->pixmap,
-                                     flip_active->sync_flip, flip_active->valid, 0, 0, NULL))
-            present_wnmd_flips_stop(window);
-    }
-
-    /* Now check any queued vblanks */
-    xorg_list_for_each_entry(vblank, &window_priv->vblank, window_list) {
-        if (vblank->queued && vblank->flip &&
-                !present_wnmd_check_flip(vblank->crtc, window, vblank->pixmap,
-                                         vblank->sync_flip, vblank->valid, 0, 0, &reason)) {
-            vblank->flip = FALSE;
-            vblank->reason = reason;
-        }
-    }
-}
-
-/*
- * Clean up any pending or current flips for this window
- */
-static void
-present_wnmd_clear_window_flip(WindowPtr window)
-{
-    present_window_priv_ptr     window_priv = present_window_priv(window);
-    present_vblank_ptr          vblank, tmp;
-
-    xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->flip_queue, event_queue) {
-        present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
-        present_vblank_destroy(vblank);
-    }
-
-    xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->idle_queue, event_queue) {
-        present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
-        present_vblank_destroy(vblank);
-    }
-
-    vblank = window_priv->flip_active;
-    if (vblank) {
-        present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
-        present_vblank_destroy(vblank);
-    }
-    window_priv->flip_active = NULL;
-}
-
-static Bool
-present_wnmd_flip(WindowPtr window,
-                  RRCrtcPtr crtc,
-                  uint64_t event_id,
-                  uint64_t target_msc,
-                  PixmapPtr pixmap,
-                  Bool sync_flip,
-                  RegionPtr damage)
-{
-    ScreenPtr                   screen = window->drawable.pScreen;
-    present_screen_priv_ptr     screen_priv = present_screen_priv(screen);
-
-    return (*screen_priv->wnmd_info->flip) (window,
-                                            crtc,
-                                            event_id,
-                                            target_msc,
-                                            pixmap,
-                                            sync_flip,
-                                            damage);
-}
-
-static void
-present_wnmd_cancel_flip(WindowPtr window)
-{
-    present_window_priv_ptr window_priv = present_window_priv(window);
-
-    if (window_priv->flip_pending)
-        window_priv->flip_pending->abort_flip = TRUE;
-    else if (window_priv->flip_active)
-        present_wnmd_flips_stop(window);
-}
-
-/*
- * Once the required MSC has been reached, execute the pending request.
- *
- * For requests to actually present something, either blt contents to
- * the window pixmap or queue a window buffer swap on the backend.
- *
- * For requests to just get the current MSC/UST combo, skip that part and
- * go straight to event delivery.
- */
-static void
-present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
-{
-    WindowPtr               window = vblank->window;
-    present_window_priv_ptr window_priv = present_window_priv(window);
-
-    if (present_execute_wait(vblank, crtc_msc))
-        return;
-
-    if (vblank->flip && vblank->pixmap && vblank->window) {
-        if (window_priv->flip_pending) {
-            DebugPresent(("\tr %" PRIu64 " %p (pending %p)\n",
-                          vblank->event_id, vblank,
-                          window_priv->flip_pending));
-            xorg_list_del(&vblank->event_queue);
-            xorg_list_append(&vblank->event_queue, &window_priv->flip_queue);
-            vblank->flip_ready = TRUE;
-            return;
-        }
-    }
-
-    xorg_list_del(&vblank->event_queue);
-    xorg_list_del(&vblank->window_list);
-    vblank->queued = FALSE;
-
-    if (vblank->pixmap && vblank->window) {
-        ScreenPtr screen = window->drawable.pScreen;
-
-        if (vblank->flip) {
-            RegionPtr damage;
-
-            DebugPresent(("\tf %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
-                          vblank->event_id, vblank, crtc_msc,
-                          vblank->pixmap->drawable.id, vblank->window->drawable.id));
-
-            /* Prepare to flip by placing it in the flip queue
-             */
-            xorg_list_add(&vblank->event_queue, &window_priv->flip_queue);
-
-            /* Set update region as damaged */
-            if (vblank->update) {
-                damage = RegionDuplicate(vblank->update);
-                /* Translate update region to screen space */
-                assert(vblank->x_off == 0 && vblank->y_off == 0);
-                RegionTranslate(damage, window->drawable.x, window->drawable.y);
-                RegionIntersect(damage, damage, &window->clipList);
-            } else
-                damage = RegionDuplicate(&window->clipList);
-
-            /* Try to flip - the vblank is now pending
-             */
-            window_priv->flip_pending = vblank;
-            // ask the driver
-            if (present_wnmd_flip(vblank->window, vblank->crtc, vblank->event_id,
-                                     vblank->target_msc, vblank->pixmap, vblank->sync_flip, damage)) {
-                WindowPtr toplvl_window = present_wnmd_toplvl_pixmap_window(vblank->window);
-                PixmapPtr old_pixmap = screen->GetWindowPixmap(window);
-
-                /* Replace window pixmap with flip pixmap */
-#ifdef COMPOSITE
-                vblank->pixmap->screen_x = old_pixmap->screen_x;
-                vblank->pixmap->screen_y = old_pixmap->screen_y;
-#endif
-                present_set_tree_pixmap(toplvl_window, old_pixmap, vblank->pixmap);
-                vblank->pixmap->refcnt++;
-                dixDestroyPixmap(old_pixmap, old_pixmap->drawable.id);
-
-                /* Report damage */
-                DamageDamageRegion(&vblank->window->drawable, damage);
-                RegionDestroy(damage);
-                return;
-            }
-
-            xorg_list_del(&vblank->event_queue);
-            /* Flip failed. Clear the flip_pending field
-              */
-            window_priv->flip_pending = NULL;
-            vblank->flip = FALSE;
-        }
-        DebugPresent(("\tc %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 "\n",
-                      vblank, crtc_msc, vblank->pixmap->drawable.id, vblank->window->drawable.id));
-
-        present_wnmd_cancel_flip(window);
-
-        present_execute_copy(vblank, crtc_msc);
-        assert(!vblank->queued);
-
-        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;
-        }
-    }
-
-    present_execute_post(vblank, ust, crtc_msc);
-}
-
-static void
-present_wnmd_update_window_crtc(WindowPtr window, RRCrtcPtr crtc, uint64_t new_msc)
-{
-    present_window_priv_ptr window_priv = present_get_window_priv(window, TRUE);
-
-    /* Crtc unchanged, no offset. */
-    if (crtc == window_priv->crtc)
-        return;
-
-    /* No crtc earlier to offset against, just set the crtc. */
-    if (window_priv->crtc == PresentCrtcNeverSet) {
-        window_priv->msc_offset = 0;
-        window_priv->crtc = crtc;
-        return;
-    }
-
-    /* In window-mode the last correct msc-offset is always kept
-     * in window-priv struct because msc is saved per window and
-     * not per crtc as in screen-mode.
-     */
-    window_priv->msc_offset += new_msc - window_priv->msc;
-    window_priv->crtc = crtc;
-}
-
-static int
-present_wnmd_pixmap(WindowPtr window,
-                    PixmapPtr pixmap,
-                    CARD32 serial,
-                    RegionPtr valid,
-                    RegionPtr update,
-                    int16_t x_off,
-                    int16_t y_off,
-                    RRCrtcPtr target_crtc,
-                    SyncFence *wait_fence,
-                    SyncFence *idle_fence,
-                    uint32_t options,
-                    uint64_t target_window_msc,
-                    uint64_t divisor,
-                    uint64_t remainder,
-                    present_notify_ptr notifies,
-                    int num_notifies)
-{
-    uint64_t                    ust = 0;
-    uint64_t                    target_msc;
-    uint64_t                    crtc_msc = 0;
-    int                         ret;
-    present_vblank_ptr          vblank, tmp;
-    ScreenPtr                   screen = window->drawable.pScreen;
-    present_window_priv_ptr     window_priv = present_get_window_priv(window, TRUE);
-    present_screen_priv_ptr     screen_priv = present_screen_priv(screen);
-
-    if (!window_priv)
-        return BadAlloc;
-
-    target_crtc = present_wnmd_get_crtc(screen_priv, window);
-
-    ret = present_wnmd_get_ust_msc(screen, window, &ust, &crtc_msc);
-
-    present_wnmd_update_window_crtc(window, target_crtc, crtc_msc);
-
-    if (ret == Success) {
-        /* Stash the current MSC away in case we need it later
-         */
-        window_priv->msc = crtc_msc;
-    }
-
-    target_msc = present_get_target_msc(target_window_msc + window_priv->msc_offset,
-                                        crtc_msc,
-                                        divisor,
-                                        remainder,
-                                        options);
-
-    /*
-     * Look for a matching presentation already on the list...
-     */
-
-    if (!update && pixmap) {
-        xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->vblank, window_list) {
-
-            if (!vblank->pixmap)
-                continue;
-
-            if (!vblank->queued)
-                continue;
-
-            if (vblank->target_msc != target_msc)
-                continue;
-
-            present_vblank_scrap(vblank);
-            if (vblank->flip_ready)
-                present_wnmd_re_execute(vblank);
-        }
-    }
-
-    vblank = present_vblank_create(window,
-                                   pixmap,
-                                   serial,
-                                   valid,
-                                   update,
-                                   x_off,
-                                   y_off,
-                                   target_crtc,
-                                   wait_fence,
-                                   idle_fence,
-                                   options,
-                                   screen_priv->wnmd_info->capabilities,
-                                   notifies,
-                                   num_notifies,
-                                   target_msc,
-                                   crtc_msc);
-    if (!vblank)
-        return BadAlloc;
-
-    vblank->event_id = ++present_wnmd_event_id;
-
-    /* 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;
-    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"));
-    }
-
-    present_wnmd_execute(vblank, ust, crtc_msc);
-    return Success;
-}
-
-static void
-present_wnmd_abort_vblank(ScreenPtr screen, WindowPtr window, RRCrtcPtr crtc, uint64_t event_id, uint64_t msc)
-{
-    present_screen_priv_ptr screen_priv = present_screen_priv(screen);
-    present_window_priv_ptr window_priv = present_window_priv(window);
-    present_vblank_ptr      vblank;
-
-    (*screen_priv->wnmd_info->abort_vblank) (window, crtc, event_id, msc);
-
-    xorg_list_for_each_entry(vblank, &window_priv->exec_queue, event_queue) {
-        if (vblank->event_id == event_id) {
-            xorg_list_del(&vblank->event_queue);
-            vblank->queued = FALSE;
-            return;
-        }
-    }
-    xorg_list_for_each_entry(vblank, &window_priv->flip_queue, event_queue) {
-        if (vblank->event_id == event_id) {
-            xorg_list_del(&vblank->event_queue);
-            vblank->queued = FALSE;
-            return;
-        }
-    }
-}
-
-static void
-present_wnmd_flush(WindowPtr window)
-{
-    ScreenPtr               screen = window->drawable.pScreen;
-    present_screen_priv_ptr screen_priv = present_screen_priv(screen);
-
-    (*screen_priv->wnmd_info->flush) (window);
-}
-
-/*
- * Initialize a screen for use with present in window flip mode (wnmd)
- */
-int
-present_wnmd_screen_init(ScreenPtr screen, present_wnmd_info_ptr info)
-{
-    present_screen_priv_ptr screen_priv;
-
-    if (!present_screen_register_priv_keys())
-        return FALSE;
-
-    if (present_screen_priv(screen))
-        return TRUE;
-
-    screen_priv = present_screen_priv_init(screen);
-    if (!screen_priv)
-        return FALSE;
-
-    screen_priv->wnmd_info = info;
-
-    screen_priv->query_capabilities =   &present_wnmd_query_capabilities;
-    screen_priv->get_crtc           =   &present_wnmd_get_crtc;
-
-    screen_priv->check_flip         =   &present_wnmd_check_flip;
-    screen_priv->check_flip_window  =   &present_wnmd_check_flip_window;
-    screen_priv->clear_window_flip  =   &present_wnmd_clear_window_flip;
-
-    screen_priv->present_pixmap     =   &present_wnmd_pixmap;
-    screen_priv->queue_vblank       =   &present_wnmd_queue_vblank;
-    screen_priv->flush              =   &present_wnmd_flush;
-    screen_priv->re_execute         =   &present_wnmd_re_execute;
-
-    screen_priv->abort_vblank       =   &present_wnmd_abort_vblank;
-
-    return TRUE;
-}
commit c35a716b02921e2fcae5fe89295a99c6dd5dec8c
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Fri Apr 16 18:45:39 2021 +0200

    present: Fold wnmd_init_mode_hooks into wnmd_screen_init
    
    Preparation for moving WNMD code to hw/xwayland. No functional change
    intended.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/present/present_priv.h b/present/present_priv.h
index 6d0588b1e..811250b09 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -481,10 +481,4 @@ present_vblank_scrap(present_vblank_ptr vblank);
 void
 present_vblank_destroy(present_vblank_ptr vblank);
 
-/*
- * present_wnmd.c
- */
-void
-present_wnmd_init_mode_hooks(present_screen_priv_ptr screen_priv);
-
 #endif /*  _PRESENT_PRIV_H_ */
diff --git a/present/present_wnmd.c b/present/present_wnmd.c
index ea8aa3123..061698209 100644
--- a/present/present_wnmd.c
+++ b/present/present_wnmd.c
@@ -708,9 +708,26 @@ present_wnmd_flush(WindowPtr window)
     (*screen_priv->wnmd_info->flush) (window);
 }
 
-void
-present_wnmd_init_mode_hooks(present_screen_priv_ptr screen_priv)
+/*
+ * Initialize a screen for use with present in window flip mode (wnmd)
+ */
+int
+present_wnmd_screen_init(ScreenPtr screen, present_wnmd_info_ptr info)
 {
+    present_screen_priv_ptr screen_priv;
+
+    if (!present_screen_register_priv_keys())
+        return FALSE;
+
+    if (present_screen_priv(screen))
+        return TRUE;
+
+    screen_priv = present_screen_priv_init(screen);
+    if (!screen_priv)
+        return FALSE;
+
+    screen_priv->wnmd_info = info;
+
     screen_priv->query_capabilities =   &present_wnmd_query_capabilities;
     screen_priv->get_crtc           =   &present_wnmd_get_crtc;
 
@@ -724,25 +741,6 @@ present_wnmd_init_mode_hooks(present_screen_priv_ptr screen_priv)
     screen_priv->re_execute         =   &present_wnmd_re_execute;
 
     screen_priv->abort_vblank       =   &present_wnmd_abort_vblank;
-}
-
-/*
- * Initialize a screen for use with present in window flip mode (wnmd)
- */
-int
-present_wnmd_screen_init(ScreenPtr screen, present_wnmd_info_ptr info)
-{
-    if (!present_screen_register_priv_keys())
-        return FALSE;
-
-    if (!present_screen_priv(screen)) {
-        present_screen_priv_ptr screen_priv = present_screen_priv_init(screen);
-        if (!screen_priv)
-            return FALSE;
-
-        screen_priv->wnmd_info = info;
-        present_wnmd_init_mode_hooks(screen_priv);
-    }
 
     return TRUE;
 }
commit 10bdd87fe49cbd9b4c4b584024d663b928d3f1be
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Fri Apr 16 18:43:48 2021 +0200

    present: Move present_wnmd_screen_init to present_wnmd.c
    
    Now all WNMD code is in present_wnmd.c.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/present/present_priv.h b/present/present_priv.h
index 921184cc6..6d0588b1e 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -445,6 +445,11 @@ present_scmd_init_mode_hooks(present_screen_priv_ptr screen_priv);
 /*
  * present_screen.c
  */
+Bool
+present_screen_register_priv_keys(void);
+
+present_screen_priv_ptr
+present_screen_priv_init(ScreenPtr screen);
 
 /*
  * present_vblank.c
diff --git a/present/present_screen.c b/present/present_screen.c
index 7372c89d7..c2ae773a1 100644
--- a/present/present_screen.c
+++ b/present/present_screen.c
@@ -155,7 +155,7 @@ present_clip_notify(WindowPtr window, int dx, int dy)
     wrap(screen_priv, screen, ClipNotify, present_clip_notify);
 }
 
-static Bool
+Bool
 present_screen_register_priv_keys(void)
 {
     if (!dixRegisterPrivateKey(&present_screen_private_key, PRIVATE_SCREEN, 0))
@@ -167,7 +167,7 @@ present_screen_register_priv_keys(void)
     return TRUE;
 }
 
-static present_screen_priv_ptr
+present_screen_priv_ptr
 present_screen_priv_init(ScreenPtr screen)
 {
     present_screen_priv_ptr screen_priv;
@@ -186,27 +186,6 @@ present_screen_priv_init(ScreenPtr screen)
     return screen_priv;
 }
 
-/*
- * Initialize a screen for use with present in window flip mode (wnmd)
- */
-int
-present_wnmd_screen_init(ScreenPtr screen, present_wnmd_info_ptr info)
-{
-    if (!present_screen_register_priv_keys())
-        return FALSE;
-
-    if (!present_screen_priv(screen)) {
-        present_screen_priv_ptr screen_priv = present_screen_priv_init(screen);
-        if (!screen_priv)
-            return FALSE;
-
-        screen_priv->wnmd_info = info;
-        present_wnmd_init_mode_hooks(screen_priv);
-    }
-
-    return TRUE;
-}
-
 /*
  * Initialize a screen for use with present in default screen flip mode (scmd)
  */
diff --git a/present/present_wnmd.c b/present/present_wnmd.c
index d072d191a..ea8aa3123 100644
--- a/present/present_wnmd.c
+++ b/present/present_wnmd.c
@@ -725,3 +725,24 @@ present_wnmd_init_mode_hooks(present_screen_priv_ptr screen_priv)
 
     screen_priv->abort_vblank       =   &present_wnmd_abort_vblank;
 }
+
+/*
+ * Initialize a screen for use with present in window flip mode (wnmd)
+ */
+int
+present_wnmd_screen_init(ScreenPtr screen, present_wnmd_info_ptr info)
+{
+    if (!present_screen_register_priv_keys())
+        return FALSE;
+
+    if (!present_screen_priv(screen)) {
+        present_screen_priv_ptr screen_priv = present_screen_priv_init(screen);
+        if (!screen_priv)
+            return FALSE;
+
+        screen_priv->wnmd_info = info;
+        present_wnmd_init_mode_hooks(screen_priv);
+    }
+
+    return TRUE;
+}
commit b6d54b0f5d2fb3dc8a4b2812bfee94112c332256
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Wed Apr 21 17:01:36 2021 +0200

    present: Dispatch clear_window_flip via present_screen_priv hook
    
    Eliminates special cases in present_destroy_window.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/present/present_priv.h b/present/present_priv.h
index 5659c7e90..921184cc6 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -108,6 +108,7 @@ typedef Bool (*present_priv_check_flip_ptr)(RRCrtcPtr crtc,
                                             PresentFlipReason *reason);
 typedef void (*present_priv_check_flip_window_ptr)(WindowPtr window);
 typedef Bool (*present_priv_can_window_flip_ptr)(WindowPtr window);
+typedef void (*present_priv_clear_window_flip_ptr)(WindowPtr window);
 
 typedef int (*present_priv_pixmap_ptr)(WindowPtr window,
                                        PixmapPtr pixmap,
@@ -170,6 +171,7 @@ struct present_screen_priv {
     present_priv_check_flip_ptr         check_flip;
     present_priv_check_flip_window_ptr  check_flip_window;
     present_priv_can_window_flip_ptr    can_window_flip;
+    present_priv_clear_window_flip_ptr  clear_window_flip;
 
     present_priv_pixmap_ptr             present_pixmap;
 
diff --git a/present/present_scmd.c b/present/present_scmd.c
index cc21007e8..da836ea6b 100644
--- a/present/present_scmd.c
+++ b/present/present_scmd.c
@@ -495,6 +495,26 @@ present_scmd_can_window_flip(WindowPtr window)
     return TRUE;
 }
 
+/*
+ * Clean up any pending or current flips for this window
+ */
+static void
+present_scmd_clear_window_flip(WindowPtr window)
+{
+    ScreenPtr                   screen = window->drawable.pScreen;
+    present_screen_priv_ptr     screen_priv = present_screen_priv(screen);
+    present_vblank_ptr          flip_pending = screen_priv->flip_pending;
+
+    if (flip_pending && flip_pending->window == window) {
+        present_set_abort_flip(screen);
+        flip_pending->window = NULL;
+    }
+    if (screen_priv->flip_window == window) {
+        present_restore_screen_pixmap(screen);
+        screen_priv->flip_window = NULL;
+    }
+}
+
 /*
  * Once the required MSC has been reached, execute the pending request.
  *
@@ -812,6 +832,7 @@ present_scmd_init_mode_hooks(present_screen_priv_ptr screen_priv)
     screen_priv->check_flip         =   &present_check_flip;
     screen_priv->check_flip_window  =   &present_check_flip_window;
     screen_priv->can_window_flip    =   &present_scmd_can_window_flip;
+    screen_priv->clear_window_flip  =   &present_scmd_clear_window_flip;
 
     screen_priv->present_pixmap     =   &present_scmd_pixmap;
 
diff --git a/present/present_screen.c b/present/present_screen.c
index 05a810f5e..7372c89d7 100644
--- a/present/present_screen.c
+++ b/present/present_screen.c
@@ -86,50 +86,6 @@ present_free_window_vblank(WindowPtr window)
     }
 }
 
-/*
- * Clean up any pending or current flips for this window
- */
-static void
-present_clear_window_flip(WindowPtr window)
-{
-    ScreenPtr                   screen = window->drawable.pScreen;
-    present_screen_priv_ptr     screen_priv = present_screen_priv(screen);
-    present_vblank_ptr          flip_pending = screen_priv->flip_pending;
-
-    if (flip_pending && flip_pending->window == window) {
-        present_set_abort_flip(screen);
-        flip_pending->window = NULL;
-    }
-    if (screen_priv->flip_window == window) {
-        present_restore_screen_pixmap(screen);
-        screen_priv->flip_window = NULL;
-    }
-}
-
-static void
-present_wnmd_clear_window_flip(WindowPtr window)
-{
-    present_window_priv_ptr     window_priv = present_window_priv(window);
-    present_vblank_ptr          vblank, tmp;
-
-    xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->flip_queue, event_queue) {
-        present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
-        present_vblank_destroy(vblank);
-    }
-
-    xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->idle_queue, event_queue) {
-        present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
-        present_vblank_destroy(vblank);
-    }
-
-    vblank = window_priv->flip_active;
-    if (vblank) {
-        present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
-        present_vblank_destroy(vblank);
-    }
-    window_priv->flip_active = NULL;
-}
-
 /*
  * Hook the close window function to clean up our window private
  */
@@ -146,10 +102,7 @@ present_destroy_window(WindowPtr window)
         present_free_events(window);
         present_free_window_vblank(window);
 
-        if (screen_priv->wnmd_info)
-            present_wnmd_clear_window_flip(window);
-        else
-            present_clear_window_flip(window);
+        screen_priv->clear_window_flip(window);
 
         free(window_priv);
     }
diff --git a/present/present_wnmd.c b/present/present_wnmd.c
index 27c3e8ac7..d072d191a 100644
--- a/present/present_wnmd.c
+++ b/present/present_wnmd.c
@@ -373,6 +373,33 @@ present_wnmd_check_flip_window (WindowPtr window)
     }
 }
 
+/*
+ * Clean up any pending or current flips for this window
+ */
+static void
+present_wnmd_clear_window_flip(WindowPtr window)
+{
+    present_window_priv_ptr     window_priv = present_window_priv(window);
+    present_vblank_ptr          vblank, tmp;
+
+    xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->flip_queue, event_queue) {
+        present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
+        present_vblank_destroy(vblank);
+    }
+
+    xorg_list_for_each_entry_safe(vblank, tmp, &window_priv->idle_queue, event_queue) {
+        present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
+        present_vblank_destroy(vblank);
+    }
+
+    vblank = window_priv->flip_active;
+    if (vblank) {
+        present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
+        present_vblank_destroy(vblank);
+    }
+    window_priv->flip_active = NULL;
+}
+
 static Bool
 present_wnmd_flip(WindowPtr window,
                   RRCrtcPtr crtc,
@@ -689,6 +716,7 @@ present_wnmd_init_mode_hooks(present_screen_priv_ptr screen_priv)
 
     screen_priv->check_flip         =   &present_wnmd_check_flip;
     screen_priv->check_flip_window  =   &present_wnmd_check_flip_window;
+    screen_priv->clear_window_flip  =   &present_wnmd_clear_window_flip;
 
     screen_priv->present_pixmap     =   &present_wnmd_pixmap;
     screen_priv->queue_vblank       =   &present_wnmd_queue_vblank;
commit 93666ebe37a9c8d64b814c7af6b895f89ca5ff88
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Wed Apr 21 18:39:36 2021 +0200

    present: Remove create_event_id hook
    
    Each present_vblank_create caller generates and sets the ID afterwards.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/present/present_priv.h b/present/present_priv.h
index c50462cef..5659c7e90 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -126,9 +126,6 @@ typedef int (*present_priv_pixmap_ptr)(WindowPtr window,
                                        present_notify_ptr notifies,
                                        int num_notifies);
 
-typedef void (*present_priv_create_event_id_ptr)(present_window_priv_ptr window_priv,
-                                                 present_vblank_ptr vblank);
-
 typedef int (*present_priv_queue_vblank_ptr)(ScreenPtr screen,
                                              WindowPtr window,
                                              RRCrtcPtr crtc,
@@ -175,7 +172,6 @@ struct present_screen_priv {
     present_priv_can_window_flip_ptr    can_window_flip;
 
     present_priv_pixmap_ptr             present_pixmap;
-    present_priv_create_event_id_ptr    create_event_id;
 
     present_priv_queue_vblank_ptr       queue_vblank;
     present_priv_flush_ptr              flush;
@@ -223,7 +219,6 @@ struct present_window_priv {
     struct xorg_list       notifies;
 
     /* Used for window flips */
-    uint64_t               event_id;
     struct xorg_list       exec_queue;
     struct xorg_list       flip_queue;
     struct xorg_list       idle_queue;
diff --git a/present/present_scmd.c b/present/present_scmd.c
index c55ae0990..cc21007e8 100644
--- a/present/present_scmd.c
+++ b/present/present_scmd.c
@@ -35,20 +35,14 @@
  *
  */
 
-static uint64_t         present_event_id;
+static uint64_t present_scmd_event_id;
+
 static struct xorg_list present_exec_queue;
 static struct xorg_list present_flip_queue;
 
 static void
 present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc);
 
-static void
-present_scmd_create_event_id(present_window_priv_ptr window_priv,
-                             present_vblank_ptr vblank)
-{
-    vblank->event_id = ++present_event_id;
-}
-
 static inline PixmapPtr
 present_flip_pending_pixmap(ScreenPtr screen)
 {
@@ -326,7 +320,7 @@ present_unflip(ScreenPtr screen)
 
     present_restore_screen_pixmap(screen);
 
-    screen_priv->unflip_event_id = ++present_event_id;
+    screen_priv->unflip_event_id = ++present_scmd_event_id;
     DebugPresent(("u %" PRIu64 "\n", screen_priv->unflip_event_id));
     (*screen_priv->info->unflip) (screen, screen_priv->unflip_event_id);
 }
@@ -745,6 +739,8 @@ present_scmd_pixmap(WindowPtr window,
     if (!vblank)
         return BadAlloc;
 
+    vblank->event_id = ++present_scmd_event_id;
+
     if (vblank->flip && vblank->sync_flip)
         vblank->exec_msc--;
 
@@ -818,7 +814,6 @@ present_scmd_init_mode_hooks(present_screen_priv_ptr screen_priv)
     screen_priv->can_window_flip    =   &present_scmd_can_window_flip;
 
     screen_priv->present_pixmap     =   &present_scmd_pixmap;
-    screen_priv->create_event_id    =   &present_scmd_create_event_id;
 
     screen_priv->queue_vblank       =   &present_queue_vblank;
     screen_priv->flush              =   &present_flush;
diff --git a/present/present_vblank.c b/present/present_vblank.c
index 6ab0d35f1..4401395d7 100644
--- a/present/present_vblank.c
+++ b/present/present_vblank.c
@@ -77,8 +77,6 @@ present_vblank_create(WindowPtr window,
     vblank->window = window;
     vblank->pixmap = pixmap;
 
-    screen_priv->create_event_id(window_priv, vblank);
-
     if (pixmap) {
         vblank->kind = PresentCompleteKindPixmap;
         pixmap->refcnt++;
diff --git a/present/present_wnmd.c b/present/present_wnmd.c
index 9e70d83b3..27c3e8ac7 100644
--- a/present/present_wnmd.c
+++ b/present/present_wnmd.c
@@ -35,6 +35,8 @@
  *
  */
 
+static uint64_t present_wnmd_event_id;
+
 static void
 present_wnmd_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc);
 
@@ -49,12 +51,6 @@ present_wnmd_queue_vblank(ScreenPtr 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)
-{
-    vblank->event_id = ++window_priv->event_id;
-}
-
 static uint32_t
 present_wnmd_query_capabilities(present_screen_priv_ptr screen_priv)
 {
@@ -631,6 +627,8 @@ present_wnmd_pixmap(WindowPtr window,
     if (!vblank)
         return BadAlloc;
 
+    vblank->event_id = ++present_wnmd_event_id;
+
     /* WNMD presentations always complete (at least) one frame after they
      * are executed
      */
@@ -693,7 +691,6 @@ present_wnmd_init_mode_hooks(present_screen_priv_ptr screen_priv)
     screen_priv->check_flip_window  =   &present_wnmd_check_flip_window;
 
     screen_priv->present_pixmap     =   &present_wnmd_pixmap;
-    screen_priv->create_event_id    =   &present_wnmd_create_event_id;
     screen_priv->queue_vblank       =   &present_wnmd_queue_vblank;
     screen_priv->flush              =   &present_wnmd_flush;
     screen_priv->re_execute         =   &present_wnmd_re_execute;
commit 44f705a5b6b4f79682c5e649eb718a193e01ec47
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Mon Apr 19 18:19:30 2021 +0200

    present: Pass capabilities to present_vblank_create by value
    
    Preparation for moving WNMD code to hw/xwayland. No functional change
    intended.
    
    Acked-by: Olivier Fourdan <ofourdan at redhat.com>

diff --git a/present/present_priv.h b/present/present_priv.h
index eb0c20fbb..c50462cef 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -467,7 +467,7 @@ present_vblank_create(WindowPtr window,
                       SyncFence *wait_fence,
                       SyncFence *idle_fence,
                       uint32_t options,
-                      const uint32_t *capabilities,
+                      const uint32_t capabilities,
                       present_notify_ptr notifies,
                       int num_notifies,
                       uint64_t target_msc,
diff --git a/present/present_scmd.c b/present/present_scmd.c
index c8c701d72..c55ae0990 100644
--- a/present/present_scmd.c
+++ b/present/present_scmd.c
@@ -736,7 +736,7 @@ present_scmd_pixmap(WindowPtr window,
                                    wait_fence,
                                    idle_fence,
                                    options,
-                                   screen_priv->info ? &screen_priv->info->capabilities : NULL,
+                                   screen_priv->info ? screen_priv->info->capabilities : 0,
                                    notifies,
                                    num_notifies,
                                    target_msc,
diff --git a/present/present_vblank.c b/present/present_vblank.c
index b46370982..6ab0d35f1 100644
--- a/present/present_vblank.c
+++ b/present/present_vblank.c
@@ -50,7 +50,7 @@ present_vblank_create(WindowPtr window,
                       SyncFence *wait_fence,
                       SyncFence *idle_fence,
                       uint32_t options,
-                      const uint32_t *capabilities,
+                      const uint32_t capabilities,
                       present_notify_ptr notifies,
                       int num_notifies,
                       uint64_t target_msc,
@@ -111,13 +111,13 @@ present_vblank_create(WindowPtr window,
 
     if (pixmap != NULL &&
         !(options & PresentOptionCopy) &&
-        capabilities) {
+        screen_priv->check_flip) {
         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;
-        } else if ((*capabilities & PresentCapabilityAsync) &&
+        } else if ((capabilities & PresentCapabilityAsync) &&
             screen_priv->check_flip (target_crtc, window, pixmap, FALSE, valid, x_off, y_off, &reason))
         {
             vblank->flip = TRUE;
diff --git a/present/present_wnmd.c b/present/present_wnmd.c
index aed10dae3..9e70d83b3 100644
--- a/present/present_wnmd.c
+++ b/present/present_wnmd.c
@@ -623,7 +623,7 @@ present_wnmd_pixmap(WindowPtr window,
                                    wait_fence,
                                    idle_fence,
                                    options,
-                                   &screen_priv->wnmd_info->capabilities,
+                                   screen_priv->wnmd_info->capabilities,
                                    notifies,
                                    num_notifies,
                                    target_msc,


More information about the xorg-commit mailing list