소스 검색

Dynamically load libwayland-egl.so.1 when dealing with Wayland to remove dependencies at program startup. (#3359)

Martijn Courteaux 1 년 전
부모
커밋
a6e372ead9
4개의 변경된 파일51개의 추가작업 그리고 37개의 파일을 삭제
  1. 0 13
      examples/common/entry/entry_sdl.cpp
  2. 8 21
      scripts/genie.lua
  3. 41 3
      src/glcontext_egl.cpp
  4. 2 0
      src/glcontext_egl.h

+ 0 - 13
examples/common/entry/entry_sdl.cpp

@@ -8,9 +8,6 @@
 #if ENTRY_CONFIG_USE_SDL
 #if ENTRY_CONFIG_USE_SDL
 
 
 #if BX_PLATFORM_LINUX
 #if BX_PLATFORM_LINUX
-#	if ENTRY_CONFIG_USE_WAYLAND
-#		include <wayland-egl.h>
-#	endif
 #elif BX_PLATFORM_WINDOWS
 #elif BX_PLATFORM_WINDOWS
 #	define SDL_MAIN_HANDLED
 #	define SDL_MAIN_HANDLED
 #endif
 #endif
@@ -68,16 +65,6 @@ namespace entry
 	{
 	{
 		if(!_window)
 		if(!_window)
 			return;
 			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);
 		SDL_DestroyWindow(_window);
 	}
 	}
 
 

+ 8 - 21
scripts/genie.lua

@@ -22,7 +22,7 @@ newoption {
 
 
 newoption {
 newoption {
 	trigger = "with-wayland",
 	trigger = "with-wayland",
-	description = "Use Wayland backend.",
+	description = "Enable Wayland support.",
 }
 }
 
 
 newoption {
 newoption {
@@ -235,13 +235,6 @@ function exampleProjectDefaults()
 		defines { "ENTRY_CONFIG_USE_SDL=1" }
 		defines { "ENTRY_CONFIG_USE_SDL=1" }
 		links   { "SDL2" }
 		links   { "SDL2" }
 
 
-		configuration { "linux or freebsd" }
-			if _OPTIONS["with-wayland"]  then
-				links {
-					"wayland-egl",
-				}
-			end
-
 		configuration { "osx*" }
 		configuration { "osx*" }
 			libdirs { "$(SDL2_DIR)/lib" }
 			libdirs { "$(SDL2_DIR)/lib" }
 
 
@@ -253,19 +246,13 @@ function exampleProjectDefaults()
 		links   { "glfw3" }
 		links   { "glfw3" }
 
 
 		configuration { "linux or freebsd" }
 		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*" }
 		configuration { "osx*" }
 			linkoptions {
 			linkoptions {

+ 41 - 3
src/glcontext_egl.cpp

@@ -128,6 +128,39 @@ EGL_IMPORT
 	}
 	}
 #endif // BGFX_USE_GL_DYNAMIC_LIB
 #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
 #	define GL_IMPORT(_optional, _proto, _func, _import) _proto _func = NULL
 #	include "glimports.h"
 #	include "glimports.h"
 
 
@@ -335,9 +368,11 @@ EGL_IMPORT
 
 
 #	if BX_PLATFORM_LINUX && defined(WL_EGL_PLATFORM)
 #	if BX_PLATFORM_LINUX && defined(WL_EGL_PLATFORM)
 			if (g_platformData.type == NativeWindowHandleType::Wayland) {
 			if (g_platformData.type == NativeWindowHandleType::Wayland) {
+				m_waylandEglLibrary = waylandEglOpen();
+
 				// A wl_surface needs to be first wrapped in a wl_egl_window
 				// A wl_surface needs to be first wrapped in a wl_egl_window
 				// before it can be used to create the EGLSurface.
 				// 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;
 				nwh = m_egl_window;
 			}
 			}
 #	endif
 #	endif
@@ -444,7 +479,9 @@ EGL_IMPORT
 			EGL_CHECK(eglDestroySurface(m_display, m_surface) );
 			EGL_CHECK(eglDestroySurface(m_display, m_surface) );
 #	if BX_PLATFORM_LINUX && defined(WL_EGL_PLATFORM)
 #	if BX_PLATFORM_LINUX && defined(WL_EGL_PLATFORM)
 			if (m_egl_window) {
 			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
 #	endif
 			EGL_CHECK(eglTerminate(m_display) );
 			EGL_CHECK(eglTerminate(m_display) );
@@ -453,6 +490,7 @@ EGL_IMPORT
 
 
 		EGL_CHECK(eglReleaseThread() );
 		EGL_CHECK(eglReleaseThread() );
 		eglClose(m_eglLibrary);
 		eglClose(m_eglLibrary);
+		m_eglLibrary = NULL;
 
 
 #	if BX_PLATFORM_RPI
 #	if BX_PLATFORM_RPI
 		bcm_host_deinit();
 		bcm_host_deinit();
@@ -480,7 +518,7 @@ EGL_IMPORT
 		EMSCRIPTEN_CHECK(emscripten_set_canvas_element_size(HTML5_TARGET_CANVAS_SELECTOR, _width, _height) );
 		EMSCRIPTEN_CHECK(emscripten_set_canvas_element_size(HTML5_TARGET_CANVAS_SELECTOR, _width, _height) );
 #	elif BX_PLATFORM_LINUX && defined(WL_EGL_PLATFORM)
 #	elif BX_PLATFORM_LINUX && defined(WL_EGL_PLATFORM)
 		if (NULL != m_egl_window) {
 		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
 #	else
 		BX_UNUSED(_width, _height);
 		BX_UNUSED(_width, _height);

+ 2 - 0
src/glcontext_egl.h

@@ -37,6 +37,7 @@ namespace bgfx { namespace gl
 			, m_display(NULL)
 			, m_display(NULL)
 			, m_surface(NULL)
 			, m_surface(NULL)
 #if BX_PLATFORM_LINUX && defined(WL_EGL_PLATFORM)
 #if BX_PLATFORM_LINUX && defined(WL_EGL_PLATFORM)
+			, m_waylandEglLibrary(NULL)
 			, m_egl_window(NULL)
 			, m_egl_window(NULL)
 #endif
 #endif
 			, m_msaaContext(false)
 			, m_msaaContext(false)
@@ -67,6 +68,7 @@ namespace bgfx { namespace gl
 		EGLDisplay m_display;
 		EGLDisplay m_display;
 		EGLSurface m_surface;
 		EGLSurface m_surface;
 #if BX_PLATFORM_LINUX && defined(WL_EGL_PLATFORM)
 #if BX_PLATFORM_LINUX && defined(WL_EGL_PLATFORM)
+		void *m_waylandEglLibrary;
 		struct wl_egl_window *m_egl_window;
 		struct wl_egl_window *m_egl_window;
 #endif
 #endif
 		// true when MSAA is handled by the context instead of using MSAA FBO
 		// true when MSAA is handled by the context instead of using MSAA FBO