From c233a8042f35feacc257e02eceefaf201e7c6017 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Mon, 25 Jul 2022 17:21:15 +1000 Subject: [PATCH] GLContext: Dynamically load wayland-egl --- CMakeLists.txt | 3 -- scripts/make-appimage.sh | 2 ++ src/common/CMakeLists.txt | 1 - src/common/gl/context_egl_wayland.cpp | 44 ++++++++++++++++++++++----- src/common/gl/context_egl_wayland.h | 7 +++++ 5 files changed, 46 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 964495d6f..6aa822264 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -119,9 +119,6 @@ if(USE_X11) endif() endif() if(USE_WAYLAND) - find_package(ECM REQUIRED NO_MODULE) - list(APPEND CMAKE_MODULE_PATH "${ECM_MODULE_PATH}") - find_package(Wayland REQUIRED Egl) message(STATUS "Wayland support enabled") endif() if(USE_DRMKMS AND USE_FBDEV) diff --git a/scripts/make-appimage.sh b/scripts/make-appimage.sh index 24ba71b1c..4875ae653 100755 --- a/scripts/make-appimage.sh +++ b/scripts/make-appimage.sh @@ -59,6 +59,8 @@ declare -a SYSLIBS=( "libwrap.so.0" "libharfbuzz.so.0" "libFLAC.so.8" + "libX11.so.6" + "libX11-xcb.so.1" "libXau.so.6" "libXcomposite.so.1" "libXcursor.so.1" diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 61a08146f..f031b5cde 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -205,7 +205,6 @@ if(USE_WAYLAND) gl/context_egl_wayland.h ) target_compile_definitions(common PRIVATE "-DUSE_WAYLAND=1") - target_link_libraries(common PRIVATE Wayland::Egl) endif() if(APPLE) diff --git a/src/common/gl/context_egl_wayland.cpp b/src/common/gl/context_egl_wayland.cpp index 2046c44f8..16532e8b1 100644 --- a/src/common/gl/context_egl_wayland.cpp +++ b/src/common/gl/context_egl_wayland.cpp @@ -1,19 +1,25 @@ #include "context_egl_wayland.h" -#include +#include "../log.h" +#include +Log_SetChannel(ContextEGLWayland); namespace GL { +static const char* WAYLAND_EGL_MODNAME = "libwayland-egl.so.1"; + ContextEGLWayland::ContextEGLWayland(const WindowInfo& wi) : ContextEGL(wi) {} ContextEGLWayland::~ContextEGLWayland() { if (m_wl_window) - wl_egl_window_destroy(m_wl_window); + m_wl_egl_window_destroy(m_wl_window); + if (m_wl_module) + dlclose(m_wl_module); } std::unique_ptr ContextEGLWayland::Create(const WindowInfo& wi, const Version* versions_to_try, size_t num_versions_to_try) { std::unique_ptr context = std::make_unique(wi); - if (!context->Initialize(versions_to_try, num_versions_to_try)) + if (!context->LoadModule() || !context->Initialize(versions_to_try, num_versions_to_try)) return nullptr; return context; @@ -24,7 +30,7 @@ std::unique_ptr ContextEGLWayland::CreateSharedContext(const WindowInfo std::unique_ptr context = std::make_unique(wi); context->m_display = m_display; - if (!context->CreateContextAndSurface(m_version, m_context, false)) + if (!context->LoadModule() || !context->CreateContextAndSurface(m_version, m_context, false)) return nullptr; return context; @@ -33,7 +39,7 @@ std::unique_ptr ContextEGLWayland::CreateSharedContext(const WindowInfo void ContextEGLWayland::ResizeSurface(u32 new_surface_width, u32 new_surface_height) { if (m_wl_window) - wl_egl_window_resize(m_wl_window, new_surface_width, new_surface_height, 0, 0); + m_wl_egl_window_resize(m_wl_window, new_surface_width, new_surface_height, 0, 0); ContextEGL::ResizeSurface(new_surface_width, new_surface_height); } @@ -42,15 +48,39 @@ EGLNativeWindowType ContextEGLWayland::GetNativeWindow(EGLConfig config) { if (m_wl_window) { - wl_egl_window_destroy(m_wl_window); + m_wl_egl_window_destroy(m_wl_window); m_wl_window = nullptr; } m_wl_window = - wl_egl_window_create(static_cast(m_wi.window_handle), m_wi.surface_width, m_wi.surface_height); + m_wl_egl_window_create(static_cast(m_wi.window_handle), m_wi.surface_width, m_wi.surface_height); if (!m_wl_window) return {}; return reinterpret_cast(m_wl_window); } + +bool ContextEGLWayland::LoadModule() +{ + m_wl_module = dlopen(WAYLAND_EGL_MODNAME, RTLD_NOW | RTLD_GLOBAL); + if (!m_wl_module) + { + Log_ErrorPrintf("Failed to load %s.", WAYLAND_EGL_MODNAME); + return false; + } + + m_wl_egl_window_create = + reinterpret_cast(dlsym(m_wl_module, "wl_egl_window_create")); + m_wl_egl_window_destroy = + reinterpret_cast(dlsym(m_wl_module, "wl_egl_window_destroy")); + m_wl_egl_window_resize = + reinterpret_cast(dlsym(m_wl_module, "wl_egl_window_resize")); + if (!m_wl_egl_window_create || !m_wl_egl_window_destroy || !m_wl_egl_window_resize) + { + Log_ErrorPrintf("Failed to load one or more functions from %s.", WAYLAND_EGL_MODNAME); + return false; + } + + return true; +} } // namespace GL diff --git a/src/common/gl/context_egl_wayland.h b/src/common/gl/context_egl_wayland.h index d57dd82ac..4682f4244 100644 --- a/src/common/gl/context_egl_wayland.h +++ b/src/common/gl/context_egl_wayland.h @@ -20,7 +20,14 @@ protected: EGLNativeWindowType GetNativeWindow(EGLConfig config) override; private: + bool LoadModule(); + wl_egl_window* m_wl_window = nullptr; + + void* m_wl_module = nullptr; + wl_egl_window* (*m_wl_egl_window_create)(struct wl_surface* surface, int width, int height); + void (*m_wl_egl_window_destroy)(struct wl_egl_window* egl_window); + void (*m_wl_egl_window_resize)(struct wl_egl_window* egl_window, int width, int height, int dx, int dy); }; } // namespace GL