xserver: Branch 'server-1.20-branch' - 3 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Mar 4 22:45:05 UTC 2020


 hw/xwayland/xwayland-present.c |   62 +++++++++++++++++++----------------------
 hw/xwayland/xwayland.c         |   38 +++++++++++++++++++------
 hw/xwayland/xwayland.h         |    8 +++--
 3 files changed, 64 insertions(+), 44 deletions(-)

New commits:
commit 2a185dd22ddb5b0d7d2ef5948591028766bb9530
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Mon Mar 2 18:09:31 2020 +0100

    xwayland: Use frame callbacks for Present vblank events
    
    Instead of only the fallback timer.
    
    Fixes https://gitlab.freedesktop.org/xorg/xserver/issues/854
    
    v2:
    * Drop unused frame_callback member of struct xwl_present_window
      (Olivier Fourdan)
    
    Reviewed-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 9b31358c52e951883bf7c01c953a9da080542244)

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index baa97d6f3..c7c077aaa 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -242,7 +242,10 @@ xwl_present_timer_callback(OsTimerPtr timer,
 {
     struct xwl_present_window *xwl_present_window = arg;
 
-    xwl_present_window->frame_timer_firing = TRUE;
+    /* If we were expecting a frame callback for this window, it didn't arrive
+     * in a second. Stop listening to it to avoid double-bumping the MSC
+     */
+    xorg_list_del(&xwl_present_window->frame_callback_list);
 
     xwl_present_msc_bump(xwl_present_window);
     xwl_present_reset_timer(xwl_present_window);
@@ -255,11 +258,6 @@ xwl_present_frame_callback(struct xwl_present_window *xwl_present_window)
 {
     xorg_list_del(&xwl_present_window->frame_callback_list);
 
-    if (xwl_present_window->frame_timer_firing) {
-        /* If the timer is firing, this frame callback is too late */
-        return;
-    }
-
     xwl_present_msc_bump(xwl_present_window);
 
     /* we do not need the timer anymore for this frame,
@@ -349,6 +347,7 @@ xwl_present_queue_vblank(WindowPtr present_window,
                          uint64_t msc)
 {
     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);
@@ -361,7 +360,15 @@ xwl_present_queue_vblank(WindowPtr present_window,
 
     xorg_list_append(&event->list, &xwl_present_window->event_list);
 
-    if (!xwl_present_window->frame_timer)
+    /* If there's a pending frame callback, use that */
+    if (xwl_window && xwl_window->frame_callback &&
+        xorg_list_is_empty(&xwl_present_window->frame_callback_list)) {
+        xorg_list_add(&xwl_present_window->frame_callback_list,
+                      &xwl_window->frame_callback_list);
+    }
+
+    if ((xwl_window && xwl_window->frame_callback) ||
+        !xwl_present_window->frame_timer)
         xwl_present_reset_timer(xwl_present_window);
 
     return Success;
@@ -486,7 +493,6 @@ xwl_present_flip(WindowPtr present_window,
     }
 
     /* Realign timer */
-    xwl_present_window->frame_timer_firing = FALSE;
     xwl_present_reset_timer(xwl_present_window);
 
     wl_surface_damage(xwl_window->surface, 0, 0,
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index d4eb6bf1a..a12ec257b 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -199,9 +199,7 @@ struct xwl_present_window {
     uint64_t ust;
 
     OsTimerPtr frame_timer;
-    Bool frame_timer_firing;
 
-    struct wl_callback *frame_callback;
     struct wl_callback *sync_callback;
 
     struct xorg_list event_list;
commit 99a6d6b15e0757a4652a569a1b2070c76a00b567
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Wed Nov 27 18:04:06 2019 +0100

    xwayland: Use single frame callback for Present flips and normal updates
    
    Using a list of Present windows that need to be called back.
    
    This prepares for the following change, there should be no change in
    observed behaviour.
    
    v2:
    * Use xwl_window_create_frame_callback instead of making the
      frame_listener struct non-static (Olivier Fourdan)
    
    Reviewed-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit c5067feaeea115761f0a72f37407c6e5e943d1a1)

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 31c276623..baa97d6f3 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -60,6 +60,7 @@ xwl_present_window_get_priv(WindowPtr window)
         xwl_present_window->msc = 1;
         xwl_present_window->ust = GetTimeInMicros();
 
+        xorg_list_init(&xwl_present_window->frame_callback_list);
         xorg_list_init(&xwl_present_window->event_list);
         xorg_list_init(&xwl_present_window->release_queue);
 
@@ -96,7 +97,7 @@ xwl_present_reset_timer(struct xwl_present_window *xwl_present_window)
     if (xwl_present_has_events(xwl_present_window)) {
         CARD32 timeout;
 
-        if (xwl_present_window->frame_callback)
+        if (!xorg_list_is_empty(&xwl_present_window->frame_callback_list))
             timeout = TIMER_LEN_FLIP;
         else
             timeout = TIMER_LEN_COPY;
@@ -119,10 +120,7 @@ xwl_present_cleanup(WindowPtr window)
     if (!xwl_present_window)
         return;
 
-    if (xwl_present_window->frame_callback) {
-        wl_callback_destroy(xwl_present_window->frame_callback);
-        xwl_present_window->frame_callback = NULL;
-    }
+    xorg_list_del(&xwl_present_window->frame_callback_list);
 
     if (xwl_present_window->sync_callback) {
         wl_callback_destroy(xwl_present_window->sync_callback);
@@ -252,15 +250,10 @@ xwl_present_timer_callback(OsTimerPtr timer,
     return 0;
 }
 
-static void
-xwl_present_frame_callback(void *data,
-               struct wl_callback *callback,
-               uint32_t time)
+void
+xwl_present_frame_callback(struct xwl_present_window *xwl_present_window)
 {
-    struct xwl_present_window *xwl_present_window = data;
-
-    wl_callback_destroy(xwl_present_window->frame_callback);
-    xwl_present_window->frame_callback = NULL;
+    xorg_list_del(&xwl_present_window->frame_callback_list);
 
     if (xwl_present_window->frame_timer_firing) {
         /* If the timer is firing, this frame callback is too late */
@@ -275,10 +268,6 @@ xwl_present_frame_callback(void *data,
     xwl_present_reset_timer(xwl_present_window);
 }
 
-static const struct wl_callback_listener xwl_present_frame_listener = {
-    xwl_present_frame_callback
-};
-
 static void
 xwl_present_sync_callback(void *data,
                struct wl_callback *callback,
@@ -488,11 +477,12 @@ xwl_present_flip(WindowPtr present_window,
     /* We can flip directly to the main surface (full screen window without clips) */
     wl_surface_attach(xwl_window->surface, buffer, 0, 0);
 
-    if (!xwl_present_window->frame_callback) {
-        xwl_present_window->frame_callback = wl_surface_frame(xwl_window->surface);
-        wl_callback_add_listener(xwl_present_window->frame_callback,
-                                 &xwl_present_frame_listener,
-                                 xwl_present_window);
+    if (!xwl_window->frame_callback)
+        xwl_window_create_frame_callback(xwl_window);
+
+    if (xorg_list_is_empty(&xwl_present_window->frame_callback_list)) {
+        xorg_list_add(&xwl_present_window->frame_callback_list,
+                      &xwl_window->frame_callback_list);
     }
 
     /* Realign timer */
@@ -532,14 +522,14 @@ xwl_present_unrealize_window(WindowPtr window)
 {
     struct xwl_present_window *xwl_present_window = xwl_present_window_priv(window);
 
-    if (!xwl_present_window || !xwl_present_window->frame_callback)
+    if (!xwl_present_window ||
+        xorg_list_is_empty(&xwl_present_window->frame_callback_list))
         return;
 
     /* The pending frame callback may never be called, so drop it and shorten
      * the frame timer interval.
      */
-    wl_callback_destroy(xwl_present_window->frame_callback);
-    xwl_present_window->frame_callback = NULL;
+    xorg_list_del(&xwl_present_window->frame_callback_list);
     xwl_present_reset_timer(xwl_present_window);
 }
 
diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index ef01842f0..feb1058b7 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -600,6 +600,10 @@ ensure_surface_for_window(WindowPtr window)
     dixSetPrivate(&window->devPrivates, &xwl_window_private_key, xwl_window);
     xorg_list_init(&xwl_window->link_damage);
 
+#ifdef GLAMOR_HAS_GBM
+    xorg_list_init(&xwl_window->frame_callback_list);
+#endif
+
     xwl_window_init_allow_commits(xwl_window);
 
     return TRUE;
@@ -684,11 +688,6 @@ xwl_unrealize_window(WindowPtr window)
     xwl_screen->UnrealizeWindow = screen->UnrealizeWindow;
     screen->UnrealizeWindow = xwl_unrealize_window;
 
-#ifdef GLAMOR_HAS_GBM
-    if (xwl_screen->present)
-        xwl_present_unrealize_window(window);
-#endif
-
     xwl_window = xwl_window_get(window);
     if (!xwl_window)
         return ret;
@@ -700,6 +699,11 @@ xwl_unrealize_window(WindowPtr window)
     if (xwl_window->frame_callback)
         wl_callback_destroy(xwl_window->frame_callback);
 
+#ifdef GLAMOR_HAS_GBM
+    if (xwl_screen->present)
+        xwl_present_unrealize_window(window);
+#endif
+
     free(xwl_window);
     dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL);
 
@@ -741,6 +745,18 @@ frame_callback(void *data,
 
     wl_callback_destroy (xwl_window->frame_callback);
     xwl_window->frame_callback = NULL;
+
+#ifdef GLAMOR_HAS_GBM
+    if (xwl_window->xwl_screen->present) {
+        struct xwl_present_window *xwl_present_window, *tmp;
+
+        xorg_list_for_each_entry_safe(xwl_present_window, tmp,
+                                      &xwl_window->frame_callback_list,
+                                      frame_callback_list) {
+            xwl_present_frame_callback(xwl_present_window);
+        }
+    }
+#endif
 }
 
 static const struct wl_callback_listener frame_listener = {
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index d20016c5d..d4eb6bf1a 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -183,6 +183,7 @@ struct xwl_window {
     struct wl_callback *frame_callback;
     Bool allow_commits;
 #ifdef GLAMOR_HAS_GBM
+    struct xorg_list frame_callback_list;
     Bool present_flipped;
 #endif
 };
@@ -192,7 +193,7 @@ struct xwl_present_window {
     struct xwl_screen *xwl_screen;
     struct xwl_present_event *sync_flip;
     WindowPtr window;
-    struct xorg_list link;
+    struct xorg_list frame_callback_list;
 
     uint64_t msc;
     uint64_t ust;
@@ -454,6 +455,7 @@ Bool xwl_glamor_allow_commits(struct xwl_window *xwl_window);
 void xwl_glamor_egl_make_current(struct xwl_screen *xwl_screen);
 
 #ifdef GLAMOR_HAS_GBM
+void xwl_present_frame_callback(struct xwl_present_window *xwl_present_window);
 Bool xwl_present_init(ScreenPtr screen);
 void xwl_present_cleanup(WindowPtr window);
 void xwl_present_unrealize_window(WindowPtr window);
commit 915cc107767624bd7914c962347bab9c2e21cdff
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Fri Dec 13 18:26:35 2019 +0100

    xwayland: Add xwl_window_create_frame_callback helper
    
    This will be used by the following changes. No functional change
    intended.
    
    Reviewed-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit f80eea0529b2cfb805a9c7d4994a4235451131e3)

diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index d3a4684d2..ef01842f0 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -747,6 +747,14 @@ static const struct wl_callback_listener frame_listener = {
     frame_callback
 };
 
+void
+xwl_window_create_frame_callback(struct xwl_window *xwl_window)
+{
+    xwl_window->frame_callback = wl_surface_frame(xwl_window->surface);
+    wl_callback_add_listener(xwl_window->frame_callback, &frame_listener,
+                             xwl_window);
+}
+
 static Bool
 xwl_destroy_window(WindowPtr window)
 {
@@ -817,9 +825,7 @@ xwl_window_post_damage(struct xwl_window *xwl_window)
                               box->x2 - box->x1, box->y2 - box->y1);
     }
 
-    xwl_window->frame_callback = wl_surface_frame(xwl_window->surface);
-    wl_callback_add_listener(xwl_window->frame_callback, &frame_listener, xwl_window);
-
+    xwl_window_create_frame_callback(xwl_window);
     DamageEmpty(window_get_damage(xwl_window->window));
 }
 
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 0854df456..d20016c5d 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -378,6 +378,8 @@ struct xwl_output {
     Bool xdg_output_done;
 };
 
+void xwl_window_create_frame_callback(struct xwl_window *xwl_window);
+
 void xwl_sync_events (struct xwl_screen *xwl_screen);
 
 Bool xwl_screen_init_cursor(struct xwl_screen *xwl_screen);


More information about the xorg-commit mailing list