diff --git a/glfw/cocoa_window.m b/glfw/cocoa_window.m index 313ca63aa..3a905be5c 100644 --- a/glfw/cocoa_window.m +++ b/glfw/cocoa_window.m @@ -2105,8 +2105,34 @@ const char* _glfwPlatformGetClipboardString(void) return _glfw.ns.clipboardString; } -EGLenum _glfwPlatformGetEGLPlatform(void) +EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs) { + if (_glfw.egl.ANGLE_platform_angle) + { + int type = 0; + + if (_glfw.egl.ANGLE_platform_angle_opengl) + { + if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_OPENGL) + type = EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE; + } + + if (_glfw.egl.ANGLE_platform_angle_metal) + { + if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_METAL) + type = EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE; + } + + if (type) + { + *attribs = calloc(3, sizeof(EGLint)); + (*attribs)[0] = EGL_PLATFORM_ANGLE_TYPE_ANGLE; + (*attribs)[1] = type; + (*attribs)[2] = EGL_NONE; + return EGL_PLATFORM_ANGLE_ANGLE; + } + } + return 0; } diff --git a/glfw/egl_context.c b/glfw/egl_context.c index 67dc18679..a02efb493 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; + EGLint* attribs = NULL; const char* extensions; const char* sonames[] = { @@ -364,6 +365,16 @@ bool _glfwInitEGL(void) _glfwStringInExtensionString("EGL_EXT_platform_x11", extensions); _glfw.egl.EXT_platform_wayland = _glfwStringInExtensionString("EGL_EXT_platform_wayland", extensions); + _glfw.egl.ANGLE_platform_angle = + _glfwStringInExtensionString("EGL_ANGLE_platform_angle", extensions); + _glfw.egl.ANGLE_platform_angle_opengl = + _glfwStringInExtensionString("EGL_ANGLE_platform_angle_opengl", extensions); + _glfw.egl.ANGLE_platform_angle_d3d = + _glfwStringInExtensionString("EGL_ANGLE_platform_angle_d3d", extensions); + _glfw.egl.ANGLE_platform_angle_vulkan = + _glfwStringInExtensionString("EGL_ANGLE_platform_angle_vulkan", extensions); + _glfw.egl.ANGLE_platform_angle_metal = + _glfwStringInExtensionString("EGL_ANGLE_platform_angle_metal", extensions); } if (_glfw.egl.EXT_platform_base) @@ -374,17 +385,19 @@ bool _glfwInitEGL(void) eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT"); } - _glfw.egl.platform = _glfwPlatformGetEGLPlatform(); + _glfw.egl.platform = _glfwPlatformGetEGLPlatform(&attribs); if (_glfw.egl.platform) { _glfw.egl.display = eglGetPlatformDisplayEXT(_glfw.egl.platform, _glfwPlatformGetEGLNativeDisplay(), - NULL); + attribs); } else _glfw.egl.display = eglGetDisplay(_glfwPlatformGetEGLNativeDisplay()); + free(attribs); + if (_glfw.egl.display == EGL_NO_DISPLAY) { _glfwInputError(GLFW_API_UNAVAILABLE, @@ -589,7 +602,9 @@ bool _glfwCreateContextEGL(_GLFWwindow* window, setAttrib(EGL_NONE, EGL_NONE); native = _glfwPlatformGetEGLNativeWindow(window); - if (_glfw.egl.platform) + // HACK: ANGLE does not implement eglCreatePlatformWindowSurfaceEXT + // despite reporting EGL_EXT_platform_base + if (_glfw.egl.platform && _glfw.egl.platform != EGL_PLATFORM_ANGLE_ANGLE) { window->context.egl.surface = eglCreatePlatformWindowSurfaceEXT(_glfw.egl.display, config, native, attribs); diff --git a/glfw/egl_context.h b/glfw/egl_context.h index c7999e42f..2c8b3add8 100644 --- a/glfw/egl_context.h +++ b/glfw/egl_context.h @@ -94,6 +94,15 @@ #define EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR 0x2098 #define EGL_PLATFORM_X11_EXT 0x31d5 #define EGL_PLATFORM_WAYLAND_EXT 0x31d8 +#define EGL_PLATFORM_ANGLE_ANGLE 0x3202 +#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203 +#define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320d +#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320e +#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207 +#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208 +#define EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE 0x3450 +#define EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE 0x3489 +#define EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE 0x348f typedef int EGLint; typedef unsigned int EGLBoolean; @@ -177,6 +186,11 @@ typedef struct _GLFWlibraryEGL bool EXT_platform_base; bool EXT_platform_x11; bool EXT_platform_wayland; + bool ANGLE_platform_angle; + bool ANGLE_platform_angle_opengl; + bool ANGLE_platform_angle_d3d; + bool ANGLE_platform_angle_vulkan; + bool ANGLE_platform_angle_metal; void* handle; diff --git a/glfw/glfw3.h b/glfw/glfw3.h index 00af40498..c537b9356 100644 --- a/glfw/glfw3.h +++ b/glfw/glfw3.h @@ -1147,6 +1147,14 @@ extern "C" { #define GLFW_EGL_CONTEXT_API 0x00036002 #define GLFW_OSMESA_CONTEXT_API 0x00036003 +#define GLFW_ANGLE_PLATFORM_TYPE_NONE 0x00037001 +#define GLFW_ANGLE_PLATFORM_TYPE_OPENGL 0x00037002 +#define GLFW_ANGLE_PLATFORM_TYPE_OPENGLES 0x00037003 +#define GLFW_ANGLE_PLATFORM_TYPE_D3D9 0x00037004 +#define GLFW_ANGLE_PLATFORM_TYPE_D3D11 0x00037005 +#define GLFW_ANGLE_PLATFORM_TYPE_VULKAN 0x00037007 +#define GLFW_ANGLE_PLATFORM_TYPE_METAL 0x00037008 + /*! @defgroup shapes Standard cursor shapes * @brief Standard system cursor shapes. * @@ -1180,8 +1188,13 @@ typedef enum { * Joystick hat buttons [init hint](@ref GLFW_JOYSTICK_HAT_BUTTONS). */ #define GLFW_JOYSTICK_HAT_BUTTONS 0x00050001 -#define GLFW_DEBUG_KEYBOARD 0x00050002 -#define GLFW_ENABLE_JOYSTICKS 0x00050003 +/*! @brief ANGLE rendering backend init hint. + * + * ANGLE rendering backend [init hint](@ref GLFW_ANGLE_PLATFORM_TYPE_hint). + */ +#define GLFW_ANGLE_PLATFORM_TYPE 0x00050002 +#define GLFW_DEBUG_KEYBOARD 0x00050003 +#define GLFW_ENABLE_JOYSTICKS 0x00050004 /*! @brief macOS specific init hint. * * macOS specific [init hint](@ref GLFW_COCOA_CHDIR_RESOURCES_hint). diff --git a/glfw/init.c b/glfw/init.c index b218de346..ca3af4d0c 100644 --- a/glfw/init.c +++ b/glfw/init.c @@ -53,6 +53,7 @@ static GLFWerrorfun _glfwErrorCallback; static _GLFWinitconfig _glfwInitHints = { true, // hat buttons + GLFW_ANGLE_PLATFORM_TYPE_NONE, // ANGLE backend false, // debug keyboard true, // enable joystick { @@ -281,6 +282,9 @@ GLFWAPI void glfwInitHint(int hint, int value) case GLFW_JOYSTICK_HAT_BUTTONS: _glfwInitHints.hatButtons = value; return; + case GLFW_ANGLE_PLATFORM_TYPE: + _glfwInitHints.angleType = value; + return; case GLFW_DEBUG_KEYBOARD: _glfwInitHints.debugKeyboard = value; return; diff --git a/glfw/internal.h b/glfw/internal.h index e61bb2da6..227458151 100644 --- a/glfw/internal.h +++ b/glfw/internal.h @@ -274,6 +274,7 @@ struct _GLFWerror struct _GLFWinitconfig { bool hatButtons; + int angleType; bool debugKeyboard; bool enableJoysticks; struct { @@ -724,7 +725,7 @@ void _glfwPlatformWaitEvents(void); void _glfwPlatformWaitEventsTimeout(monotonic_t timeout); void _glfwPlatformPostEmptyEvent(void); -EGLenum _glfwPlatformGetEGLPlatform(void); +EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs); EGLNativeDisplayType _glfwPlatformGetEGLNativeDisplay(void); EGLNativeWindowType _glfwPlatformGetEGLNativeWindow(_GLFWwindow* window); diff --git a/glfw/wl_window.c b/glfw/wl_window.c index 58d474035..ef9f87cb9 100644 --- a/glfw/wl_window.c +++ b/glfw/wl_window.c @@ -2014,7 +2014,7 @@ const char* _glfwPlatformGetPrimarySelectionString(void) return NULL; } -EGLenum _glfwPlatformGetEGLPlatform(void) +EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs UNUSED) { if (_glfw.egl.EXT_platform_base && _glfw.egl.EXT_platform_wayland) return EGL_PLATFORM_WAYLAND_EXT; diff --git a/glfw/x11_window.c b/glfw/x11_window.c index 5de5db20b..d35465573 100644 --- a/glfw/x11_window.c +++ b/glfw/x11_window.c @@ -2855,12 +2855,40 @@ const char* _glfwPlatformGetPrimarySelectionString(void) return getSelectionString(_glfw.x11.PRIMARY); } -EGLenum _glfwPlatformGetEGLPlatform(void) +EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs) { + if (_glfw.egl.ANGLE_platform_angle) + { + int type = 0; + + if (_glfw.egl.ANGLE_platform_angle_opengl) + { + if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_OPENGL) + type = EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE; + } + + if (_glfw.egl.ANGLE_platform_angle_vulkan) + { + if (_glfw.hints.init.angleType == GLFW_ANGLE_PLATFORM_TYPE_VULKAN) + type = EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE; + } + + if (type) + { + *attribs = calloc(5, sizeof(EGLint)); + (*attribs)[0] = EGL_PLATFORM_ANGLE_TYPE_ANGLE; + (*attribs)[1] = type; + (*attribs)[2] = EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE; + (*attribs)[3] = EGL_PLATFORM_X11_EXT; + (*attribs)[4] = EGL_NONE; + return EGL_PLATFORM_ANGLE_ANGLE; + } + } + if (_glfw.egl.EXT_platform_base && _glfw.egl.EXT_platform_x11) return EGL_PLATFORM_X11_EXT; - else - return 0; + + return 0; } EGLNativeDisplayType _glfwPlatformGetEGLNativeDisplay(void) diff --git a/kitty/glfw-wrapper.h b/kitty/glfw-wrapper.h index d6d896c1d..a32a727a7 100644 --- a/kitty/glfw-wrapper.h +++ b/kitty/glfw-wrapper.h @@ -885,6 +885,14 @@ #define GLFW_EGL_CONTEXT_API 0x00036002 #define GLFW_OSMESA_CONTEXT_API 0x00036003 +#define GLFW_ANGLE_PLATFORM_TYPE_NONE 0x00037001 +#define GLFW_ANGLE_PLATFORM_TYPE_OPENGL 0x00037002 +#define GLFW_ANGLE_PLATFORM_TYPE_OPENGLES 0x00037003 +#define GLFW_ANGLE_PLATFORM_TYPE_D3D9 0x00037004 +#define GLFW_ANGLE_PLATFORM_TYPE_D3D11 0x00037005 +#define GLFW_ANGLE_PLATFORM_TYPE_VULKAN 0x00037007 +#define GLFW_ANGLE_PLATFORM_TYPE_METAL 0x00037008 + /*! @defgroup shapes Standard cursor shapes * @brief Standard system cursor shapes. * @@ -918,8 +926,13 @@ typedef enum { * Joystick hat buttons [init hint](@ref GLFW_JOYSTICK_HAT_BUTTONS). */ #define GLFW_JOYSTICK_HAT_BUTTONS 0x00050001 -#define GLFW_DEBUG_KEYBOARD 0x00050002 -#define GLFW_ENABLE_JOYSTICKS 0x00050003 +/*! @brief ANGLE rendering backend init hint. + * + * ANGLE rendering backend [init hint](@ref GLFW_ANGLE_PLATFORM_TYPE_hint). + */ +#define GLFW_ANGLE_PLATFORM_TYPE 0x00050002 +#define GLFW_DEBUG_KEYBOARD 0x00050003 +#define GLFW_ENABLE_JOYSTICKS 0x00050004 /*! @brief macOS specific init hint. * * macOS specific [init hint](@ref GLFW_COCOA_CHDIR_RESOURCES_hint).