xserver: Branch 'xwayland-22.1' - 8 commits

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Apr 27 11:48:35 UTC 2023


 glamor/glamor.c                |    2 
 hw/xwayland/meson.build        |    6 +-
 hw/xwayland/xwayland-present.c |   27 +++++++++
 hw/xwayland/xwayland-present.h |    3 +
 hw/xwayland/xwayland-screen.c  |    5 +
 hw/xwayland/xwayland-window.c  |  121 +++++++++++++++++++++--------------------
 hw/xwayland/xwayland.c         |    3 -
 include/meson.build            |    2 
 8 files changed, 103 insertions(+), 66 deletions(-)

New commits:
commit f8d6ae3877aacaeea2876f2dad054278895708b8
Author: Jonas Ådahl <jadahl at gmail.com>
Date:   Fri Mar 31 16:01:20 2023 +0200

    xwayland/window: Queue damage after commits are allowed
    
    Compositors may use XWAYLAND_ALLOW_COMMITS to communicate when Xwayland
    may or may not commit new buffers to a wl_surface. If commits are
    denied, then later allowed, we'll only get a buffer attached if there is
    actual damage posted, which might be long after.
    
    This fixes an issue where the window manager would reparent a window
    while denying commits, then after reparenting, allow commits. The window
    in question belonged to a game and took several seconds produce the next
    frame, resulting in an empty window appearing as if it had just
    disappeared.
    
    Signed-off-by: Jonas Ådahl <jadahl at gmail.com>
    (cherry picked from commit 9a55c402aa803fb10e39ab4fd18a709d0cd06fd4)

diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index 462d27a57..1b904166d 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -102,9 +102,21 @@ static void
 xwl_window_set_allow_commits(struct xwl_window *xwl_window, Bool allow,
                              const char *debug_msg)
 {
+    struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
+    DamagePtr damage;
+
     xwl_window->allow_commits = allow;
     DebugF("XWAYLAND: win %d allow_commits = %d (%s)\n",
            xwl_window->window->drawable.id, allow, debug_msg);
+
+    damage = window_get_damage(xwl_window->window);
+    if (allow &&
+        xorg_list_is_empty(&xwl_window->link_damage) &&
+        damage &&
+        RegionNotEmpty(DamageRegion(damage))) {
+        xorg_list_add(&xwl_window->link_damage,
+                      &xwl_screen->damage_window_list);
+    }
 }
 
 static void
commit 3bf134075e6ffe172a2604e013423c4ceff923e8
Author: Jonas Ådahl <jadahl at gmail.com>
Date:   Wed Apr 26 09:37:23 2023 +0200

    xwayland/window: Move set-allow functions lower down
    
    This will make some helper functions in the same file usable without
    extra declarations.
    
    Signed-off-by: Jonas Ådahl <jadahl at gmail.com>
    (cherry picked from commit 5ce96a2a733b0a6556e1512fd9a703ede6a7c959)

diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index 6c11dbc37..462d27a57 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -52,41 +52,6 @@ static DevPrivateKeyRec xwl_window_private_key;
 static DevPrivateKeyRec xwl_damage_private_key;
 static const char *xwl_surface_tag = "xwl-surface";
 
-static void
-xwl_window_set_allow_commits(struct xwl_window *xwl_window, Bool allow,
-                             const char *debug_msg)
-{
-    xwl_window->allow_commits = allow;
-    DebugF("xwayland: win %d allow_commits = %d (%s)\n",
-           xwl_window->window->drawable.id, allow, debug_msg);
-}
-
-static void
-xwl_window_set_allow_commits_from_property(struct xwl_window *xwl_window,
-                                           PropertyPtr prop)
-{
-    static Bool warned = FALSE;
-    CARD32 *propdata;
-
-    if (prop->propertyName != xwl_window->xwl_screen->allow_commits_prop)
-        FatalError("Xwayland internal error: prop mismatch in %s.\n", __func__);
-
-    if (prop->type != XA_CARDINAL || prop->format != 32 || prop->size != 1) {
-        /* Not properly set, so fall back to safe and glitchy */
-        xwl_window_set_allow_commits(xwl_window, TRUE, "WM fault");
-
-        if (!warned) {
-            LogMessageVerb(X_WARNING, 0, "Window manager is misusing property %s.\n",
-                           NameForAtom(prop->propertyName));
-            warned = TRUE;
-        }
-        return;
-    }
-
-    propdata = prop->data;
-    xwl_window_set_allow_commits(xwl_window, !!propdata[0], "from property");
-}
-
 struct xwl_window *
 xwl_window_get(WindowPtr window)
 {
@@ -133,6 +98,41 @@ is_surface_from_xwl_window(struct wl_surface *surface)
     return wl_proxy_get_tag((struct wl_proxy *) surface) == &xwl_surface_tag;
 }
 
+static void
+xwl_window_set_allow_commits(struct xwl_window *xwl_window, Bool allow,
+                             const char *debug_msg)
+{
+    xwl_window->allow_commits = allow;
+    DebugF("XWAYLAND: win %d allow_commits = %d (%s)\n",
+           xwl_window->window->drawable.id, allow, debug_msg);
+}
+
+static void
+xwl_window_set_allow_commits_from_property(struct xwl_window *xwl_window,
+                                           PropertyPtr prop)
+{
+    static Bool warned = FALSE;
+    CARD32 *propdata;
+
+    if (prop->propertyName != xwl_window->xwl_screen->allow_commits_prop)
+        FatalError("Xwayland internal error: prop mismatch in %s.\n", __func__);
+
+    if (prop->type != XA_CARDINAL || prop->format != 32 || prop->size != 1) {
+        /* Not properly set, so fall back to safe and glitchy */
+        xwl_window_set_allow_commits(xwl_window, TRUE, "WM fault");
+
+        if (!warned) {
+            LogMessageVerb(X_WARNING, 0, "Window manager is misusing property %s.\n",
+                           NameForAtom(prop->propertyName));
+            warned = TRUE;
+        }
+        return;
+    }
+
+    propdata = prop->data;
+    xwl_window_set_allow_commits(xwl_window, !!propdata[0], "from property");
+}
+
 void
 xwl_window_update_property(struct xwl_window *xwl_window,
                            PropertyStateRec *propstate)
commit 415bb04758a8c346d8e6e42e42cc27d011c8d4fd
Author: Simon Ser <contact at emersion.fr>
Date:   Sat Feb 18 11:29:25 2023 +0100

    build: set _GNU_SOURCE when checking for SO_PEERCRED
    
    SO_PEERCRED is not POSIX, so might be hidden unless _GNU_SOURCE
    is defined.
    
    See [1]: cc.has_header_symbol() does not inherit the project
    arguments.
    
    [1]: https://github.com/mesonbuild/meson/issues/3301
    
    Signed-off-by: Simon Ser <contact at emersion.fr>
    (cherry picked from commit 636c9aa359eab45102c12a9fccb8f60587c7d485)

diff --git a/include/meson.build b/include/meson.build
index a6c7fa368..a9d80abad 100644
--- a/include/meson.build
+++ b/include/meson.build
@@ -177,7 +177,7 @@ if cc.has_header_symbol('sys/socket.h', 'SCM_RIGHTS')
 endif
 
 if conf_data.get('HAVE_GETPEEREID').to_int() == 0 and conf_data.get('HAVE_GETPEERUCRED').to_int() == 0
-    if not cc.has_header_symbol('sys/socket.h', 'SO_PEERCRED')
+    if not cc.has_header_symbol('sys/socket.h', 'SO_PEERCRED', args: '-D_GNU_SOURCE')
         conf_data.set('NO_LOCAL_CLIENT_CRED', 1)
     endif
 endif
commit 18e7250309919b005c0261af1872d74b66d84afb
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Thu Apr 6 16:13:17 2023 +0200

    xwayland: Fix build without GBM
    
    The present code in Xwayland cannot be used without GBM, so if GBM is
    not available (or too old), the build would fail.
    
    Make sure we do not use the present code without GBM support.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit da0de3caf62023d2b507ed3d66a0b0daa7104c4a)

diff --git a/hw/xwayland/meson.build b/hw/xwayland/meson.build
index 37c39497c..178fd0e3c 100644
--- a/hw/xwayland/meson.build
+++ b/hw/xwayland/meson.build
@@ -91,7 +91,10 @@ if build_glamor
         srcs += 'xwayland-glx.c'
     endif
     if gbm_dep.found()
-        srcs += 'xwayland-glamor-gbm.c'
+        srcs += [
+                  'xwayland-glamor-gbm.c',
+                  'xwayland-present.c'
+                ]
     endif
     if build_eglstream
         eglstream_protodir = eglstream_dep.get_pkgconfig_variable('pkgdatadir')
@@ -105,7 +108,6 @@ if build_glamor
 
         srcs += 'xwayland-glamor-eglstream.c'
     endif
-    srcs += 'xwayland-present.c'
     if build_xv
         srcs += 'xwayland-glamor-xv.c'
     endif
diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c
index 812d60dfc..884143bf0 100644
--- a/hw/xwayland/xwayland-screen.c
+++ b/hw/xwayland/xwayland-screen.c
@@ -794,10 +794,11 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
            xwl_screen->glamor = 0;
         }
     }
-
+#ifdef GLAMOR_HAS_GBM
     if (xwl_screen->glamor && xwl_screen->rootless)
         xwl_screen->present = xwl_present_init(pScreen);
-#endif
+#endif /* GLAMOR_HAS_GBM */
+#endif /* XWL_HAS_GLAMOR */
 
     if (!xwl_screen->glamor) {
         xwl_screen->CreateScreenResources = pScreen->CreateScreenResources;
commit 594029dd9008cb7fbd42bf48f7a9f6217cdf333e
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Thu Apr 6 16:12:54 2023 +0200

    glamor: Fix build without GBM
    
    The functions glamor_egl_fd_from_pixmap()/glamor_egl_fds_from_pixmap()
    are not available without GBM support.
    
    So if GBM is not available or too old, the code would fail to link
    trying to find the references to those functions.
    
    Make sure we skip that code when glamor is built without GBM.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit c24910d0e138dc1dc58c0c0cdc10b49a1ed85975)

diff --git a/glamor/glamor.c b/glamor/glamor.c
index b8e8f2b8f..7083ac112 100644
--- a/glamor/glamor.c
+++ b/glamor/glamor.c
@@ -990,6 +990,7 @@ _glamor_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
                         uint32_t *strides, uint32_t *offsets,
                         CARD32 *size, uint64_t *modifier)
 {
+#ifdef GLAMOR_HAS_GBM
     glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap);
     glamor_screen_private *glamor_priv =
         glamor_get_screen_private(pixmap->drawable.pScreen);
@@ -1017,6 +1018,7 @@ _glamor_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
     default:
         break;
     }
+#endif /* GLAMOR_HAS_GBM */
     return 0;
 }
 
commit 2297527aaa29753784141b34a684cc105c91468b
Author: Olivier Fourdan <ofourdan at redhat.com>
Date:   Wed Mar 8 11:46:13 2023 +0100

    xwayland: Make Wayland logs non-fatal
    
    The Wayland library may log warnings, we do not need to make that fatal
    to the Xserver.
    
    By killing the Xserver whenever a warning is raised, we hide other log
    messages that might be also interesting.
    
    Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 62b1fac0b5c5b9eeeca7a66cba6398c211acc504)

diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 603e8be4f..174aed5e3 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -266,14 +266,13 @@ wm_selection_callback(CallbackListPtr *p, void *data, void *arg)
     DeleteCallback(&SelectionCallback, wm_selection_callback, xwl_screen);
 }
 
-_X_NORETURN
 static void _X_ATTRIBUTE_PRINTF(1, 0)
 xwl_log_handler(const char *format, va_list args)
 {
     char msg[256];
 
     vsnprintf(msg, sizeof msg, format, args);
-    FatalError("%s", msg);
+    ErrorF("XWAYLAND: %s", msg);
 }
 
 static const ExtensionModule xwayland_extensions[] = {
commit 2cb8e5e1e68b0a3ebe49dc03355b71ffeb94aa54
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Fri Mar 10 12:39:30 2023 +0100

    xwayland: Prevent nested xwl_present_for_each_frame_callback calls
    
    It could happen with the following call path:
    
    frame_callback
     xwl_present_frame_callback
      xwl_present_msc_bump
       xwl_present_execute
        xwl_present_flip
         xwl_window_create_frame_callback
    
    The nested loop called xwl_present_reset_timer, which may end up calling
    xorg_list_del for the entry after the one frame_callback started the
    chain for. This resulted in the outer loop never terminating, because
    its next element wasn't hooked up to the list anymore.
    
    We avoid this by calling xwl_present_reset_timer as needed in
    frame_callback, and bailing from xwl_window_create_frame_callback if it
    was called from the former.
    
    We also catch nested calls and FatalError if they ever happen again due
    to another bug.
    
    v2:
    * Leave xwl_present_reset_timer call in xwl_present_frame_callback,
      needed if xwl_present_msc_bump didn't hook up the window to the frame
      callback list again.
    
    Closes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1442
    (cherry picked from commit 754d6b6dd0a9ec42d75247596a8885bf54352ee7)

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 9f03ba5f0..0d6459b92 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -89,16 +89,31 @@ xwl_present_event_from_id(uint64_t event_id)
     return (struct xwl_present_event*)(uintptr_t)event_id;
 }
 
+static Bool entered_for_each_frame_callback;
+
+Bool
+xwl_present_entered_for_each_frame_callback(void)
+{
+    return entered_for_each_frame_callback;
+}
+
 void
 xwl_present_for_each_frame_callback(struct xwl_window *xwl_window,
                                     void iter_func(struct xwl_present_window *))
 {
     struct xwl_present_window *xwl_present_window, *tmp;
 
+    if (entered_for_each_frame_callback)
+        FatalError("Nested xwl_present_for_each_frame_callback call");
+
+    entered_for_each_frame_callback = TRUE;
+
     xorg_list_for_each_entry_safe(xwl_present_window, tmp,
                                   &xwl_window->frame_callback_list,
                                   frame_callback_list)
         iter_func(xwl_present_window);
+
+    entered_for_each_frame_callback = FALSE;
 }
 
 static void
diff --git a/hw/xwayland/xwayland-present.h b/hw/xwayland/xwayland-present.h
index 620e6c5ca..806272089 100644
--- a/hw/xwayland/xwayland-present.h
+++ b/hw/xwayland/xwayland-present.h
@@ -61,6 +61,7 @@ struct xwl_present_event {
     PixmapPtr pixmap;
 };
 
+Bool xwl_present_entered_for_each_frame_callback(void);
 void xwl_present_for_each_frame_callback(struct xwl_window *xwl_window,
                                          void iter_func(struct xwl_present_window *));
 void xwl_present_reset_timer(struct xwl_present_window *xwl_present_window);
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index 4e6d85a57..6c11dbc37 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -815,8 +815,16 @@ frame_callback(void *data,
     xwl_window->frame_callback = NULL;
 
 #ifdef GLAMOR_HAS_GBM
-    if (xwl_window->xwl_screen->present)
+    if (xwl_window->xwl_screen->present) {
         xwl_present_for_each_frame_callback(xwl_window, xwl_present_frame_callback);
+
+        /* If xwl_window_create_frame_callback was called from
+         * xwl_present_frame_callback, need to make sure all fallback timers
+         * are adjusted correspondingly.
+         */
+        if (xwl_window->frame_callback)
+            xwl_present_for_each_frame_callback(xwl_window, xwl_present_reset_timer);
+    }
 #endif
 }
 
@@ -832,7 +840,11 @@ xwl_window_create_frame_callback(struct xwl_window *xwl_window)
                              xwl_window);
 
 #ifdef GLAMOR_HAS_GBM
-    if (xwl_window->xwl_screen->present)
+    /* If we get called from frame_callback, it will take care of calling
+     * xwl_present_reset_timer.
+     */
+    if (xwl_window->xwl_screen->present &&
+        !xwl_present_entered_for_each_frame_callback())
         xwl_present_for_each_frame_callback(xwl_window, xwl_present_reset_timer);
 #endif
 }
commit c74e1e40724c0d33fa29cdb727a1f606c555ae54
Author: Michel Dänzer <mdaenzer at redhat.com>
Date:   Thu Mar 9 18:44:25 2023 +0100

    xwayland: Refactor xwl_present_for_each_frame_callback helper
    
    Preparation for following changes, no functional change intended.
    
    (cherry picked from commit 4d1cd7cdc22013ed8de17d3218b9790b7027e1fe)

diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c
index 99e476b2f..9f03ba5f0 100644
--- a/hw/xwayland/xwayland-present.c
+++ b/hw/xwayland/xwayland-present.c
@@ -89,6 +89,18 @@ xwl_present_event_from_id(uint64_t event_id)
     return (struct xwl_present_event*)(uintptr_t)event_id;
 }
 
+void
+xwl_present_for_each_frame_callback(struct xwl_window *xwl_window,
+                                    void iter_func(struct xwl_present_window *))
+{
+    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)
+        iter_func(xwl_present_window);
+}
+
 static void
 xwl_present_free_timer(struct xwl_present_window *xwl_present_window)
 {
diff --git a/hw/xwayland/xwayland-present.h b/hw/xwayland/xwayland-present.h
index ab7f04a3b..620e6c5ca 100644
--- a/hw/xwayland/xwayland-present.h
+++ b/hw/xwayland/xwayland-present.h
@@ -61,6 +61,8 @@ struct xwl_present_event {
     PixmapPtr pixmap;
 };
 
+void xwl_present_for_each_frame_callback(struct xwl_window *xwl_window,
+                                         void iter_func(struct xwl_present_window *));
 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);
diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c
index ba7d7af0b..4e6d85a57 100644
--- a/hw/xwayland/xwayland-window.c
+++ b/hw/xwayland/xwayland-window.c
@@ -685,15 +685,8 @@ xwl_unrealize_window(WindowPtr window)
         xwl_window_disable_viewport(xwl_window);
 
 #ifdef GLAMOR_HAS_GBM
-    if (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_unrealize_window(xwl_present_window);
-        }
-    }
+    if (xwl_window->xwl_screen->present)
+        xwl_present_for_each_frame_callback(xwl_window, xwl_present_unrealize_window);
 #endif
 
     release_wl_surface_for_window(xwl_window);
@@ -822,15 +815,8 @@ frame_callback(void *data,
     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);
-        }
-    }
+    if (xwl_window->xwl_screen->present)
+        xwl_present_for_each_frame_callback(xwl_window, xwl_present_frame_callback);
 #endif
 }
 
@@ -846,15 +832,8 @@ xwl_window_create_frame_callback(struct xwl_window *xwl_window)
                              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);
-        }
-    }
+    if (xwl_window->xwl_screen->present)
+        xwl_present_for_each_frame_callback(xwl_window, xwl_present_reset_timer);
 #endif
 }
 


More information about the xorg-commit mailing list