[Bf-blender-cvs] [e58e023e1a3] master: GHOST/Wayland: support dynamic loading libraries for Wayland
Campbell Barton
noreply at git.blender.org
Wed Jul 6 07:30:56 CEST 2022
Commit: e58e023e1a3e10f4ff2557aedcd730b5dba23579
Author: Campbell Barton
Date: Tue Jul 5 14:49:36 2022 +1000
Branches: master
https://developer.blender.org/rBe58e023e1a3e10f4ff2557aedcd730b5dba23579
GHOST/Wayland: support dynamic loading libraries for Wayland
Add intern/wayland_dynload which is used when WITH_GHOST_WAYLAND_DYNLOAD
is enabled (off by default). When enabled, systems without Wayland
installed will fall back to X11.
This allows Blender to dynamically load:
- libwayland-client
- libwayland-cursor
- libwayland-egl
- libdecor-0 (when WITH_GHOST_WAYLAND_LIBDECOR is enabled).
===================================================================
M CMakeLists.txt
M build_files/cmake/platform/platform_unix.cmake
M intern/CMakeLists.txt
M intern/ghost/CMakeLists.txt
M intern/ghost/intern/GHOST_ISystem.cpp
M intern/ghost/intern/GHOST_SystemWayland.cpp
M intern/ghost/intern/GHOST_SystemWayland.h
M intern/ghost/intern/GHOST_WindowWayland.cpp
A intern/wayland_dynload/CMakeLists.txt
A intern/wayland_dynload/extern/wayland_dynload_API.h
A intern/wayland_dynload/extern/wayland_dynload_client.h
A intern/wayland_dynload/extern/wayland_dynload_cursor.h
A intern/wayland_dynload/extern/wayland_dynload_egl.h
A intern/wayland_dynload/extern/wayland_dynload_libdecor.h
A intern/wayland_dynload/intern/wayland_dynload_client.c
A intern/wayland_dynload/intern/wayland_dynload_cursor.c
A intern/wayland_dynload/intern/wayland_dynload_egl.c
A intern/wayland_dynload/intern/wayland_dynload_libdecor.c
A intern/wayland_dynload/intern/wayland_dynload_utils.c
A intern/wayland_dynload/intern/wayland_dynload_utils.h
===================================================================
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b2b8c56001b..1416b5b4189 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -229,6 +229,9 @@ if(UNIX AND NOT (APPLE OR HAIKU))
option(WITH_GHOST_WAYLAND_DBUS "Optionally build with DBUS support (used for Cursor themes). May hang on startup systems where DBUS is not used." OFF)
mark_as_advanced(WITH_GHOST_WAYLAND_DBUS)
+
+ option(WITH_GHOST_WAYLAND_DYNLOAD "Enable runtime dynamic WAYLAND libraries loading" OFF)
+ mark_as_advanced(WITH_GHOST_WAYLAND_DYNLOAD)
endif()
endif()
diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake
index dff860d9876..4b654420531 100644
--- a/build_files/cmake/platform/platform_unix.cmake
+++ b/build_files/cmake/platform/platform_unix.cmake
@@ -641,12 +641,17 @@ if(WITH_GHOST_WAYLAND)
endif()
list(APPEND PLATFORM_LINKLIBS
- ${wayland-client_LINK_LIBRARIES}
- ${wayland-egl_LINK_LIBRARIES}
${xkbcommon_LINK_LIBRARIES}
- ${wayland-cursor_LINK_LIBRARIES}
)
+ if(NOT WITH_GHOST_WAYLAND_DYNLOAD)
+ list(APPEND PLATFORM_LINKLIBS
+ ${wayland-client_LINK_LIBRARIES}
+ ${wayland-egl_LINK_LIBRARIES}
+ ${wayland-cursor_LINK_LIBRARIES}
+ )
+ endif()
+
if(WITH_GHOST_WAYLAND_DBUS)
list(APPEND PLATFORM_LINKLIBS
${dbus_LINK_LIBRARIES}
@@ -655,9 +660,11 @@ if(WITH_GHOST_WAYLAND)
endif()
if(WITH_GHOST_WAYLAND_LIBDECOR)
- list(APPEND PLATFORM_LINKLIBS
- ${libdecor_LIBRARIES}
- )
+ if(NOT WITH_GHOST_WAYLAND_DYNLOAD)
+ list(APPEND PLATFORM_LINKLIBS
+ ${libdecor_LIBRARIES}
+ )
+ endif()
add_definitions(-DWITH_GHOST_WAYLAND_LIBDECOR)
endif()
endif()
diff --git a/intern/CMakeLists.txt b/intern/CMakeLists.txt
index 2ff2fb39806..6387fd016ba 100644
--- a/intern/CMakeLists.txt
+++ b/intern/CMakeLists.txt
@@ -67,3 +67,10 @@ endif()
if(UNIX AND NOT APPLE)
add_subdirectory(libc_compat)
endif()
+
+if(UNIX AND NOT APPLE)
+ # Important this comes after "ghost" as it uses includes defined by GHOST's CMake.
+ if(WITH_GHOST_WAYLAND AND WITH_GHOST_WAYLAND_DYNLOAD)
+ add_subdirectory(wayland_dynload)
+ endif()
+endif()
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt
index 6a11d00cbc4..0203c5ecf5d 100644
--- a/intern/ghost/CMakeLists.txt
+++ b/intern/ghost/CMakeLists.txt
@@ -270,6 +270,16 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND)
${wayland-cursor_INCLUDE_DIRS}
)
+ if(WITH_GHOST_WAYLAND_DYNLOAD)
+ list(APPEND INC_SYS
+ ../../intern/wayland_dynload/extern
+ )
+ list(APPEND LIB
+ bf_intern_wayland_dynload
+ )
+ add_definitions(-DWITH_GHOST_WAYLAND_DYNLOAD)
+ endif()
+
if(WITH_GHOST_WAYLAND_DBUS)
list(APPEND INC_SYS
${dbus_INCLUDE_DIRS}
diff --git a/intern/ghost/intern/GHOST_ISystem.cpp b/intern/ghost/intern/GHOST_ISystem.cpp
index 745d5faeed4..4f6a9531077 100644
--- a/intern/ghost/intern/GHOST_ISystem.cpp
+++ b/intern/ghost/intern/GHOST_ISystem.cpp
@@ -37,12 +37,23 @@ GHOST_TSuccess GHOST_ISystem::createSystem()
{
GHOST_TSuccess success;
if (!m_system) {
+
+#if defined(WITH_HEADLESS)
+ /* Pass. */
+#elif defined(WITH_GHOST_WAYLAND)
+# if defined(WITH_GHOST_WAYLAND_DYNLOAD)
+ const bool has_wayland_libraries = ghost_wl_dynload_libraries();
+# else
+ const bool has_wayland_libraries = true;
+# endif
+#endif
+
#if defined(WITH_HEADLESS)
m_system = new GHOST_SystemNULL();
#elif defined(WITH_GHOST_X11) && defined(WITH_GHOST_WAYLAND)
/* Special case, try Wayland, fall back to X11. */
try {
- m_system = new GHOST_SystemWayland();
+ m_system = has_wayland_libraries ? new GHOST_SystemWayland() : nullptr;
}
catch (const std::runtime_error &) {
/* fallback to X11. */
@@ -55,7 +66,7 @@ GHOST_TSuccess GHOST_ISystem::createSystem()
#elif defined(WITH_GHOST_X11)
m_system = new GHOST_SystemX11();
#elif defined(WITH_GHOST_WAYLAND)
- m_system = new GHOST_SystemWayland();
+ m_system = has_wayland_libraries ? new GHOST_SystemWayland() : nullptr;
#elif defined(WITH_GHOST_SDL)
m_system = new GHOST_SystemSDL();
#elif defined(WIN32)
diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp
index 8cd3476c4d6..98526eb0bc6 100644
--- a/intern/ghost/intern/GHOST_SystemWayland.cpp
+++ b/intern/ghost/intern/GHOST_SystemWayland.cpp
@@ -16,7 +16,15 @@
#include "GHOST_ContextEGL.h"
+#ifdef WITH_GHOST_WAYLAND_DYNLOAD
+# include <wayland_dynload_API.h> /* For `ghost_wl_dynload_libraries`. */
+#endif
+
#include <EGL/egl.h>
+
+#ifdef WITH_GHOST_WAYLAND_DYNLOAD
+# include <wayland_dynload_egl.h>
+#endif
#include <wayland-egl.h>
#include <algorithm>
@@ -26,6 +34,9 @@
#include <unordered_map>
#include <unordered_set>
+#ifdef WITH_GHOST_WAYLAND_DYNLOAD
+# include <wayland_dynload_cursor.h>
+#endif
#include <wayland-cursor.h>
#include "GHOST_WaylandCursorSettings.h"
@@ -3614,4 +3625,35 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod
return GHOST_kSuccess;
}
+#ifdef WITH_GHOST_WAYLAND_DYNLOAD
+bool ghost_wl_dynload_libraries()
+{
+ /* Only report when `libwayland-client` is not found when building without X11,
+ * which will be used as a fallback. */
+# ifdef WITH_GHOST_X11
+ bool verbose = false;
+# else
+ bool verbose = true;
+# endif
+
+ if (wayland_dynload_client_init(verbose) && /* `libwayland-client`. */
+ wayland_dynload_cursor_init(verbose) && /* `libwayland-cursor`. */
+ wayland_dynload_egl_init(verbose) && /* `libwayland-egl`. */
+# ifdef WITH_GHOST_WAYLAND_LIBDECOR
+ wayland_dynload_libdecor_init(verbose) && /* `libdecor-0`. */
+# endif
+ true) {
+ return true;
+ }
+# ifdef WITH_GHOST_WAYLAND_LIBDECOR
+ wayland_dynload_libdecor_exit();
+# endif
+ wayland_dynload_client_exit();
+ wayland_dynload_cursor_exit();
+ wayland_dynload_egl_exit();
+
+ return false;
+}
+#endif /* WITH_GHOST_WAYLAND_DYNLOAD */
+
/** \} */
diff --git a/intern/ghost/intern/GHOST_SystemWayland.h b/intern/ghost/intern/GHOST_SystemWayland.h
index e336b02ec9e..e40448ff20b 100644
--- a/intern/ghost/intern/GHOST_SystemWayland.h
+++ b/intern/ghost/intern/GHOST_SystemWayland.h
@@ -11,9 +11,15 @@
#include "GHOST_System.h"
#include "GHOST_WindowWayland.h"
+#ifdef WITH_GHOST_WAYLAND_DYNLOAD
+# include <wayland_dynload_client.h>
+#endif
#include <wayland-client.h>
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
+# ifdef WITH_GHOST_WAYLAND_DYNLOAD
+# include <wayland_dynload_libdecor.h>
+# endif
# include <libdecor.h>
#else
/* Generated by `wayland-scanner`. */
@@ -35,6 +41,14 @@ bool ghost_wl_surface_own(const struct wl_surface *surface);
void ghost_wl_surface_tag(struct wl_surface *surface);
GHOST_WindowWayland *ghost_wl_surface_user_data(struct wl_surface *surface);
+#ifdef WITH_GHOST_WAYLAND_DYNLOAD
+/**
+ * Return true when all required WAYLAND libraries are present,
+ * Performs dynamic loading when `WITH_GHOST_WAYLAND_DYNLOAD` is in use.
+ */
+bool ghost_wl_dynload_libraries();
+#endif
+
struct output_t {
struct wl_output *wl_output = nullptr;
struct zxdg_output_v1 *xdg_output = nullptr;
diff --git a/intern/ghost/intern/GHOST_WindowWayland.cpp b/intern/ghost/intern/GHOST_WindowWayland.cpp
index d26dfe0e7e6..77eddbb13a5 100644
--- a/intern/ghost/intern/GHOST_WindowWayland.cpp
+++ b/intern/ghost/intern/GHOST_WindowWayland.cpp
@@ -15,11 +15,18 @@
#include "GHOST_ContextNone.h"
#include <wayland-client-protocol.h>
+
+#ifdef WITH_GHOST_WAYLAND_DYNLOAD
+# include <wayland_dynload_egl.h>
+#endif
#include <wayland-egl.h>
#include <algorithm> /* For `std::find`. */
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
+# ifdef WITH_GHOST_WAYLAND_DYNLOAD
+# include <wayland_dynload_libdecor.h>
+# endif
# include <libdecor.h>
#endif
@@ -347,7 +354,7 @@ static void surface_handle_leave(void *data,
}
}
-struct wl_surface_listener wl_surface_listener = {
+static struct wl_surface_listener wl_surface_listener = {
surface_handle_enter,
surface_handle_leave,
};
diff --git a/intern/wayland_dynload/CMakeLists.txt b/intern/wayland_dynload/CMakeLists.txt
new file mode 100644
index 00000000000..2b1a6370126
--- /dev/null
+++ b/intern/wayland_dynload/CMakeLists.txt
@@ -0,0 +1,44 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+set(INC
+ extern
+
+ # For internal includes.
+ intern
+)
+
+set(INC_SYS
+ ${wayland-client_INCLUDE_DIRS}
+ ${wayland-egl_INCLUDE_DIRS}
+ ${wayland-cursor_INCLUDE_DIRS}
+)
+
+set(SRC
+ intern/wayland_dynload_client.c
+ intern/wayland_dynload_cursor.c
+ intern/wayland_dynload_egl.c
+ intern/wayland_dynload_utils.c
+
+ extern/wayland_dynload_API.h
+ extern/wayland_dynload_client.h
+ extern/wayland_dynload_cursor.h
+ extern/wayland_dynload_egl.h
+ intern/wayland_dynload_utils.h
+)
+
+if(WITH_GHOST_WAYLAND_LIBDECOR)
+ list(APPEND INC_SYS
+ ${libdecor_INCLUDE_DIRS}
+ )
+ list(APPEND SRC
+ intern/wayland_dynload_libdecor.c
+
+ extern/wayland_dynload_libdecor.h
+ )
+endif()
+
+set(LIB
+)
+
+
+blender_add_lib(bf_intern_wayland_dynload "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
diff --git a/intern/wayland_dynload/extern/wayland_dynload_API.h b/intern/wayland_dynload/extern/wayland_dynload_API.h
new file mode 100644
index 00000000000..07ff00b5a76
--- /dev/null
+++ b/intern/wayland_dynload/extern/wayland_dynload_API.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup intern_wayland_dynload
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+
+bool wayland_dynload_client_init(bool verbose);
+void wayland_dynload_client_exit(void);
+
+bool wayland_dynload_cursor_init(bool verbose);
+void wayland_dynload_cursor_exit(void);
+
+bool wayland_dynload_egl_init(bool verbose);
+void wayland_dynload_egl_exit(void);
+
+#ifdef WITH_GHOST_WAYLAND_LIBDECOR
+bool wayland_dynload_libdecor_init(bool verbose);
+void wayland_dynload_libdecor_exit(void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/intern/wayland_dynload/extern/wayland_dynload_client.h b/intern/wayland_dynload/extern/wayland_dynload_client.h
new file mode
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list