diff --git a/examples/common/entry/entry_glfw.cpp b/examples/common/entry/entry_glfw.cpp index c9c2f0d4b..fe001ed31 100644 --- a/examples/common/entry/entry_glfw.cpp +++ b/examples/common/entry/entry_glfw.cpp @@ -15,8 +15,13 @@ #endif // GLFW_VERSION_MINOR < 2 #if BX_PLATFORM_LINUX || BX_PLATFORM_BSD -# define GLFW_EXPOSE_NATIVE_X11 -# define GLFW_EXPOSE_NATIVE_GLX +# if BGFX_USE_WAYLAND +# include +# define GLFW_EXPOSE_NATIVE_WAYLAND +# else +# define GLFW_EXPOSE_NATIVE_X11 +# define GLFW_EXPOSE_NATIVE_GLX +# endif #elif BX_PLATFORM_OSX # define GLFW_EXPOSE_NATIVE_COCOA # define GLFW_EXPOSE_NATIVE_NSGL @@ -40,7 +45,22 @@ namespace entry static void* glfwNativeWindowHandle(GLFWwindow* _window) { # if BX_PLATFORM_LINUX || BX_PLATFORM_BSD +# if BGFX_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; +# else return (void*)(uintptr_t)glfwGetX11Window(_window); +# endif # elif BX_PLATFORM_OSX return glfwGetCocoaWindow(_window); # elif BX_PLATFORM_WINDOWS @@ -48,11 +68,32 @@ namespace entry # endif // BX_PLATFORM_ } + static void glfwDestroyWindowImpl(GLFWwindow *_window) + { + if(!_window) + return; +# if BX_PLATFORM_LINUX || BX_PLATFORM_BSD +# if BGFX_USE_WAYLAND + wl_egl_window *win_impl = (wl_egl_window*)glfwGetWindowUserPointer(_window); + if(win_impl) + { + glfwSetWindowUserPointer(_window, nullptr); + wl_egl_window_destroy(win_impl); + } +# endif +# endif + glfwDestroyWindow(_window); + } + static void glfwSetWindow(GLFWwindow* _window) { bgfx::PlatformData pd; # if BX_PLATFORM_LINUX || BX_PLATFORM_BSD +# if BGFX_USE_WAYLAND + pd.ndt = glfwGetWaylandDisplay(); +# else pd.ndt = glfwGetX11Display(); + #endif # elif BX_PLATFORM_OSX pd.ndt = NULL; # elif BX_PLATFORM_WINDOWS @@ -506,7 +547,7 @@ namespace entry { GLFWwindow* window = m_windows[msg->m_handle.idx]; m_eventQueue.postWindowEvent(msg->m_handle); - glfwDestroyWindow(window); + glfwDestroyWindowImpl(window); m_windows[msg->m_handle.idx] = NULL; } } @@ -598,7 +639,7 @@ namespace entry m_eventQueue.postExitEvent(); m_thread.shutdown(); - glfwDestroyWindow(m_windows[0]); + glfwDestroyWindowImpl(m_windows[0]); glfwTerminate(); return m_thread.getExitCode(); diff --git a/examples/common/entry/entry_sdl.cpp b/examples/common/entry/entry_sdl.cpp index e5b3ac95c..7bd149525 100644 --- a/examples/common/entry/entry_sdl.cpp +++ b/examples/common/entry/entry_sdl.cpp @@ -7,9 +7,13 @@ #if ENTRY_CONFIG_USE_SDL -#if BX_PLATFORM_WINDOWS +#if BX_PLATFORM_LINUX || BX_PLATFORM_BSD +# if BGFX_USE_WAYLAND +# include +# endif +#elif BX_PLATFORM_WINDOWS # define SDL_MAIN_HANDLED -#endif // BX_PLATFORM_WINDOWS +#endif #include @@ -34,6 +38,42 @@ BX_PRAGMA_DIAGNOSTIC_POP() namespace entry { + /// + static void* sdlNativeWindowHandle(SDL_Window* _window) + { + SDL_SysWMinfo wmi; + SDL_VERSION(&wmi.version); + if (!SDL_GetWindowWMInfo(_window, &wmi) ) + { + return NULL; + } + +# if BX_PLATFORM_LINUX || BX_PLATFORM_BSD +# if BGFX_USE_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; +# else + return (void*)wmi.info.x11.window; +# endif +# elif BX_PLATFORM_OSX + return wmi.info.cocoa.window; +# elif BX_PLATFORM_WINDOWS + return wmi.info.win.window; +# elif BX_PLATFORM_STEAMLINK + return wmi.info.vivante.window; +# endif // BX_PLATFORM_ + } + inline bool sdlSetWindow(SDL_Window* _window) { SDL_SysWMinfo wmi; @@ -45,18 +85,20 @@ namespace entry bgfx::PlatformData pd; # if BX_PLATFORM_LINUX || BX_PLATFORM_BSD +# if BGFX_USE_WAYLAND + pd.ndt = wmi.info.wl.display; +# else pd.ndt = wmi.info.x11.display; - pd.nwh = (void*)(uintptr_t)wmi.info.x11.window; +# endif # elif BX_PLATFORM_OSX pd.ndt = NULL; - pd.nwh = wmi.info.cocoa.window; # elif BX_PLATFORM_WINDOWS pd.ndt = NULL; - pd.nwh = wmi.info.win.window; # elif BX_PLATFORM_STEAMLINK pd.ndt = wmi.info.vivante.display; - pd.nwh = wmi.info.vivante.window; # endif // BX_PLATFORM_ + pd.nwh = sdlNativeWindowHandle(_window); + pd.context = NULL; pd.backBuffer = NULL; pd.backBufferDS = NULL; @@ -65,6 +107,23 @@ namespace entry return true; } + static void sdlDestroyWindow(SDL_Window* _window) + { + if(!_window) + return; +# if BX_PLATFORM_LINUX || BX_PLATFORM_BSD +# if BGFX_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); + } + static uint8_t translateKeyModifiers(uint16_t _sdl) { uint8_t modifiers = 0; @@ -252,27 +311,6 @@ namespace entry static int32_t threadFunc(bx::Thread* _thread, void* _userData); }; - /// - static void* sdlNativeWindowHandle(SDL_Window* _window) - { - SDL_SysWMinfo wmi; - SDL_VERSION(&wmi.version); - if (!SDL_GetWindowWMInfo(_window, &wmi) ) - { - return NULL; - } - -# if BX_PLATFORM_LINUX || BX_PLATFORM_BSD - return (void*)wmi.info.x11.window; -# elif BX_PLATFORM_OSX - return wmi.info.cocoa.window; -# elif BX_PLATFORM_WINDOWS - return wmi.info.win.window; -# elif BX_PLATFORM_STEAMLINK - return wmi.info.vivante.window; -# endif // BX_PLATFORM_ - } - struct Msg { Msg() @@ -858,7 +896,7 @@ namespace entry if (isValid(handle) ) { m_eventQueue.postWindowEvent(handle); - SDL_DestroyWindow(m_window[handle.idx]); + sdlDestroyWindow(m_window[handle.idx]); m_window[handle.idx] = NULL; } } @@ -952,7 +990,7 @@ namespace entry while (bgfx::RenderFrame::NoContext != bgfx::renderFrame() ) {}; m_thread.shutdown(); - SDL_DestroyWindow(m_window[0]); + sdlDestroyWindow(m_window[0]); SDL_Quit(); return m_thread.getExitCode(); diff --git a/scripts/genie.lua b/scripts/genie.lua index 1ae29ac57..b8864f97c 100644 --- a/scripts/genie.lua +++ b/scripts/genie.lua @@ -18,6 +18,11 @@ newoption { description = "Enable GLFW entry.", } +newoption { + trigger = "with-wayland", + description = "Use Wayland backend.", +} + newoption { trigger = "with-profiler", description = "Enable build with intrusive profiler.", @@ -115,6 +120,12 @@ end function copyLib() end +if _OPTIONS["with-wayland"] then + defines { "BGFX_USE_WAYLAND=1" } +else + defines { "BGFX_USE_WAYLAND=0" } +end + if _OPTIONS["with-sdl"] then if os.is("windows") then if not os.getenv("SDL2_DIR") then @@ -159,6 +170,13 @@ 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" } @@ -170,13 +188,19 @@ function exampleProjectDefaults() links { "glfw3" } configuration { "linux or freebsd" } - links { - "Xrandr", - "Xinerama", - "Xi", - "Xxf86vm", - "Xcursor", - } + if _OPTIONS["with-wayland"] then + links { + "wayland-egl", + } + else + links { + "Xrandr", + "Xinerama", + "Xi", + "Xxf86vm", + "Xcursor", + } + end configuration { "osx" } linkoptions { diff --git a/src/glcontext_egl.h b/src/glcontext_egl.h index 245cd7ad3..c92aabbb1 100644 --- a/src/glcontext_egl.h +++ b/src/glcontext_egl.h @@ -8,6 +8,10 @@ #if BGFX_USE_EGL +#if BGFX_USE_WAYLAND +#include +#endif + #include #include #if defined(Success)