diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml
index dc3d9f37862..348e2bb317b 100644
--- a/.github/workflows/linux_builds.yml
+++ b/.github/workflows/linux_builds.yml
@@ -106,7 +106,7 @@ jobs:
# TODO: Figure out somehow how to embed this one.
- name: wayland-scanner dependency
run: |
- sudo apt-get install libwayland-bin
+ sudo apt-get install libwayland-bin libegl-dev
- name: Free disk space on runner
run: |
diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml
index 674aa148a3c..45e802519e5 100644
--- a/doc/classes/DisplayServer.xml
+++ b/doc/classes/DisplayServer.xml
@@ -2152,12 +2152,14 @@
Display handle:
- Linux (X11): [code]X11::Display*[/code] for the display.
+ - Linux (Wayland): [code]wl_display[/code] for the display.
- Android: [code]EGLDisplay[/code] for the display.
Window handle:
- Windows: [code]HWND[/code] for the window.
- Linux (X11): [code]X11::Window*[/code] for the window.
+ - Linux (Wayland): [code]wl_surface[/code] for the window.
- macOS: [code]NSWindow*[/code] for the window.
- iOS: [code]UIViewController*[/code] for the view controller.
- Android: [code]jObject[/code] for the activity.
@@ -2172,9 +2174,20 @@
OpenGL context (only with the GL Compatibility renderer):
- Windows: [code]HGLRC[/code] for the window (native GL), or [code]EGLContext[/code] for the window (ANGLE).
- Linux (X11): [code]GLXContext*[/code] for the window.
+ - Linux (Wayland): [code]EGLContext[/code] for the window.
- macOS: [code]NSOpenGLContext*[/code] for the window (native GL), or [code]EGLContext[/code] for the window (ANGLE).
- Android: [code]EGLContext[/code] for the window.
+
+ - Windows: [code]EGLDisplay[/code] for the window (ANGLE).
+ - macOS: [code]EGLDisplay[/code] for the window (ANGLE).
+ - Linux (Wayland): [code]EGLDisplay[/code] for the window.
+
+
+ - Windows: [code]EGLConfig[/code] for the window (ANGLE).
+ - macOS: [code]EGLConfig[/code] for the window (ANGLE).
+ - Linux (Wayland): [code]EGLConfig[/code] for the window.
+
Utterance has begun to be spoken.
diff --git a/drivers/egl/egl_manager.cpp b/drivers/egl/egl_manager.cpp
index 603dfadd4b9..8ca0aa5943e 100644
--- a/drivers/egl/egl_manager.cpp
+++ b/drivers/egl/egl_manager.cpp
@@ -414,6 +414,30 @@ EGLContext EGLManager::get_context(DisplayServer::WindowID p_window_id) {
return display.egl_context;
}
+EGLDisplay EGLManager::get_display(DisplayServer::WindowID p_window_id) {
+ GLWindow &glwindow = windows[p_window_id];
+
+ if (!glwindow.initialized) {
+ return EGL_NO_CONTEXT;
+ }
+
+ GLDisplay &display = displays[glwindow.gldisplay_id];
+
+ return display.egl_display;
+}
+
+EGLConfig EGLManager::get_config(DisplayServer::WindowID p_window_id) {
+ GLWindow &glwindow = windows[p_window_id];
+
+ if (!glwindow.initialized) {
+ return nullptr;
+ }
+
+ GLDisplay &display = displays[glwindow.gldisplay_id];
+
+ return display.egl_config;
+}
+
Error EGLManager::initialize(void *p_native_display) {
#if defined(GLAD_ENABLED) && !defined(EGL_STATIC)
// Loading EGL with a new display gets us just the bare minimum API. We'll then
diff --git a/drivers/egl/egl_manager.h b/drivers/egl/egl_manager.h
index f1b3dc99b78..2e1ae6ec53f 100644
--- a/drivers/egl/egl_manager.h
+++ b/drivers/egl/egl_manager.h
@@ -113,6 +113,8 @@ public:
bool is_using_vsync() const;
EGLContext get_context(DisplayServer::WindowID p_window_id);
+ EGLDisplay get_display(DisplayServer::WindowID p_window_id);
+ EGLConfig get_config(DisplayServer::WindowID p_window_id);
Error initialize(void *p_native_display = nullptr);
diff --git a/modules/openxr/SCsub b/modules/openxr/SCsub
index dd6a9214402..48c87bcd59c 100644
--- a/modules/openxr/SCsub
+++ b/modules/openxr/SCsub
@@ -26,7 +26,7 @@ elif env["platform"] == "linuxbsd":
env_openxr.AppendUnique(CPPDEFINES=["XR_USE_PLATFORM_XLIB"])
if env["wayland"]:
- env_openxr.AppendUnique(CPPDEFINES=["XR_USE_PLATFORM_WAYLAND"])
+ env_openxr.AppendUnique(CPPDEFINES=["XR_USE_PLATFORM_EGL"])
# FIXME: Review what needs to be set for Android and macOS.
env_openxr.AppendUnique(CPPDEFINES=["HAVE_SECURE_GETENV"])
diff --git a/modules/openxr/extensions/platform/openxr_opengl_extension.cpp b/modules/openxr/extensions/platform/openxr_opengl_extension.cpp
index caded14ca76..07e26298bfd 100644
--- a/modules/openxr/extensions/platform/openxr_opengl_extension.cpp
+++ b/modules/openxr/extensions/platform/openxr_opengl_extension.cpp
@@ -64,6 +64,9 @@ HashMap OpenXROpenGLExtension::get_requested_extensions() {
#else
request_extensions[XR_KHR_OPENGL_ENABLE_EXTENSION_NAME] = nullptr;
#endif
+#if defined(LINUXBSD_ENABLED) && defined(EGL_ENABLED)
+ request_extensions[XR_MNDX_EGL_ENABLE_EXTENSION_NAME] = &egl_extension_enabled;
+#endif
return request_extensions;
}
@@ -128,9 +131,14 @@ bool OpenXROpenGLExtension::check_graphics_api_support(XrVersion p_desired_versi
XrGraphicsBindingOpenGLWin32KHR OpenXROpenGLExtension::graphics_binding_gl;
#elif defined(ANDROID_ENABLED)
XrGraphicsBindingOpenGLESAndroidKHR OpenXROpenGLExtension::graphics_binding_gl;
-#elif defined(X11_ENABLED)
+#elif defined(LINUXBSD_ENABLED)
+#ifdef X11_ENABLED
XrGraphicsBindingOpenGLXlibKHR OpenXROpenGLExtension::graphics_binding_gl;
#endif
+#ifdef EGL_ENABLED
+XrGraphicsBindingEGLMNDX OpenXROpenGLExtension::graphics_binding_egl;
+#endif
+#endif
void *OpenXROpenGLExtension::set_session_create_and_get_next_pointer(void *p_next_pointer) {
XrVersion desired_version = XR_MAKE_VERSION(3, 3, 0);
@@ -142,10 +150,6 @@ void *OpenXROpenGLExtension::set_session_create_and_get_next_pointer(void *p_nex
DisplayServer *display_server = DisplayServer::get_singleton();
-#ifdef WAYLAND_ENABLED
- ERR_FAIL_COND_V_MSG(display_server->get_name() == "Wayland", p_next_pointer, "OpenXR is not yet supported on OpenGL Wayland.");
-#endif
-
#ifdef WIN32
graphics_binding_gl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR,
graphics_binding_gl.next = p_next_pointer;
@@ -159,7 +163,23 @@ void *OpenXROpenGLExtension::set_session_create_and_get_next_pointer(void *p_nex
graphics_binding_gl.display = (void *)display_server->window_get_native_handle(DisplayServer::DISPLAY_HANDLE);
graphics_binding_gl.config = (EGLConfig)0; // https://github.com/KhronosGroup/OpenXR-SDK-Source/blob/master/src/tests/hello_xr/graphicsplugin_opengles.cpp#L122
graphics_binding_gl.context = (void *)display_server->window_get_native_handle(DisplayServer::OPENGL_CONTEXT);
-#elif defined(X11_ENABLED)
+#else
+#if defined(EGL_ENABLED) && defined(WAYLAND_ENABLED)
+ if (display_server->get_name() == "Wayland") {
+ ERR_FAIL_COND_V_MSG(!egl_extension_enabled, p_next_pointer, "OpenXR cannot initialize on Wayland without the XR_MNDX_egl_enable extension.");
+
+ graphics_binding_egl.type = XR_TYPE_GRAPHICS_BINDING_EGL_MNDX;
+ graphics_binding_egl.next = p_next_pointer;
+
+ graphics_binding_egl.getProcAddress = eglGetProcAddress;
+ graphics_binding_egl.display = (void *)display_server->window_get_native_handle(DisplayServer::EGL_DISPLAY);
+ graphics_binding_egl.config = (void *)display_server->window_get_native_handle(DisplayServer::EGL_CONFIG);
+ graphics_binding_egl.context = (void *)display_server->window_get_native_handle(DisplayServer::OPENGL_CONTEXT);
+
+ return &graphics_binding_egl;
+ }
+#endif
+#if defined(X11_ENABLED)
graphics_binding_gl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR;
graphics_binding_gl.next = p_next_pointer;
@@ -175,8 +195,13 @@ void *OpenXROpenGLExtension::set_session_create_and_get_next_pointer(void *p_nex
graphics_binding_gl.visualid = 0;
graphics_binding_gl.glxFBConfig = 0;
#endif
+#endif
+#if defined(WIN32) || defined(ANDROID_ENABLED) || defined(X11_ENABLED)
return &graphics_binding_gl;
+#else
+ return p_next_pointer;
+#endif
}
void OpenXROpenGLExtension::get_usable_swapchain_formats(Vector &p_usable_swap_chains) {
diff --git a/modules/openxr/extensions/platform/openxr_opengl_extension.h b/modules/openxr/extensions/platform/openxr_opengl_extension.h
index 8da3ca48f4f..beb68e47e38 100644
--- a/modules/openxr/extensions/platform/openxr_opengl_extension.h
+++ b/modules/openxr/extensions/platform/openxr_opengl_extension.h
@@ -64,8 +64,17 @@ private:
static XrGraphicsBindingOpenGLWin32KHR graphics_binding_gl;
#elif defined(ANDROID_ENABLED)
static XrGraphicsBindingOpenGLESAndroidKHR graphics_binding_gl;
-#else // Linux/X11
+#elif defined(LINUXBSD_ENABLED)
+#ifdef X11_ENABLED
static XrGraphicsBindingOpenGLXlibKHR graphics_binding_gl;
+#endif
+#ifdef EGL_ENABLED
+ static XrGraphicsBindingEGLMNDX graphics_binding_egl;
+
+ bool egl_extension_enabled = false;
+#endif
+#else
+#error "OpenXR with OpenGL isn't supported on this platform"
#endif
struct SwapchainGraphicsData {
diff --git a/modules/openxr/openxr_platform_inc.h b/modules/openxr/openxr_platform_inc.h
index 957a87cbb21..09bc0c89a28 100644
--- a/modules/openxr/openxr_platform_inc.h
+++ b/modules/openxr/openxr_platform_inc.h
@@ -49,6 +49,13 @@
#else
#define XR_USE_GRAPHICS_API_OPENGL
#endif // ANDROID_ENABLED
+#if defined(LINUXBSD_ENABLED) && defined(EGL_ENABLED)
+#ifdef GLAD_ENABLED
+#include "thirdparty/glad/glad/egl.h"
+#else
+#include
+#endif // GLAD_ENABLED
+#endif // defined(LINUXBSD_ENABLED) && defined(EGL_ENABLED)
#ifdef X11_ENABLED
#define GL_GLEXT_PROTOTYPES 1
#define GL3_PROTOTYPES 1
diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp
index fa5b970a962..e3ee1dd6316 100644
--- a/platform/android/display_server_android.cpp
+++ b/platform/android/display_server_android.cpp
@@ -389,6 +389,14 @@ int64_t DisplayServerAndroid::window_get_native_handle(HandleType p_handle_type,
}
return 0;
}
+ case EGL_DISPLAY: {
+ // @todo Find a way to get this from the Java side.
+ return 0;
+ }
+ case EGL_CONFIG: {
+ // @todo Find a way to get this from the Java side.
+ return 0;
+ }
#endif
default: {
return 0;
diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp
index 71c721ca1dd..0a87c4a517f 100644
--- a/platform/linuxbsd/wayland/display_server_wayland.cpp
+++ b/platform/linuxbsd/wayland/display_server_wayland.cpp
@@ -627,6 +627,18 @@ int64_t DisplayServerWayland::window_get_native_handle(HandleType p_handle_type,
}
return 0;
} break;
+ case EGL_DISPLAY: {
+ if (egl_manager) {
+ return (int64_t)egl_manager->get_display(p_window);
+ }
+ return 0;
+ }
+ case EGL_CONFIG: {
+ if (egl_manager) {
+ return (int64_t)egl_manager->get_config(p_window);
+ }
+ return 0;
+ }
#endif // GLES3_ENABLED
default: {
diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp
index 293623e594f..f1be5d83dc7 100644
--- a/platform/linuxbsd/x11/display_server_x11.cpp
+++ b/platform/linuxbsd/x11/display_server_x11.cpp
@@ -1861,6 +1861,18 @@ int64_t DisplayServerX11::window_get_native_handle(HandleType p_handle_type, Win
}
return 0;
}
+ case EGL_DISPLAY: {
+ if (gl_manager_egl) {
+ return (int64_t)gl_manager_egl->get_display(p_window);
+ }
+ return 0;
+ }
+ case EGL_CONFIG: {
+ if (gl_manager_egl) {
+ return (int64_t)gl_manager_egl->get_config(p_window);
+ }
+ return 0;
+ }
#endif
default: {
return 0;
diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm
index 48cc7bbba3e..43469d981b5 100644
--- a/platform/macos/display_server_macos.mm
+++ b/platform/macos/display_server_macos.mm
@@ -2676,6 +2676,18 @@ int64_t DisplayServerMacOS::window_get_native_handle(HandleType p_handle_type, W
}
return 0;
}
+ case EGL_DISPLAY: {
+ if (gl_manager_angle) {
+ return (int64_t)gl_manager_angle->get_display(p_window);
+ }
+ return 0;
+ }
+ case EGL_CONFIG: {
+ if (gl_manager_angle) {
+ return (int64_t)gl_manager_angle->get_config(p_window);
+ }
+ return 0;
+ }
#endif
default: {
return 0;
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index c4275968291..fc49b63ddee 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -1665,6 +1665,18 @@ int64_t DisplayServerWindows::window_get_native_handle(HandleType p_handle_type,
}
return 0;
}
+ case EGL_DISPLAY: {
+ if (gl_manager_angle) {
+ return (int64_t)gl_manager_angle->get_display(p_window);
+ }
+ return 0;
+ }
+ case EGL_CONFIG: {
+ if (gl_manager_angle) {
+ return (int64_t)gl_manager_angle->get_config(p_window);
+ }
+ return 0;
+ }
#endif
default: {
return 0;
diff --git a/servers/display_server.cpp b/servers/display_server.cpp
index 428fb77c74c..dc5752cf4d4 100644
--- a/servers/display_server.cpp
+++ b/servers/display_server.cpp
@@ -1149,6 +1149,8 @@ void DisplayServer::_bind_methods() {
BIND_ENUM_CONSTANT(WINDOW_HANDLE);
BIND_ENUM_CONSTANT(WINDOW_VIEW);
BIND_ENUM_CONSTANT(OPENGL_CONTEXT);
+ BIND_ENUM_CONSTANT(EGL_DISPLAY);
+ BIND_ENUM_CONSTANT(EGL_CONFIG);
BIND_ENUM_CONSTANT(TTS_UTTERANCE_STARTED);
BIND_ENUM_CONSTANT(TTS_UTTERANCE_ENDED);
diff --git a/servers/display_server.h b/servers/display_server.h
index f25bf334a48..5726f267925 100644
--- a/servers/display_server.h
+++ b/servers/display_server.h
@@ -82,6 +82,8 @@ public:
WINDOW_HANDLE,
WINDOW_VIEW,
OPENGL_CONTEXT,
+ EGL_DISPLAY,
+ EGL_CONFIG,
};
enum Context {