diff --git a/hw/xwayland/xwayland-glamor-gbm.c b/hw/xwayland/xwayland-glamor-gbm.c index f7f78560c..9518d49ab 100644 --- a/hw/xwayland/xwayland-glamor-gbm.c +++ b/hw/xwayland/xwayland-glamor-gbm.c @@ -1707,6 +1707,21 @@ xwl_glamor_gbm_init_main_dev(struct xwl_screen *xwl_screen) return TRUE; } +void +xwl_glamor_gbm_cleanup_egl(struct xwl_screen *xwl_screen) +{ + if (!xwl_screen->glamor) + return; + + if (xwl_screen->egl_display != EGL_NO_DISPLAY) { + xwl_glamor_maybe_destroy_context(xwl_screen); + eglTerminate(xwl_screen->egl_display); + xwl_screen->egl_display = EGL_NO_DISPLAY; + } + + xwl_glamor_gbm_cleanup(xwl_screen); +} + Bool xwl_glamor_gbm_init_egl(struct xwl_screen *xwl_screen) { @@ -1845,7 +1860,7 @@ skip_drm_auth: return TRUE; error: - xwl_glamor_gbm_cleanup(xwl_screen); + xwl_glamor_gbm_cleanup_egl(xwl_screen); return FALSE; } diff --git a/hw/xwayland/xwayland-glamor-gbm.h b/hw/xwayland/xwayland-glamor-gbm.h index b346a0ba6..039deba77 100644 --- a/hw/xwayland/xwayland-glamor-gbm.h +++ b/hw/xwayland/xwayland-glamor-gbm.h @@ -40,6 +40,7 @@ Bool xwl_glamor_init_gbm(struct xwl_screen *xwl_screen); Bool xwl_glamor_has_wl_drm(struct xwl_screen *xwl_screen); Bool xwl_glamor_gbm_init_egl(struct xwl_screen *xwl_screen); Bool xwl_glamor_gbm_init_screen(struct xwl_screen *xwl_screen); +void xwl_glamor_gbm_cleanup_egl(struct xwl_screen *xwl_screen); drmDevice *xwl_gbm_get_main_device(struct xwl_screen *xwl_screen); /* Explicit buffer synchronization points */ diff --git a/hw/xwayland/xwayland-glamor.c b/hw/xwayland/xwayland-glamor.c index b7f98d3ac..870f44599 100644 --- a/hw/xwayland/xwayland-glamor.c +++ b/hw/xwayland/xwayland-glamor.c @@ -50,6 +50,8 @@ #include +#include + static void glamor_egl_make_current(struct glamor_context *glamor_ctx) { @@ -268,3 +270,23 @@ xwl_glamor_init(struct xwl_screen *xwl_screen) return TRUE; } + +void +xwl_glamor_cleanup_all_screens(void) +{ + int i; + + for (i = 0; i < screenInfo.numScreens; i++) { + ScreenPtr screen = screenInfo.screens[i]; + struct xwl_screen *xwl_screen; + + if (!screen) + continue; + + xwl_screen = xwl_screen_get(screen); + if (!xwl_screen) + continue; + + xwl_glamor_gbm_cleanup_egl(xwl_screen); + } +} diff --git a/hw/xwayland/xwayland-glamor.h b/hw/xwayland/xwayland-glamor.h index ef312a857..0a20e590d 100644 --- a/hw/xwayland/xwayland-glamor.h +++ b/hw/xwayland/xwayland-glamor.h @@ -47,6 +47,7 @@ typedef enum _xwl_glamor_mode_flags{ #ifdef XWL_HAS_GLAMOR Bool xwl_glamor_init(struct xwl_screen *xwl_screen); +void xwl_glamor_cleanup_all_screens(void); Bool xwl_screen_set_drm_interface(struct xwl_screen *xwl_screen, uint32_t id, uint32_t version); diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c index 0a21c449c..9fc752167 100644 --- a/hw/xwayland/xwayland-screen.c +++ b/hw/xwayland/xwayland-screen.c @@ -91,6 +91,10 @@ xwl_give_up(const char *f, ...) VErrorFSigSafe(f, args); va_end(args); +#ifdef XWL_HAS_GLAMOR + xwl_glamor_cleanup_all_screens(); +#endif + CloseWellKnownConnections(); OsCleanup(TRUE); fflush(stderr); @@ -237,9 +241,11 @@ Bool xwl_close_screen(ScreenPtr screen) { struct xwl_screen *xwl_screen = xwl_screen_get(screen); + CloseScreenProcPtr close_screen = xwl_screen->CloseScreen; struct xwl_output *xwl_output, *next_xwl_output; struct xwl_seat *xwl_seat, *next_xwl_seat; struct xwl_wl_surface *xwl_wl_surface, *xwl_wl_surface_next; + Bool ret; #ifdef XWL_HAS_GLAMOR xwl_dmabuf_feedback_destroy(&xwl_screen->default_feedback); #endif @@ -281,13 +287,18 @@ xwl_close_screen(ScreenPtr screen) RemoveNotifyFd(xwl_screen->wayland_fd); - wl_display_disconnect(xwl_screen->display); + screen->CloseScreen = close_screen; + ret = close_screen(screen); - screen->CloseScreen = xwl_screen->CloseScreen; +#ifdef XWL_HAS_GLAMOR + xwl_glamor_gbm_cleanup_egl(xwl_screen); +#endif + + wl_display_disconnect(xwl_screen->display); free(xwl_screen); - return screen->CloseScreen(screen); + return ret; } static struct xwl_seat * @@ -1180,6 +1191,7 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) #ifdef XWL_HAS_GLAMOR if (xwl_screen->glamor && !xwl_glamor_init(xwl_screen)) { ErrorF("Failed to initialize glamor, falling back to sw\n"); + xwl_glamor_gbm_cleanup_egl(xwl_screen); xwl_screen->glamor = XWL_GLAMOR_NONE; } #endif diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c index d0be6028e..f8760cba0 100644 --- a/hw/xwayland/xwayland.c +++ b/hw/xwayland/xwayland.c @@ -61,6 +61,9 @@ extern _X_EXPORT Bool noXFree86VidModeExtension; void ddxGiveUp(enum ExitCode error) { +#ifdef XWL_HAS_GLAMOR + xwl_glamor_cleanup_all_screens(); +#endif } void