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

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Sep 10 15:22:20 UTC 2019


 hw/xwayland/xwayland.c |  159 ++++++++++++++++++++++++++++++++++++++-----------
 hw/xwayland/xwayland.h |    2 
 2 files changed, 125 insertions(+), 36 deletions(-)

New commits:
commit 63346c74393e1df4555f84367529802a67578ef6
Author: Carlos Garnacho <carlosg at gnome.org>
Date:   Mon Jan 7 15:33:35 2019 +0100

    xwayland: Handle the case of windows being realized before redirection
    
    If Xwayland gets to realize a window meant for composition before the
    compositor redirected windows (i.e. redirect mode is not RedirectDrawManual
    yet), the window would stay "invisible" as we wouldn't create a
    wl_surface/wl_shell_surface for it at any later point.
    
    This scenario may happen if the wayland compositor sets up a X11 socket
    upfront, but waits to raise Xwayland until there are X11 clients. In this
    case the first data on the socket is the client's, the compositor can hardly
    beat that in order to redirect subwindows before the client realizes a
    Window.
    
    In order to jump across this hurdle, allow the late creation of a matching
    (shell) surface for the WindowPtr on SetWindowPixmapProc, so it is ensured
    to be created after the compositor set up redirection.
    
    Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
    Reviewed-by: Michel Dänzer <mdaenzer at redhat.com>
    Reviewed-by: Olivier Fourdan <ofourdan at redhat.com>
    (cherry picked from commit 78cc8b6f9613fc71f6ecc7e8848d54364a250634)

diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 9a4b52fa9..baa08d87b 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -700,6 +700,26 @@ xwl_save_screen(ScreenPtr pScreen, int on)
 }
 
 static void
+xwl_set_window_pixmap(WindowPtr window,
+                      PixmapPtr pixmap)
+{
+    ScreenPtr screen = window->drawable.pScreen;
+    struct xwl_screen *xwl_screen;
+
+    xwl_screen = xwl_screen_get(screen);
+
+    screen->SetWindowPixmap = xwl_screen->SetWindowPixmap;
+    (*screen->SetWindowPixmap) (window, pixmap);
+    xwl_screen->SetWindowPixmap = screen->SetWindowPixmap;
+    screen->SetWindowPixmap = xwl_set_window_pixmap;
+
+    if (!RegionNotEmpty(&window->winSize))
+        return;
+
+    ensure_surface_for_window(window);
+}
+
+static void
 frame_callback(void *data,
                struct wl_callback *callback,
                uint32_t time)
@@ -1185,6 +1205,11 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
     xwl_screen->CloseScreen = pScreen->CloseScreen;
     pScreen->CloseScreen = xwl_close_screen;
 
+    if (xwl_screen->rootless) {
+        xwl_screen->SetWindowPixmap = pScreen->SetWindowPixmap;
+        pScreen->SetWindowPixmap = xwl_set_window_pixmap;
+    }
+
     pScreen->CursorWarpedTo = xwl_cursor_warped_to;
     pScreen->CursorConfinedTo = xwl_cursor_confined_to;
 
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index dfa3b37c3..0854df456 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -133,6 +133,7 @@ struct xwl_screen {
     UnrealizeWindowProcPtr UnrealizeWindow;
     DestroyWindowProcPtr DestroyWindow;
     XYToWindowProcPtr XYToWindow;
+    SetWindowPixmapProcPtr SetWindowPixmap;
 
     struct xorg_list output_list;
     struct xorg_list seat_list;
commit 12db645c7fc0539752a881df7ac2bcd09e3cb17b
Author: Carlos Garnacho <carlosg at gnome.org>
Date:   Mon Jan 7 15:33:31 2019 +0100

    xwayland: Refactor surface creation into a separate function
    
    This is just called from xwl_window_realize() ATM, but will be useful in
    future commits.
    
    Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
    (cherry picked from commit c2e8ae964052944312c5023ca7ea5c41a92990e5)

diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 1efebd061..9a4b52fa9 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -518,36 +518,25 @@ send_surface_id_event(struct xwl_window *xwl_window)
 }
 
 static Bool
-xwl_realize_window(WindowPtr window)
+ensure_surface_for_window(WindowPtr window)
 {
     ScreenPtr screen = window->drawable.pScreen;
     struct xwl_screen *xwl_screen;
     struct xwl_window *xwl_window;
     struct wl_region *region;
-    Bool ret;
-
-    xwl_screen = xwl_screen_get(screen);
-
-    screen->RealizeWindow = xwl_screen->RealizeWindow;
-    ret = (*screen->RealizeWindow) (window);
-    xwl_screen->RealizeWindow = screen->RealizeWindow;
-    screen->RealizeWindow = xwl_realize_window;
 
-    if (xwl_screen->rootless && !window->parent) {
-        BoxRec box = { 0, 0, xwl_screen->width, xwl_screen->height };
+    if (xwl_window_get(window))
+        return TRUE;
 
-        RegionReset(&window->winSize, &box);
-        RegionNull(&window->clipList);
-        RegionNull(&window->borderClip);
-    }
+    xwl_screen = xwl_screen_get(screen);
 
     if (xwl_screen->rootless) {
         if (window->redirectDraw != RedirectDrawManual)
-            return ret;
+            return TRUE;
     }
     else {
         if (window->parent)
-            return ret;
+            return TRUE;
     }
 
     xwl_window = calloc(1, sizeof *xwl_window);
@@ -595,15 +584,12 @@ xwl_realize_window(WindowPtr window)
 
     compRedirectWindow(serverClient, window, CompositeRedirectManual);
 
-    if (!register_damage(window))
-        goto err_surf;
-
     dixSetPrivate(&window->devPrivates, &xwl_window_private_key, xwl_window);
     xorg_list_init(&xwl_window->link_damage);
 
     xwl_window_init_allow_commits(xwl_window);
 
-    return ret;
+    return TRUE;
 
 err_surf:
     if (xwl_window->shell_surface)
@@ -615,6 +601,42 @@ err:
 }
 
 static Bool
+xwl_realize_window(WindowPtr window)
+{
+    ScreenPtr screen = window->drawable.pScreen;
+    struct xwl_screen *xwl_screen;
+    Bool ret;
+
+    xwl_screen = xwl_screen_get(screen);
+
+    screen->RealizeWindow = xwl_screen->RealizeWindow;
+    ret = (*screen->RealizeWindow) (window);
+    xwl_screen->RealizeWindow = screen->RealizeWindow;
+    screen->RealizeWindow = xwl_realize_window;
+
+    if (!ret)
+        return FALSE;
+
+    if (xwl_screen->rootless && !window->parent) {
+        BoxRec box = { 0, 0, xwl_screen->width, xwl_screen->height };
+
+        RegionReset(&window->winSize, &box);
+        RegionNull(&window->clipList);
+        RegionNull(&window->borderClip);
+    }
+
+    if (xwl_screen->rootless ?
+        (window->drawable.class == InputOutput &&
+         window->parent == window->drawable.pScreen->root) :
+        !window->parent) {
+        if (!register_damage(window))
+            return FALSE;
+    }
+
+    return ensure_surface_for_window(window);
+}
+
+static Bool
 xwl_unrealize_window(WindowPtr window)
 {
     ScreenPtr screen = window->drawable.pScreen;
commit e0af09061f9e8397ca564ec3bbedea51974455d4
Author: Carlos Garnacho <carlosg at gnome.org>
Date:   Mon Jan 7 15:20:05 2019 +0100

    xwayland: Separate DamagePtr into separate window data
    
    This will be dissociated in future commits to handle the cases
    where windows are being realized before there is a compositor
    handling redirection.
    
    In that case, we still want the DamagePtr to be registered upfront
    on RealizeWindowProc before a corresponding xwl_window might be
    created. Most notably, it cannot be lazily created on
    SetWindowPixmapProc as damage accounting gets broken.
    
    Signed-off-by: Carlos Garnacho <carlosg at gnome.org>
    (cherry picked from commit 4e50440ae20c537d6a4edf356cda67dd33d4e5a8)

diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c
index 7e6e0ab25..1efebd061 100644
--- a/hw/xwayland/xwayland.c
+++ b/hw/xwayland/xwayland.c
@@ -125,6 +125,7 @@ ddxProcessArgument(int argc, char *argv[], int i)
 static DevPrivateKeyRec xwl_window_private_key;
 static DevPrivateKeyRec xwl_screen_private_key;
 static DevPrivateKeyRec xwl_pixmap_private_key;
+static DevPrivateKeyRec xwl_damage_private_key;
 
 static struct xwl_window *
 xwl_window_get(WindowPtr window)
@@ -367,8 +368,14 @@ xwl_cursor_confined_to(DeviceIntPtr device,
 static void
 damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data)
 {
-    struct xwl_window *xwl_window = data;
-    struct xwl_screen *xwl_screen = xwl_window->xwl_screen;
+    WindowPtr window = data;
+    struct xwl_window *xwl_window = xwl_window_get(window);
+    struct xwl_screen *xwl_screen;
+
+    if (!xwl_window)
+        return;
+
+    xwl_screen = xwl_window->xwl_screen;
 
 #ifdef GLAMOR_HAS_GBM
     if (xwl_window->present_flipped) {
@@ -390,6 +397,47 @@ damage_destroy(DamagePtr pDamage, void *data)
 {
 }
 
+static Bool
+register_damage(WindowPtr window)
+{
+    DamagePtr damage;
+
+    damage = DamageCreate(damage_report, damage_destroy, DamageReportNonEmpty,
+                          FALSE, window->drawable.pScreen, window);
+    if (damage == NULL) {
+        ErrorF("Failed creating damage\n");
+        return FALSE;
+    }
+
+    DamageRegister(&window->drawable, damage);
+    DamageSetReportAfterOp(damage, TRUE);
+
+    dixSetPrivate(&window->devPrivates, &xwl_damage_private_key, damage);
+
+    return TRUE;
+}
+
+static void
+unregister_damage(WindowPtr window)
+{
+    DamagePtr damage;
+
+    damage = dixLookupPrivate(&window->devPrivates, &xwl_damage_private_key);
+    if (!damage)
+        return;
+
+    DamageUnregister(damage);
+    DamageDestroy(damage);
+
+    dixSetPrivate(&window->devPrivates, &xwl_damage_private_key, NULL);
+}
+
+static DamagePtr
+window_get_damage(WindowPtr window)
+{
+    return dixLookupPrivate(&window->devPrivates, &xwl_damage_private_key);
+}
+
 static void
 shell_surface_ping(void *data,
                    struct wl_shell_surface *shell_surface, uint32_t serial)
@@ -545,18 +593,10 @@ xwl_realize_window(WindowPtr window)
 
     wl_surface_set_user_data(xwl_window->surface, xwl_window);
 
-    xwl_window->damage =
-        DamageCreate(damage_report, damage_destroy, DamageReportNonEmpty,
-                     FALSE, screen, xwl_window);
-    if (xwl_window->damage == NULL) {
-        ErrorF("Failed creating damage\n");
-        goto err_surf;
-    }
-
     compRedirectWindow(serverClient, window, CompositeRedirectManual);
 
-    DamageRegister(&window->drawable, xwl_window->damage);
-    DamageSetReportAfterOp(xwl_window->damage, TRUE);
+    if (!register_damage(window))
+        goto err_surf;
 
     dixSetPrivate(&window->devPrivates, &xwl_window_private_key, xwl_window);
     xorg_list_init(&xwl_window->link_damage);
@@ -620,8 +660,8 @@ xwl_unrealize_window(WindowPtr window)
 
     wl_surface_destroy(xwl_window->surface);
     xorg_list_del(&xwl_window->link_damage);
-    DamageUnregister(xwl_window->damage);
-    DamageDestroy(xwl_window->damage);
+    unregister_damage(window);
+
     if (xwl_window->frame_callback)
         wl_callback_destroy(xwl_window->frame_callback);
 
@@ -689,7 +729,7 @@ xwl_window_post_damage(struct xwl_window *xwl_window)
 
     assert(!xwl_window->frame_callback);
 
-    region = DamageRegion(xwl_window->damage);
+    region = DamageRegion(window_get_damage(xwl_window->window));
     pixmap = (*xwl_screen->screen->GetWindowPixmap) (xwl_window->window);
 
 #ifdef XWL_HAS_GLAMOR
@@ -726,7 +766,7 @@ xwl_window_post_damage(struct xwl_window *xwl_window)
     wl_callback_add_listener(xwl_window->frame_callback, &frame_listener, xwl_window);
 
     wl_surface_commit(xwl_window->surface);
-    DamageEmpty(xwl_window->damage);
+    DamageEmpty(window_get_damage(xwl_window->window));
 
     xorg_list_del(&xwl_window->link_damage);
 }
@@ -962,6 +1002,8 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
         return FALSE;
     if (!dixRegisterPrivateKey(&xwl_pixmap_private_key, PRIVATE_PIXMAP, 0))
         return FALSE;
+    if (!dixRegisterPrivateKey(&xwl_damage_private_key, PRIVATE_WINDOW, 0))
+        return FALSE;
 
     dixSetPrivate(&pScreen->devPrivates, &xwl_screen_private_key, xwl_screen);
     xwl_screen->screen = pScreen;
diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
index 463622669..dfa3b37c3 100644
--- a/hw/xwayland/xwayland.h
+++ b/hw/xwayland/xwayland.h
@@ -178,7 +178,6 @@ struct xwl_window {
     struct wl_surface *surface;
     struct wl_shell_surface *shell_surface;
     WindowPtr window;
-    DamagePtr damage;
     struct xorg_list link_damage;
     struct wl_callback *frame_callback;
     Bool allow_commits;


More information about the xorg-commit mailing list