Don’t let the driver guess the platform

EGL_EXT_platform_base, and later EGL 1.5, introduced two new functions
which take a platform enum instead of guessing based on the shape of the
passed pointer data, which is incredibly error-prone.

This commit makes use of them when they’re exposed by the driver, and
falls back to the old insecure API when not.
This commit is contained in:
Emmanuel Gil Peyrot 2019-12-27 20:29:02 +01:00
parent d7ae90a790
commit 29be50ea99
4 changed files with 97 additions and 10 deletions

View File

@ -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 arent, 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 isnt 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,

View File

@ -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;

View File

@ -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

View File

@ -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