diff --git a/src/egl_context.c b/src/egl_context.c index 706a79224..f766d1704 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -395,7 +395,58 @@ GLFWbool _glfwInitEGL(void) return GLFW_FALSE; } - _glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY); + // Test for the presence of EGL_EXT_platform_base and related extensions on + // EGL_NO_DISPLAY. + _glfw.egl.display = EGL_NO_DISPLAY; + + // If the KHR version of the extension for the relevant platform is + // exposed, we can assume we are on EGL 1.5 and eglGetPlatformDisplay() and + // eglCreatePlatformWindowSurface() will be available. + // + // If they aren’t, we check for the EXT version, which requires both + // EXT_platform_base and the platform extension to exist, and uses + // EXT-suffixed symbols. + // + // If none of these extensions are exposed, we use the error-prone + // eglGetDisplay() and eglCreateWindowSurface() symbols instead. +#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND) + _glfw.egl.platform_supported = + extensionSupportedEGL(_GLFW_EGL_KHR_PLATFORM); + if (_glfw.egl.platform_supported) + { + _glfw.egl.GetPlatformDisplay = (PFN_eglGetPlatformDisplay) + _glfw_dlsym(_glfw.egl.handle, "eglGetPlatformDisplay"); + _glfw.egl.CreatePlatformWindowSurface = (PFN_eglCreatePlatformWindowSurface) + _glfw_dlsym(_glfw.egl.handle, "eglCreatePlatformWindowSurface"); + } + else + { + _glfw.egl.platform_supported = + extensionSupportedEGL("EGL_EXT_platform_base") && + extensionSupportedEGL(_GLFW_EGL_EXT_PLATFORM); + if (_glfw.egl.platform_supported) + { + _glfw.egl.GetPlatformDisplay = (PFN_eglGetPlatformDisplay) + eglGetProcAddress("eglGetPlatformDisplayEXT"); + _glfw.egl.CreatePlatformWindowSurface = (PFN_eglCreatePlatformWindowSurface) + eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT"); + } + } +#else + _glfw.egl.platform_supported = GLFW_FALSE; +#endif + + if (_glfw.egl.platform_supported) + { + _glfw.egl.display = eglGetPlatformDisplay(_GLFW_EGL_NATIVE_PLATFORM, _GLFW_EGL_NATIVE_DISPLAY, NULL); + } + else + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "EGL: Falling back to the unsafe eglGetDisplay() API"); + _glfw.egl.display = eglGetDisplay(_GLFW_EGL_NATIVE_DISPLAY); + } + if (_glfw.egl.display == EGL_NO_DISPLAY) { _glfwInputError(GLFW_API_UNAVAILABLE, @@ -600,11 +651,29 @@ GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, setAttrib(EGL_NONE, EGL_NONE); } - window->context.egl.surface = - eglCreateWindowSurface(_glfw.egl.display, - config, - _GLFW_EGL_NATIVE_WINDOW, - attribs); + if (_glfw.egl.platform_supported) + { + window->context.egl.surface = + eglCreatePlatformWindowSurface(_glfw.egl.display, + config, +#if defined(_GLFW_X11) + // An X11 Window isn’t a pointer, so + // we have to take its address here. + &_GLFW_EGL_NATIVE_WINDOW, +#else + _GLFW_EGL_NATIVE_WINDOW, +#endif + attribs); + } + else + { + window->context.egl.surface = + eglCreateWindowSurface(_glfw.egl.display, + config, + _GLFW_EGL_NATIVE_WINDOW, + attribs); + } + if (window->context.egl.surface == EGL_NO_SURFACE) { _glfwInputError(GLFW_PLATFORM_ERROR, diff --git a/src/egl_context.h b/src/egl_context.h index 8bfb7db6a..ae16d7f1a 100644 --- a/src/egl_context.h +++ b/src/egl_context.h @@ -107,6 +107,11 @@ typedef struct wl_egl_window* EGLNativeWindowType; #define EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR 0 #define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098 +#define EGL_PLATFORM_WAYLAND_EXT 0x31d8 +#define EGL_PLATFORM_X11_EXT 0x31d5 + +#define EGL_PLATFORM_GBM_MESA 0x31d7 + typedef int EGLint; typedef unsigned int EGLBoolean; typedef unsigned int EGLenum; @@ -132,6 +137,8 @@ typedef EGLBoolean (EGLAPIENTRY * PFN_eglSwapBuffers)(EGLDisplay,EGLSurface); typedef EGLBoolean (EGLAPIENTRY * PFN_eglSwapInterval)(EGLDisplay,EGLint); typedef const char* (EGLAPIENTRY * PFN_eglQueryString)(EGLDisplay,EGLint); typedef GLFWglproc (EGLAPIENTRY * PFN_eglGetProcAddress)(const char*); +typedef EGLDisplay (EGLAPIENTRY * PFN_eglGetPlatformDisplay)(EGLenum,void*,const EGLint*); +typedef EGLSurface (EGLAPIENTRY * PFN_eglCreatePlatformWindowSurface)(EGLDisplay,EGLConfig,void*,const EGLint*); #define eglGetConfigAttrib _glfw.egl.GetConfigAttrib #define eglGetConfigs _glfw.egl.GetConfigs #define eglGetDisplay _glfw.egl.GetDisplay @@ -148,6 +155,8 @@ typedef GLFWglproc (EGLAPIENTRY * PFN_eglGetProcAddress)(const char*); #define eglSwapInterval _glfw.egl.SwapInterval #define eglQueryString _glfw.egl.QueryString #define eglGetProcAddress _glfw.egl.GetProcAddress +#define eglGetPlatformDisplay _glfw.egl.GetPlatformDisplay +#define eglCreatePlatformWindowSurface _glfw.egl.CreatePlatformWindowSurface #define _GLFW_EGL_CONTEXT_STATE _GLFWcontextEGL egl #define _GLFW_EGL_LIBRARY_CONTEXT_STATE _GLFWlibraryEGL egl @@ -178,6 +187,7 @@ typedef struct _GLFWlibraryEGL GLFWbool KHR_gl_colorspace; GLFWbool KHR_get_all_proc_addresses; GLFWbool KHR_context_flush_control; + GLFWbool platform_supported; void* handle; @@ -197,6 +207,8 @@ typedef struct _GLFWlibraryEGL PFN_eglSwapInterval SwapInterval; PFN_eglQueryString QueryString; PFN_eglGetProcAddress GetProcAddress; + PFN_eglGetPlatformDisplay GetPlatformDisplay; + PFN_eglCreatePlatformWindowSurface CreatePlatformWindowSurface; } _GLFWlibraryEGL; diff --git a/src/wl_platform.h b/src/wl_platform.h index 542cc78d0..ea4dbb50c 100644 --- a/src/wl_platform.h +++ b/src/wl_platform.h @@ -67,8 +67,11 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR #define _glfw_dlclose(handle) dlclose(handle) #define _glfw_dlsym(handle, name) dlsym(handle, name) -#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->wl.native) -#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.wl.display) +#define _GLFW_EGL_NATIVE_WINDOW (window->wl.native) +#define _GLFW_EGL_NATIVE_DISPLAY (_glfw.wl.display) +#define _GLFW_EGL_NATIVE_PLATFORM EGL_PLATFORM_WAYLAND_EXT +#define _GLFW_EGL_KHR_PLATFORM "EGL_KHR_platform_wayland" +#define _GLFW_EGL_EXT_PLATFORM "EGL_EXT_platform_wayland" #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWayland wl #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryWayland wl diff --git a/src/x11_platform.h b/src/x11_platform.h index fe82a72b2..5bbc1214e 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -373,8 +373,11 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(Vk #define _glfw_dlclose(handle) dlclose(handle) #define _glfw_dlsym(handle, name) dlsym(handle, name) -#define _GLFW_EGL_NATIVE_WINDOW ((EGLNativeWindowType) window->x11.handle) -#define _GLFW_EGL_NATIVE_DISPLAY ((EGLNativeDisplayType) _glfw.x11.display) +#define _GLFW_EGL_NATIVE_WINDOW (window->x11.handle) +#define _GLFW_EGL_NATIVE_DISPLAY (_glfw.x11.display) +#define _GLFW_EGL_NATIVE_PLATFORM EGL_PLATFORM_X11_EXT +#define _GLFW_EGL_KHR_PLATFORM "EGL_KHR_platform_x11" +#define _GLFW_EGL_EXT_PLATFORM "EGL_EXT_platform_x11" #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 x11 #define _GLFW_PLATFORM_LIBRARY_WINDOW_STATE _GLFWlibraryX11 x11