diff --git a/glfw/cocoa_window.m b/glfw/cocoa_window.m index f5c37d452..313ca63aa 100644 --- a/glfw/cocoa_window.m +++ b/glfw/cocoa_window.m @@ -2105,6 +2105,11 @@ const char* _glfwPlatformGetClipboardString(void) return _glfw.ns.clipboardString; } +EGLenum _glfwPlatformGetEGLPlatform(void) +{ + return 0; +} + EGLNativeDisplayType _glfwPlatformGetEGLNativeDisplay(void) { return EGL_DEFAULT_DISPLAY; diff --git a/glfw/egl_context.c b/glfw/egl_context.c index 26ff7be0f..67dc18679 100644 --- a/glfw/egl_context.c +++ b/glfw/egl_context.c @@ -273,6 +273,7 @@ static void destroyContextEGL(_GLFWwindow* window) bool _glfwInitEGL(void) { int i; + const char* extensions; const char* sonames[] = { #if defined(_GLFW_EGL_LIBRARY) @@ -351,7 +352,39 @@ bool _glfwInitEGL(void) return false; } - _glfw.egl.display = eglGetDisplay(_glfwPlatformGetEGLNativeDisplay()); + extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); + if (extensions && eglGetError() == EGL_SUCCESS) + _glfw.egl.EXT_client_extensions = true; + + if (_glfw.egl.EXT_client_extensions) + { + _glfw.egl.EXT_platform_base = + _glfwStringInExtensionString("EGL_EXT_platform_base", extensions); + _glfw.egl.EXT_platform_x11 = + _glfwStringInExtensionString("EGL_EXT_platform_x11", extensions); + _glfw.egl.EXT_platform_wayland = + _glfwStringInExtensionString("EGL_EXT_platform_wayland", extensions); + } + + if (_glfw.egl.EXT_platform_base) + { + _glfw.egl.GetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC) + eglGetProcAddress("eglGetPlatformDisplayEXT"); + _glfw.egl.CreatePlatformWindowSurfaceEXT = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) + eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT"); + } + + _glfw.egl.platform = _glfwPlatformGetEGLPlatform(); + if (_glfw.egl.platform) + { + _glfw.egl.display = + eglGetPlatformDisplayEXT(_glfw.egl.platform, + _glfwPlatformGetEGLNativeDisplay(), + NULL); + } + else + _glfw.egl.display = eglGetDisplay(_glfwPlatformGetEGLNativeDisplay()); + if (_glfw.egl.display == EGL_NO_DISPLAY) { _glfwInputError(GLFW_API_UNAVAILABLE, @@ -419,6 +452,7 @@ bool _glfwCreateContextEGL(_GLFWwindow* window, EGLint attribs[40]; EGLConfig config; EGLContext share = NULL; + EGLNativeWindowType native; int index = 0; if (!_glfw.egl.display) @@ -554,11 +588,18 @@ bool _glfwCreateContextEGL(_GLFWwindow* window, setAttrib(EGL_NONE, EGL_NONE); - window->context.egl.surface = - eglCreateWindowSurface(_glfw.egl.display, - config, - _glfwPlatformGetEGLNativeWindow(window), - attribs); + native = _glfwPlatformGetEGLNativeWindow(window); + if (_glfw.egl.platform) + { + window->context.egl.surface = + eglCreatePlatformWindowSurfaceEXT(_glfw.egl.display, config, native, attribs); + } + else + { + window->context.egl.surface = + eglCreateWindowSurface(_glfw.egl.display, config, native, attribs); + } + if (window->context.egl.surface == EGL_NO_SURFACE) { _glfwInputError(GLFW_PLATFORM_ERROR, diff --git a/glfw/egl_context.h b/glfw/egl_context.h index 965dc53c2..f6a80a987 100644 --- a/glfw/egl_context.h +++ b/glfw/egl_context.h @@ -92,6 +92,8 @@ #define EGL_CONTEXT_RELEASE_BEHAVIOR_KHR 0x2097 #define EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR 0 #define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098 +#define EGL_PLATFORM_X11_EXT 0x31d5 +#define EGL_PLATFORM_WAYLAND_EXT 0x31d8 typedef int EGLint; typedef unsigned int EGLBoolean; @@ -140,6 +142,11 @@ typedef GLFWglproc (EGLAPIENTRY * PFN_eglGetProcAddress)(const char*); #define eglQueryString _glfw.egl.QueryString #define eglGetProcAddress _glfw.egl.GetProcAddress +typedef EGLDisplay (EGLAPIENTRY * PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum,void*,const EGLint*); +typedef EGLSurface (EGLAPIENTRY * PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)(EGLDisplay,EGLConfig,void*,const EGLint*); +#define eglGetPlatformDisplayEXT _glfw.egl.GetPlatformDisplayEXT +#define eglCreatePlatformWindowSurfaceEXT _glfw.egl.CreatePlatformWindowSurfaceEXT + #define _GLFW_EGL_CONTEXT_STATE _GLFWcontextEGL egl #define _GLFW_EGL_LIBRARY_CONTEXT_STATE _GLFWlibraryEGL egl @@ -160,6 +167,7 @@ typedef struct _GLFWcontextEGL // typedef struct _GLFWlibraryEGL { + EGLenum platform; EGLDisplay display; EGLint major, minor; bool prefix; @@ -169,6 +177,10 @@ typedef struct _GLFWlibraryEGL bool KHR_gl_colorspace; bool KHR_get_all_proc_addresses; bool KHR_context_flush_control; + bool EXT_client_extensions; + bool EXT_platform_base; + bool EXT_platform_x11; + bool EXT_platform_wayland; void* handle; @@ -190,6 +202,9 @@ typedef struct _GLFWlibraryEGL PFN_eglQueryString QueryString; PFN_eglGetProcAddress GetProcAddress; + PFNEGLGETPLATFORMDISPLAYEXTPROC GetPlatformDisplayEXT; + PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC CreatePlatformWindowSurfaceEXT; + } _GLFWlibraryEGL; diff --git a/glfw/internal.h b/glfw/internal.h index bbc7696c1..784a0105f 100644 --- a/glfw/internal.h +++ b/glfw/internal.h @@ -721,6 +721,7 @@ void _glfwPlatformWaitEvents(void); void _glfwPlatformWaitEventsTimeout(monotonic_t timeout); void _glfwPlatformPostEmptyEvent(void); +EGLenum _glfwPlatformGetEGLPlatform(void); EGLNativeDisplayType _glfwPlatformGetEGLNativeDisplay(void); EGLNativeWindowType _glfwPlatformGetEGLNativeWindow(_GLFWwindow* window); diff --git a/glfw/wl_window.c b/glfw/wl_window.c index df0dcf1cd..cc1c266ed 100644 --- a/glfw/wl_window.c +++ b/glfw/wl_window.c @@ -2008,6 +2008,14 @@ const char* _glfwPlatformGetPrimarySelectionString(void) return NULL; } +EGLenum _glfwPlatformGetEGLPlatform(void) +{ + if (_glfw.egl.EXT_platform_base && _glfw.egl.EXT_platform_wayland) + return EGL_PLATFORM_WAYLAND_EXT; + else + return 0; +} + EGLNativeDisplayType _glfwPlatformGetEGLNativeDisplay(void) { return _glfw.wl.display; diff --git a/glfw/x11_window.c b/glfw/x11_window.c index adde3eedf..5de5db20b 100644 --- a/glfw/x11_window.c +++ b/glfw/x11_window.c @@ -2855,6 +2855,14 @@ const char* _glfwPlatformGetPrimarySelectionString(void) return getSelectionString(_glfw.x11.PRIMARY); } +EGLenum _glfwPlatformGetEGLPlatform(void) +{ + if (_glfw.egl.EXT_platform_base && _glfw.egl.EXT_platform_x11) + return EGL_PLATFORM_X11_EXT; + else + return 0; +} + EGLNativeDisplayType _glfwPlatformGetEGLNativeDisplay(void) { return _glfw.x11.display; @@ -2862,7 +2870,10 @@ EGLNativeDisplayType _glfwPlatformGetEGLNativeDisplay(void) EGLNativeWindowType _glfwPlatformGetEGLNativeWindow(_GLFWwindow* window) { - return (EGLNativeWindowType) window->x11.handle; + if (_glfw.egl.platform) + return &window->x11.handle; + else + return (EGLNativeWindowType) window->x11.handle; } void _glfwPlatformGetRequiredInstanceExtensions(char** extensions)