From f2d598b9a19cd7151c592e9c74d5b0d0ba3c9e48 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 18 May 2019 19:15:47 +0000 Subject: [PATCH] wayland: Keep some resources until destroy The Wayland backend was dropping _all_ serverside resources on hide, which is too early e.g. for GtkGLArea which wants to use egl resources to unload textures on unrealize. Closes: https://gitlab.gnome.org/GNOME/gtk/issues/1485 --- gdk/wayland/gdksurface-wayland.c | 89 +++++++++++++++++++------------- 1 file changed, 54 insertions(+), 35 deletions(-) diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c index f92a8ce2ad..c192c3b09d 100644 --- a/gdk/wayland/gdksurface-wayland.c +++ b/gdk/wayland/gdksurface-wayland.c @@ -2549,39 +2549,15 @@ unmap_popups_for_surface (GdkSurface *surface) } static void -gdk_wayland_surface_hide_surface (GdkSurface *surface) +gdk_wayland_surface_unmap_surface (GdkSurface *surface) { GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); unmap_popups_for_surface (surface); - if (impl->display_server.wl_surface) + if (impl->display_server.xdg_surface) { - if (impl->dummy_egl_surface) - { - eglDestroySurface (display_wayland->egl_display, impl->dummy_egl_surface); - impl->dummy_egl_surface = NULL; - } - - if (impl->display_server.dummy_egl_window) - { - wl_egl_window_destroy (impl->display_server.dummy_egl_window); - impl->display_server.dummy_egl_window = NULL; - } - - if (impl->egl_surface) - { - eglDestroySurface (display_wayland->egl_display, impl->egl_surface); - impl->egl_surface = NULL; - } - - if (impl->display_server.egl_window) - { - wl_egl_window_destroy (impl->display_server.egl_window); - impl->display_server.egl_window = NULL; - } - if (impl->display_server.xdg_toplevel) { xdg_toplevel_destroy (impl->display_server.xdg_toplevel); @@ -2643,12 +2619,6 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface) impl->application.was_set = FALSE; } - wl_surface_destroy (impl->display_server.wl_surface); - impl->display_server.wl_surface = NULL; - - g_slist_free (impl->display_server.outputs); - impl->display_server.outputs = NULL; - if (impl->hint == GDK_SURFACE_TYPE_HINT_DIALOG && !impl->transient_for) display_wayland->orphan_dialogs = g_list_remove (display_wayland->orphan_dialogs, surface); @@ -2661,10 +2631,58 @@ gdk_wayland_surface_hide_surface (GdkSurface *surface) impl->mapped = FALSE; } +static void +gdk_wayland_surface_destroy_surface (GdkSurface *surface) +{ + GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface)); + GdkSurfaceImplWayland *impl = GDK_SURFACE_IMPL_WAYLAND (surface->impl); + + if (impl->display_server.wl_surface) + { + if (impl->dummy_egl_surface) + { + eglDestroySurface (display_wayland->egl_display, impl->dummy_egl_surface); + impl->dummy_egl_surface = NULL; + } + + if (impl->display_server.dummy_egl_window) + { + wl_egl_window_destroy (impl->display_server.dummy_egl_window); + impl->display_server.dummy_egl_window = NULL; + } + + if (impl->egl_surface) + { + eglDestroySurface (display_wayland->egl_display, impl->egl_surface); + impl->egl_surface = NULL; + } + + if (impl->display_server.egl_window) + { + wl_egl_window_destroy (impl->display_server.egl_window); + impl->display_server.egl_window = NULL; + } + + g_assert (impl->display_server.xdg_toplevel == NULL); + g_assert (impl->display_server.xdg_popup == NULL); + g_assert (impl->display_server.xdg_surface == NULL); + g_assert (impl->display_server.zxdg_toplevel_v6 == NULL); + g_assert (impl->display_server.zxdg_popup_v6 == NULL); + g_assert (impl->display_server.zxdg_surface_v6 == NULL); + g_assert (impl->display_server.gtk_surface == NULL); + + wl_surface_destroy (impl->display_server.wl_surface); + impl->display_server.wl_surface = NULL; + + g_slist_free (impl->display_server.outputs); + impl->display_server.outputs = NULL; + } +} + static void gdk_wayland_surface_hide (GdkSurface *surface) { - gdk_wayland_surface_hide_surface (surface); + gdk_wayland_surface_unmap_surface (surface); _gdk_surface_clear_update_area (surface); } @@ -2678,7 +2696,7 @@ gdk_surface_wayland_withdraw (GdkSurface *surface) g_assert (!GDK_SURFACE_IS_MAPPED (surface)); - gdk_wayland_surface_hide_surface (surface); + gdk_wayland_surface_unmap_surface (surface); } } @@ -2881,7 +2899,8 @@ gdk_wayland_surface_destroy (GdkSurface *surface, */ g_return_if_fail (!foreign_destroy); - gdk_wayland_surface_hide_surface (surface); + gdk_wayland_surface_unmap_surface (surface); + gdk_wayland_surface_destroy_surface (surface); if (surface->parent == NULL) {