Browse Source

Properly support Wayland under EGL and Vulkan. (#3358)

Martijn Courteaux 1 year ago
parent
commit
3303b451a1

+ 2 - 12
examples/common/entry/entry_glfw.cpp

@@ -46,18 +46,8 @@ namespace entry
 	{
 	{
 #	if BX_PLATFORM_LINUX
 #	if BX_PLATFORM_LINUX
 # 		if ENTRY_CONFIG_USE_WAYLAND
 # 		if ENTRY_CONFIG_USE_WAYLAND
-		wl_egl_window *win_impl = (wl_egl_window*)glfwGetWindowUserPointer(_window);
-		if(!win_impl)
-		{
-			int width, height;
-			glfwGetWindowSize(_window, &width, &height);
-			struct wl_surface* surface = (struct wl_surface*)glfwGetWaylandWindow(_window);
-			if(!surface)
-				return nullptr;
-			win_impl = wl_egl_window_create(surface, width, height);
-			glfwSetWindowUserPointer(_window, (void*)(uintptr_t)win_impl);
-		}
-		return (void*)(uintptr_t)win_impl;
+		struct wl_surface* surface = (struct wl_surface*)glfwGetWaylandWindow(_window);
+		return (void*)surface;
 #		else
 #		else
 		return (void*)(uintptr_t)glfwGetX11Window(_window);
 		return (void*)(uintptr_t)glfwGetX11Window(_window);
 #		endif
 #		endif

+ 1 - 14
examples/common/entry/entry_sdl.cpp

@@ -51,20 +51,7 @@ namespace entry
 #	if BX_PLATFORM_LINUX
 #	if BX_PLATFORM_LINUX
 #		if ENTRY_CONFIG_USE_WAYLAND
 #		if ENTRY_CONFIG_USE_WAYLAND
 			if (wmi.subsystem == SDL_SYSWM_WAYLAND)
 			if (wmi.subsystem == SDL_SYSWM_WAYLAND)
-				{
-					wl_egl_window *win_impl = (wl_egl_window*)SDL_GetWindowData(_window, "wl_egl_window");
-					if(!win_impl)
-					{
-						int width, height;
-						SDL_GetWindowSize(_window, &width, &height);
-						struct wl_surface* surface = wmi.info.wl.surface;
-						if(!surface)
-							return nullptr;
-						win_impl = wl_egl_window_create(surface, width, height);
-						SDL_SetWindowData(_window, "wl_egl_window", win_impl);
-					}
-					return (void*)(uintptr_t)win_impl;
-				}
+				return (void*)wmi.info.wl.surface;
 			else
 			else
 #		endif // ENTRY_CONFIG_USE_WAYLAND
 #		endif // ENTRY_CONFIG_USE_WAYLAND
 				return (void*)wmi.info.x11.window;
 				return (void*)wmi.info.x11.window;

+ 2 - 0
examples/common/example-glue.cpp

@@ -290,6 +290,8 @@ void showExampleDialog(entry::AppI* _app, const char* _errorText)
 			}
 			}
 		}
 		}
 	}
 	}
+#else
+	ImGui::Text("Renderer: %s", bgfx::getRendererName(bgfx::getRendererType()));
 #endif // 0
 #endif // 0
 
 
 	const bgfx::Stats* stats = bgfx::getStats();
 	const bgfx::Stats* stats = bgfx::getStats();

+ 21 - 0
src/glcontext_egl.cpp

@@ -27,6 +27,10 @@
 #	define EGL_CHECK(_call) _call
 #	define EGL_CHECK(_call) _call
 #endif // BGFX_CONFIG_DEBUG
 #endif // BGFX_CONFIG_DEBUG
 
 
+#if defined(WL_EGL_PLATFORM)
+#	include <wayland-egl.h>
+#endif
+
 namespace bgfx { namespace gl
 namespace bgfx { namespace gl
 {
 {
 #ifndef EGL_CONTEXT_FLAG_NO_ERROR_BIT_KHR
 #ifndef EGL_CONTEXT_FLAG_NO_ERROR_BIT_KHR
@@ -329,6 +333,14 @@ EGL_IMPORT
 			vc_dispmanx_update_submit_sync(dispmanUpdate);
 			vc_dispmanx_update_submit_sync(dispmanUpdate);
 #	endif // BX_PLATFORM_ANDROID
 #	endif // BX_PLATFORM_ANDROID
 
 
+#	if BX_PLATFORM_LINUX && defined(WL_EGL_PLATFORM)
+			if (g_platformData.type == NativeWindowHandleType::Wayland) {
+				// 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);
+				nwh = m_egl_window;
+			}
+#	endif
 			if (headless)
 			if (headless)
 			{
 			{
 				EGLint pbAttribs[] =
 				EGLint pbAttribs[] =
@@ -430,6 +442,11 @@ EGL_IMPORT
 			EGL_CHECK(eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) );
 			EGL_CHECK(eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) );
 			EGL_CHECK(eglDestroyContext(m_display, m_context) );
 			EGL_CHECK(eglDestroyContext(m_display, m_context) );
 			EGL_CHECK(eglDestroySurface(m_display, m_surface) );
 			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);
+			}
+#	endif
 			EGL_CHECK(eglTerminate(m_display) );
 			EGL_CHECK(eglTerminate(m_display) );
 			m_context = NULL;
 			m_context = NULL;
 		}
 		}
@@ -461,6 +478,10 @@ EGL_IMPORT
 		}
 		}
 #	elif BX_PLATFORM_EMSCRIPTEN
 #	elif BX_PLATFORM_EMSCRIPTEN
 		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)
+		if (NULL != m_egl_window) {
+			wl_egl_window_resize(m_egl_window, _width, _height, 0, 0);
+		}
 #	else
 #	else
 		BX_UNUSED(_width, _height);
 		BX_UNUSED(_width, _height);
 #	endif // BX_PLATFORM_*
 #	endif // BX_PLATFORM_*

+ 7 - 0
src/glcontext_egl.h

@@ -11,6 +11,7 @@
 #include <EGL/egl.h>
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 #include <EGL/eglext.h>
 
 
+
 // EGL pulls X11 crap...
 // EGL pulls X11 crap...
 #if defined(None)
 #if defined(None)
 #	undef None
 #	undef None
@@ -35,6 +36,9 @@ namespace bgfx { namespace gl
 			, m_context(NULL)
 			, m_context(NULL)
 			, m_display(NULL)
 			, m_display(NULL)
 			, m_surface(NULL)
 			, m_surface(NULL)
+#if BX_PLATFORM_LINUX && defined(WL_EGL_PLATFORM)
+			, m_egl_window(NULL)
+#endif
 			, m_msaaContext(false)
 			, m_msaaContext(false)
 		{
 		{
 		}
 		}
@@ -62,6 +66,9 @@ namespace bgfx { namespace gl
 		EGLContext m_context;
 		EGLContext m_context;
 		EGLDisplay m_display;
 		EGLDisplay m_display;
 		EGLSurface m_surface;
 		EGLSurface m_surface;
+#if BX_PLATFORM_LINUX && defined(WL_EGL_PLATFORM)
+		struct wl_egl_window *m_egl_window;
+#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
 		bool m_msaaContext;
 		bool m_msaaContext;
 	};
 	};

+ 1 - 1
src/renderer_vk.cpp

@@ -6940,7 +6940,7 @@ VK_DESTROY
 				sci.pNext = NULL;
 				sci.pNext = NULL;
 				sci.flags = 0;
 				sci.flags = 0;
 				sci.display = (wl_display*)g_platformData.ndt;
 				sci.display = (wl_display*)g_platformData.ndt;
-				sci.surface = (wl_surface*)((wl_egl_window*)m_nwh)->surface;
+				sci.surface = (wl_surface*)m_nwh;
 				result = vkCreateWaylandSurfaceKHR(instance, &sci, allocatorCb, &m_surface);
 				result = vkCreateWaylandSurfaceKHR(instance, &sci, allocatorCb, &m_surface);
 			}
 			}
 			else
 			else