xserver: Branch 'xwayland-22.1'

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Mar 25 07:43:01 UTC 2022


 hw/xwayland/xwayland-present.c |   17 ++++++++++-------
 hw/xwayland/xwayland-present.h |    3 +++
 hw/xwayland/xwayland-window.c  |   12 ++++++++++++
 3 files changed, 25 insertions(+), 7 deletions(-)

New commits:
commit 1a7e4e72182cf530504ea88053b0652872da3c13
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Tue Mar 15 17:47:56 2022 +0100

    xwayland: Always hook up frame_callback_list in xwl_present_queue_vblank
    
    Even if there's no pending frame callback yet.
    
    Without this, if there was no pending frame callback yet in
    xwl_present_queue_vblank, xwl_present_msc_bump would only get called
    from xwl_present_timer_callback, resulting in the MSC ticking at ~58
    Hertz.
    
    Doing this requires some adjustments elsewhere:
    
    1. xwl_present_reset_timer needs to check for a pending frame callback
       as well.
    2. xwl_window_create_frame_callback needs to call
       xwl_present_reset_timer for all child windows hooked up to
       frame_callback_list, to make sure the timer length takes the pending
       frame callback into account.
    3. xwl_present_flip needs to hook up the window to frame_callback_list
       before calling xwl_window_create_frame_callback, for 2. to work.
    
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1309
    Fixes: 9b31358c52e9 ("xwayland: Use frame callbacks for Present vblank events")
    Reviewed-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 9e5a3796108e2b89212fa440f80e918d24b971c8)

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index d727f8419..ce74482ef 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -66,6 +66,7 @@ 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();
 
@@ -127,14 +128,16 @@ xwl_present_has_pending_events(struct xwl_present_window *xwl_present_window)
            !xorg_list_is_empty(&xwl_present_window->wait_list);
 }
 
-static void
+void
 xwl_present_reset_timer(struct xwl_present_window *xwl_present_window)
 {
     if (xwl_present_has_pending_events(xwl_present_window)) {
+        struct xwl_window *xwl_window = xwl_window_from_window(xwl_present_window->window);
         CARD32 now = GetTimeInMillis();
         CARD32 timeout;
 
-        if (!xorg_list_is_empty(&xwl_present_window->frame_callback_list))
+        if (xwl_window && xwl_window->frame_callback &&
+            !xorg_list_is_empty(&xwl_present_window->frame_callback_list))
             timeout = TIMER_LEN_FLIP;
         else
             timeout = TIMER_LEN_COPY;
@@ -505,8 +508,8 @@ xwl_present_queue_vblank(ScreenPtr screen,
     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 &&
+    /* Hook up to frame callback */
+    if (xwl_window &&
         xorg_list_is_empty(&xwl_present_window->frame_callback_list)) {
         xorg_list_add(&xwl_present_window->frame_callback_list,
                       &xwl_window->frame_callback_list);
@@ -700,14 +703,14 @@ 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_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);
     }
 
+    if (!xwl_window->frame_callback)
+        xwl_window_create_frame_callback(xwl_window);
+
     xwl_surface_damage(xwl_window->xwl_screen, xwl_window->surface,
                        damage_box->x1 - present_window->drawable.x,
                        damage_box->y1 - present_window->drawable.y,
diff --git a/hw/xwayland/xwayland-present.h b/hw/xwayland/xwayland-present.h
index 5d880e822..ab7f04a3b 100644
--- a/hw/xwayland/xwayland-present.h
+++ b/hw/xwayland/xwayland-present.h
@@ -35,6 +35,8 @@
 
 #ifdef GLAMOR_HAS_GBM
 struct xwl_present_window {
+    WindowPtr window;
+
     struct xorg_list frame_callback_list;
 
     uint64_t msc;
@@ -59,6 +61,7 @@ struct xwl_present_event {
     PixmapPtr pixmap;
 };
 
+void xwl_present_reset_timer(struct xwl_present_window *xwl_present_window);
 void xwl_present_frame_callback(struct xwl_present_window *xwl_present_window);
 Bool xwl_present_init(ScreenPtr screen);
 void xwl_present_cleanup(WindowPtr window);
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index 92bcae326..41061e344 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -765,6 +765,18 @@ 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);
+
+#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_reset_timer(xwl_present_window);
+        }
+    }
+#endif
 }
 
 Bool


More information about the xorg-commit mailing list