Skip to content

Commit 07e759b

Browse files
committed
Merge pull request #97771 from dsnopek/openxr-linux-egl
OpenXR: Add support for Wayland on Linux
2 parents d3298fe + 256699e commit 07e759b

15 files changed

+149
-9
lines changed

.github/workflows/linux_builds.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ jobs:
106106
# TODO: Figure out somehow how to embed this one.
107107
- name: wayland-scanner dependency
108108
run: |
109-
sudo apt-get install libwayland-bin
109+
sudo apt-get install libwayland-bin libegl-dev
110110
111111
- name: Free disk space on runner
112112
run: |

doc/classes/DisplayServer.xml

+13
Original file line numberDiff line numberDiff line change
@@ -2152,12 +2152,14 @@
21522152
<constant name="DISPLAY_HANDLE" value="0" enum="HandleType">
21532153
Display handle:
21542154
- Linux (X11): [code]X11::Display*[/code] for the display.
2155+
- Linux (Wayland): [code]wl_display[/code] for the display.
21552156
- Android: [code]EGLDisplay[/code] for the display.
21562157
</constant>
21572158
<constant name="WINDOW_HANDLE" value="1" enum="HandleType">
21582159
Window handle:
21592160
- Windows: [code]HWND[/code] for the window.
21602161
- Linux (X11): [code]X11::Window*[/code] for the window.
2162+
- Linux (Wayland): [code]wl_surface[/code] for the window.
21612163
- macOS: [code]NSWindow*[/code] for the window.
21622164
- iOS: [code]UIViewController*[/code] for the view controller.
21632165
- Android: [code]jObject[/code] for the activity.
@@ -2172,9 +2174,20 @@
21722174
OpenGL context (only with the GL Compatibility renderer):
21732175
- Windows: [code]HGLRC[/code] for the window (native GL), or [code]EGLContext[/code] for the window (ANGLE).
21742176
- Linux (X11): [code]GLXContext*[/code] for the window.
2177+
- Linux (Wayland): [code]EGLContext[/code] for the window.
21752178
- macOS: [code]NSOpenGLContext*[/code] for the window (native GL), or [code]EGLContext[/code] for the window (ANGLE).
21762179
- Android: [code]EGLContext[/code] for the window.
21772180
</constant>
2181+
<constant name="EGL_DISPLAY" value="4" enum="HandleType">
2182+
- Windows: [code]EGLDisplay[/code] for the window (ANGLE).
2183+
- macOS: [code]EGLDisplay[/code] for the window (ANGLE).
2184+
- Linux (Wayland): [code]EGLDisplay[/code] for the window.
2185+
</constant>
2186+
<constant name="EGL_CONFIG" value="5" enum="HandleType">
2187+
- Windows: [code]EGLConfig[/code] for the window (ANGLE).
2188+
- macOS: [code]EGLConfig[/code] for the window (ANGLE).
2189+
- Linux (Wayland): [code]EGLConfig[/code] for the window.
2190+
</constant>
21782191
<constant name="TTS_UTTERANCE_STARTED" value="0" enum="TTSUtteranceEvent">
21792192
Utterance has begun to be spoken.
21802193
</constant>

drivers/egl/egl_manager.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,30 @@ EGLContext EGLManager::get_context(DisplayServer::WindowID p_window_id) {
414414
return display.egl_context;
415415
}
416416

417+
EGLDisplay EGLManager::get_display(DisplayServer::WindowID p_window_id) {
418+
GLWindow &glwindow = windows[p_window_id];
419+
420+
if (!glwindow.initialized) {
421+
return EGL_NO_CONTEXT;
422+
}
423+
424+
GLDisplay &display = displays[glwindow.gldisplay_id];
425+
426+
return display.egl_display;
427+
}
428+
429+
EGLConfig EGLManager::get_config(DisplayServer::WindowID p_window_id) {
430+
GLWindow &glwindow = windows[p_window_id];
431+
432+
if (!glwindow.initialized) {
433+
return nullptr;
434+
}
435+
436+
GLDisplay &display = displays[glwindow.gldisplay_id];
437+
438+
return display.egl_config;
439+
}
440+
417441
Error EGLManager::initialize(void *p_native_display) {
418442
#if defined(GLAD_ENABLED) && !defined(EGL_STATIC)
419443
// Loading EGL with a new display gets us just the bare minimum API. We'll then

drivers/egl/egl_manager.h

+2
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ class EGLManager {
113113
bool is_using_vsync() const;
114114

115115
EGLContext get_context(DisplayServer::WindowID p_window_id);
116+
EGLDisplay get_display(DisplayServer::WindowID p_window_id);
117+
EGLConfig get_config(DisplayServer::WindowID p_window_id);
116118

117119
Error initialize(void *p_native_display = nullptr);
118120

modules/openxr/SCsub

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ elif env["platform"] == "linuxbsd":
2626
env_openxr.AppendUnique(CPPDEFINES=["XR_USE_PLATFORM_XLIB"])
2727

2828
if env["wayland"]:
29-
env_openxr.AppendUnique(CPPDEFINES=["XR_USE_PLATFORM_WAYLAND"])
29+
env_openxr.AppendUnique(CPPDEFINES=["XR_USE_PLATFORM_EGL"])
3030

3131
# FIXME: Review what needs to be set for Android and macOS.
3232
env_openxr.AppendUnique(CPPDEFINES=["HAVE_SECURE_GETENV"])

modules/openxr/extensions/platform/openxr_opengl_extension.cpp

+31-6
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ HashMap<String, bool *> OpenXROpenGLExtension::get_requested_extensions() {
6464
#else
6565
request_extensions[XR_KHR_OPENGL_ENABLE_EXTENSION_NAME] = nullptr;
6666
#endif
67+
#if defined(LINUXBSD_ENABLED) && defined(EGL_ENABLED)
68+
request_extensions[XR_MNDX_EGL_ENABLE_EXTENSION_NAME] = &egl_extension_enabled;
69+
#endif
6770

6871
return request_extensions;
6972
}
@@ -128,9 +131,14 @@ bool OpenXROpenGLExtension::check_graphics_api_support(XrVersion p_desired_versi
128131
XrGraphicsBindingOpenGLWin32KHR OpenXROpenGLExtension::graphics_binding_gl;
129132
#elif defined(ANDROID_ENABLED)
130133
XrGraphicsBindingOpenGLESAndroidKHR OpenXROpenGLExtension::graphics_binding_gl;
131-
#elif defined(X11_ENABLED)
134+
#elif defined(LINUXBSD_ENABLED)
135+
#ifdef X11_ENABLED
132136
XrGraphicsBindingOpenGLXlibKHR OpenXROpenGLExtension::graphics_binding_gl;
133137
#endif
138+
#ifdef EGL_ENABLED
139+
XrGraphicsBindingEGLMNDX OpenXROpenGLExtension::graphics_binding_egl;
140+
#endif
141+
#endif
134142

135143
void *OpenXROpenGLExtension::set_session_create_and_get_next_pointer(void *p_next_pointer) {
136144
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
142150

143151
DisplayServer *display_server = DisplayServer::get_singleton();
144152

145-
#ifdef WAYLAND_ENABLED
146-
ERR_FAIL_COND_V_MSG(display_server->get_name() == "Wayland", p_next_pointer, "OpenXR is not yet supported on OpenGL Wayland.");
147-
#endif
148-
149153
#ifdef WIN32
150154
graphics_binding_gl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR,
151155
graphics_binding_gl.next = p_next_pointer;
@@ -159,7 +163,23 @@ void *OpenXROpenGLExtension::set_session_create_and_get_next_pointer(void *p_nex
159163
graphics_binding_gl.display = (void *)display_server->window_get_native_handle(DisplayServer::DISPLAY_HANDLE);
160164
graphics_binding_gl.config = (EGLConfig)0; // https://github.com/KhronosGroup/OpenXR-SDK-Source/blob/master/src/tests/hello_xr/graphicsplugin_opengles.cpp#L122
161165
graphics_binding_gl.context = (void *)display_server->window_get_native_handle(DisplayServer::OPENGL_CONTEXT);
162-
#elif defined(X11_ENABLED)
166+
#else
167+
#if defined(EGL_ENABLED) && defined(WAYLAND_ENABLED)
168+
if (display_server->get_name() == "Wayland") {
169+
ERR_FAIL_COND_V_MSG(!egl_extension_enabled, p_next_pointer, "OpenXR cannot initialize on Wayland without the XR_MNDX_egl_enable extension.");
170+
171+
graphics_binding_egl.type = XR_TYPE_GRAPHICS_BINDING_EGL_MNDX;
172+
graphics_binding_egl.next = p_next_pointer;
173+
174+
graphics_binding_egl.getProcAddress = eglGetProcAddress;
175+
graphics_binding_egl.display = (void *)display_server->window_get_native_handle(DisplayServer::EGL_DISPLAY);
176+
graphics_binding_egl.config = (void *)display_server->window_get_native_handle(DisplayServer::EGL_CONFIG);
177+
graphics_binding_egl.context = (void *)display_server->window_get_native_handle(DisplayServer::OPENGL_CONTEXT);
178+
179+
return &graphics_binding_egl;
180+
}
181+
#endif
182+
#if defined(X11_ENABLED)
163183
graphics_binding_gl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR;
164184
graphics_binding_gl.next = p_next_pointer;
165185

@@ -175,8 +195,13 @@ void *OpenXROpenGLExtension::set_session_create_and_get_next_pointer(void *p_nex
175195
graphics_binding_gl.visualid = 0;
176196
graphics_binding_gl.glxFBConfig = 0;
177197
#endif
198+
#endif
178199

200+
#if defined(WIN32) || defined(ANDROID_ENABLED) || defined(X11_ENABLED)
179201
return &graphics_binding_gl;
202+
#else
203+
return p_next_pointer;
204+
#endif
180205
}
181206

182207
void OpenXROpenGLExtension::get_usable_swapchain_formats(Vector<int64_t> &p_usable_swap_chains) {

modules/openxr/extensions/platform/openxr_opengl_extension.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,17 @@ class OpenXROpenGLExtension : public OpenXRGraphicsExtensionWrapper {
6464
static XrGraphicsBindingOpenGLWin32KHR graphics_binding_gl;
6565
#elif defined(ANDROID_ENABLED)
6666
static XrGraphicsBindingOpenGLESAndroidKHR graphics_binding_gl;
67-
#else // Linux/X11
67+
#elif defined(LINUXBSD_ENABLED)
68+
#ifdef X11_ENABLED
6869
static XrGraphicsBindingOpenGLXlibKHR graphics_binding_gl;
70+
#endif
71+
#ifdef EGL_ENABLED
72+
static XrGraphicsBindingEGLMNDX graphics_binding_egl;
73+
74+
bool egl_extension_enabled = false;
75+
#endif
76+
#else
77+
#error "OpenXR with OpenGL isn't supported on this platform"
6978
#endif
7079

7180
struct SwapchainGraphicsData {

modules/openxr/openxr_platform_inc.h

+7
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@
4949
#else
5050
#define XR_USE_GRAPHICS_API_OPENGL
5151
#endif // ANDROID_ENABLED
52+
#if defined(LINUXBSD_ENABLED) && defined(EGL_ENABLED)
53+
#ifdef GLAD_ENABLED
54+
#include "thirdparty/glad/glad/egl.h"
55+
#else
56+
#include <EGL/egl.h>
57+
#endif // GLAD_ENABLED
58+
#endif // defined(LINUXBSD_ENABLED) && defined(EGL_ENABLED)
5259
#ifdef X11_ENABLED
5360
#define GL_GLEXT_PROTOTYPES 1
5461
#define GL3_PROTOTYPES 1

platform/android/display_server_android.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,14 @@ int64_t DisplayServerAndroid::window_get_native_handle(HandleType p_handle_type,
389389
}
390390
return 0;
391391
}
392+
case EGL_DISPLAY: {
393+
// @todo Find a way to get this from the Java side.
394+
return 0;
395+
}
396+
case EGL_CONFIG: {
397+
// @todo Find a way to get this from the Java side.
398+
return 0;
399+
}
392400
#endif
393401
default: {
394402
return 0;

platform/linuxbsd/wayland/display_server_wayland.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,18 @@ int64_t DisplayServerWayland::window_get_native_handle(HandleType p_handle_type,
627627
}
628628
return 0;
629629
} break;
630+
case EGL_DISPLAY: {
631+
if (egl_manager) {
632+
return (int64_t)egl_manager->get_display(p_window);
633+
}
634+
return 0;
635+
}
636+
case EGL_CONFIG: {
637+
if (egl_manager) {
638+
return (int64_t)egl_manager->get_config(p_window);
639+
}
640+
return 0;
641+
}
630642
#endif // GLES3_ENABLED
631643

632644
default: {

platform/linuxbsd/x11/display_server_x11.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -1861,6 +1861,18 @@ int64_t DisplayServerX11::window_get_native_handle(HandleType p_handle_type, Win
18611861
}
18621862
return 0;
18631863
}
1864+
case EGL_DISPLAY: {
1865+
if (gl_manager_egl) {
1866+
return (int64_t)gl_manager_egl->get_display(p_window);
1867+
}
1868+
return 0;
1869+
}
1870+
case EGL_CONFIG: {
1871+
if (gl_manager_egl) {
1872+
return (int64_t)gl_manager_egl->get_config(p_window);
1873+
}
1874+
return 0;
1875+
}
18641876
#endif
18651877
default: {
18661878
return 0;

platform/macos/display_server_macos.mm

+12
Original file line numberDiff line numberDiff line change
@@ -2676,6 +2676,18 @@
26762676
}
26772677
return 0;
26782678
}
2679+
case EGL_DISPLAY: {
2680+
if (gl_manager_angle) {
2681+
return (int64_t)gl_manager_angle->get_display(p_window);
2682+
}
2683+
return 0;
2684+
}
2685+
case EGL_CONFIG: {
2686+
if (gl_manager_angle) {
2687+
return (int64_t)gl_manager_angle->get_config(p_window);
2688+
}
2689+
return 0;
2690+
}
26792691
#endif
26802692
default: {
26812693
return 0;

platform/windows/display_server_windows.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -1665,6 +1665,18 @@ int64_t DisplayServerWindows::window_get_native_handle(HandleType p_handle_type,
16651665
}
16661666
return 0;
16671667
}
1668+
case EGL_DISPLAY: {
1669+
if (gl_manager_angle) {
1670+
return (int64_t)gl_manager_angle->get_display(p_window);
1671+
}
1672+
return 0;
1673+
}
1674+
case EGL_CONFIG: {
1675+
if (gl_manager_angle) {
1676+
return (int64_t)gl_manager_angle->get_config(p_window);
1677+
}
1678+
return 0;
1679+
}
16681680
#endif
16691681
default: {
16701682
return 0;

servers/display_server.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,8 @@ void DisplayServer::_bind_methods() {
11491149
BIND_ENUM_CONSTANT(WINDOW_HANDLE);
11501150
BIND_ENUM_CONSTANT(WINDOW_VIEW);
11511151
BIND_ENUM_CONSTANT(OPENGL_CONTEXT);
1152+
BIND_ENUM_CONSTANT(EGL_DISPLAY);
1153+
BIND_ENUM_CONSTANT(EGL_CONFIG);
11521154

11531155
BIND_ENUM_CONSTANT(TTS_UTTERANCE_STARTED);
11541156
BIND_ENUM_CONSTANT(TTS_UTTERANCE_ENDED);

servers/display_server.h

+2
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ class DisplayServer : public Object {
8282
WINDOW_HANDLE,
8383
WINDOW_VIEW,
8484
OPENGL_CONTEXT,
85+
EGL_DISPLAY,
86+
EGL_CONFIG,
8587
};
8688

8789
enum Context {

0 commit comments

Comments
 (0)