From b5ce235e033114337d73516b0b9c35d8b249bdf0 Mon Sep 17 00:00:00 2001 From: Martijn Courteaux Date: Tue, 1 Oct 2024 18:59:20 +0200 Subject: [PATCH] Dynamically load libwayland-egl.so.1 when dealing with Wayland to remove dependencies at program startup. --- examples/common/entry/entry_sdl.cpp | 13 --------- scripts/genie.lua | 29 ++++++------------- src/glcontext_egl.cpp | 44 +++++++++++++++++++++++++++-- src/glcontext_egl.h | 2 ++ 4 files changed, 51 insertions(+), 37 deletions(-) diff --git a/examples/common/entry/entry_sdl.cpp b/examples/common/entry/entry_sdl.cpp index c37468e1074..ed57ba73f3f 100644 --- a/examples/common/entry/entry_sdl.cpp +++ b/examples/common/entry/entry_sdl.cpp @@ -8,9 +8,6 @@ #if ENTRY_CONFIG_USE_SDL #if BX_PLATFORM_LINUX -# if ENTRY_CONFIG_USE_WAYLAND -# include -# endif #elif BX_PLATFORM_WINDOWS # define SDL_MAIN_HANDLED #endif @@ -68,16 +65,6 @@ namespace entry { if(!_window) return; -# if BX_PLATFORM_LINUX -# if ENTRY_CONFIG_USE_WAYLAND - wl_egl_window *win_impl = (wl_egl_window*)SDL_GetWindowData(_window, "wl_egl_window"); - if(win_impl) - { - SDL_SetWindowData(_window, "wl_egl_window", nullptr); - wl_egl_window_destroy(win_impl); - } -# endif -# endif SDL_DestroyWindow(_window); } diff --git a/scripts/genie.lua b/scripts/genie.lua index 477f8f9bfd4..1bbb57687f7 100644 --- a/scripts/genie.lua +++ b/scripts/genie.lua @@ -22,7 +22,7 @@ newoption { newoption { trigger = "with-wayland", - description = "Use Wayland backend.", + description = "Enable Wayland support.", } newoption { @@ -235,13 +235,6 @@ function exampleProjectDefaults() defines { "ENTRY_CONFIG_USE_SDL=1" } links { "SDL2" } - configuration { "linux or freebsd" } - if _OPTIONS["with-wayland"] then - links { - "wayland-egl", - } - end - configuration { "osx*" } libdirs { "$(SDL2_DIR)/lib" } @@ -253,19 +246,13 @@ function exampleProjectDefaults() links { "glfw3" } configuration { "linux or freebsd" } - if _OPTIONS["with-wayland"] then - links { - "wayland-egl", - } - else - links { - "Xrandr", - "Xinerama", - "Xi", - "Xxf86vm", - "Xcursor", - } - end + links { + "Xrandr", + "Xinerama", + "Xi", + "Xxf86vm", + "Xcursor", + } configuration { "osx*" } linkoptions { diff --git a/src/glcontext_egl.cpp b/src/glcontext_egl.cpp index cf0777b6439..7cab52aff9e 100644 --- a/src/glcontext_egl.cpp +++ b/src/glcontext_egl.cpp @@ -128,6 +128,39 @@ EGL_IMPORT } #endif // BGFX_USE_GL_DYNAMIC_LIB + +#if defined(WL_EGL_PLATFORM) +#define WL_EGL_IMPORT \ + WL_EGL_FUNC(struct wl_egl_window *, wl_egl_window_create, (struct wl_surface *, int, int)) \ + WL_EGL_FUNC(void, wl_egl_window_destroy, (struct wl_egl_window *)) \ + WL_EGL_FUNC(void, wl_egl_window_resize, (struct wl_egl_window *, int, int, int, int)) \ + WL_EGL_FUNC(void, wl_egl_window_get_attached_size, (struct wl_egl_window *, int *, int *)) \ + +#define WL_EGL_FUNC(rt, fname, params) \ + typedef rt(*PFNWLEGL_##fname) params; \ + PFNWLEGL_##fname BGFX_WAYLAND_##fname; +WL_EGL_IMPORT +#undef WL_EGL_FUNC + + void *waylandEglOpen() { + void *so = bx::dlopen("libwayland-egl.so.1"); + BGFX_FATAL(so != NULL, Fatal::UnableToInitialize, "Could not dlopen() libwayland-egl.so.1"); + +#define WL_EGL_FUNC(rt, fname, params) BGFX_WAYLAND_##fname = (PFNWLEGL_##fname) bx::dlsym(so, #fname); + WL_EGL_IMPORT +#undef WL_EGL_FUNC + + return so; + } + + void waylandEglClose(void *so) { + bx::dlclose(so); +#define WL_EGL_FUNC(rt, fname, params) BGFX_WAYLAND_##fname = NULL; + WL_EGL_IMPORT +#undef WL_EGL_FUNC + } +#endif + # define GL_IMPORT(_optional, _proto, _func, _import) _proto _func = NULL # include "glimports.h" @@ -335,9 +368,11 @@ EGL_IMPORT # if BX_PLATFORM_LINUX && defined(WL_EGL_PLATFORM) if (g_platformData.type == NativeWindowHandleType::Wayland) { + m_waylandEglLibrary = waylandEglOpen(); + // A wl_surface needs to be first wrapped in a wl_egl_window // before it can be used to create the EGLSurface. - m_egl_window = wl_egl_window_create((wl_surface*)nwh, _width, _height); + m_egl_window = BGFX_WAYLAND_wl_egl_window_create((wl_surface*)nwh, _width, _height); nwh = m_egl_window; } # endif @@ -444,7 +479,9 @@ EGL_IMPORT EGL_CHECK(eglDestroySurface(m_display, m_surface) ); # if BX_PLATFORM_LINUX && defined(WL_EGL_PLATFORM) if (m_egl_window) { - wl_egl_window_destroy(m_egl_window); + BGFX_WAYLAND_wl_egl_window_destroy(m_egl_window); + waylandEglClose(m_waylandEglLibrary); + m_waylandEglLibrary = NULL; } # endif EGL_CHECK(eglTerminate(m_display) ); @@ -453,6 +490,7 @@ EGL_IMPORT EGL_CHECK(eglReleaseThread() ); eglClose(m_eglLibrary); + m_eglLibrary = NULL; # if BX_PLATFORM_RPI bcm_host_deinit(); @@ -480,7 +518,7 @@ EGL_IMPORT EMSCRIPTEN_CHECK(emscripten_set_canvas_element_size(HTML5_TARGET_CANVAS_SELECTOR, _width, _height) ); # elif BX_PLATFORM_LINUX && defined(WL_EGL_PLATFORM) if (NULL != m_egl_window) { - wl_egl_window_resize(m_egl_window, _width, _height, 0, 0); + BGFX_WAYLAND_wl_egl_window_resize(m_egl_window, _width, _height, 0, 0); } # else BX_UNUSED(_width, _height); diff --git a/src/glcontext_egl.h b/src/glcontext_egl.h index aedb3ecdc40..80ce4835cd5 100644 --- a/src/glcontext_egl.h +++ b/src/glcontext_egl.h @@ -37,6 +37,7 @@ namespace bgfx { namespace gl , m_display(NULL) , m_surface(NULL) #if BX_PLATFORM_LINUX && defined(WL_EGL_PLATFORM) + , m_waylandEglLibrary(NULL) , m_egl_window(NULL) #endif , m_msaaContext(false) @@ -67,6 +68,7 @@ namespace bgfx { namespace gl EGLDisplay m_display; EGLSurface m_surface; #if BX_PLATFORM_LINUX && defined(WL_EGL_PLATFORM) + void *m_waylandEglLibrary; struct wl_egl_window *m_egl_window; #endif // true when MSAA is handled by the context instead of using MSAA FBO