summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsfan5 <sfan5@live.de>2021-11-15 22:51:33 +0100
committersfan5 <sfan5@live.de>2021-11-17 22:38:34 +0100
commitb69af0abefd7fa78fbc5c233e264c9155b091ad9 (patch)
tree7b6111f04c918864257ee7967239959411d37ba3
parentc3d78b00173a37f715510761f4cd6d01b1e403a2 (diff)
downloadmpv-b69af0abefd7fa78fbc5c233e264c9155b091ad9.tar.bz2
mpv-b69af0abefd7fa78fbc5c233e264c9155b091ad9.tar.xz
egl_helpers: introduce wrapper around eglCreatePlatformWindowSurface
It abstracts EGL 1.5, extension checks and other inconsistencies away. This can be used in context code as the (preferred) alternative to eglCreateWindowSurface().
-rw-r--r--video/out/opengl/egl_helpers.c59
-rw-r--r--video/out/opengl/egl_helpers.h3
2 files changed, 50 insertions, 12 deletions
diff --git a/video/out/opengl/egl_helpers.c b/video/out/opengl/egl_helpers.c
index 6c3604daa5..b3e11c6f43 100644
--- a/video/out/opengl/egl_helpers.c
+++ b/video/out/opengl/egl_helpers.c
@@ -276,6 +276,20 @@ void mpegl_load_functions(struct GL *gl, struct mp_log *log)
gl->SwapInterval = swap_interval;
}
+static bool is_egl15(void)
+{
+ // It appears that EGL 1.4 is specified to _require_ an initialized display
+ // for EGL_VERSION, while EGL 1.5 is _required_ to return the EGL version.
+ const char *ver = eglQueryString(EGL_NO_DISPLAY, EGL_VERSION);
+ // Of course we have to go through the excruciating pain of parsing a
+ // version string, since EGL provides no other way without a display. In
+ // theory version!=NULL is already proof enough that it's 1.5, but be
+ // extra defensive, since this should have been true for EGL_EXTENSIONS as
+ // well, but then they added an extension that modified standard behavior.
+ int ma = 0, mi = 0;
+ return ver && sscanf(ver, "%d.%d", &ma, &mi) == 2 && (ma > 1 || mi >= 5);
+}
+
// This is similar to eglGetPlatformDisplay(platform, native_display, NULL),
// except that it 1. may use eglGetPlatformDisplayEXT, 2. checks for the
// platform client extension platform_ext_name, and 3. does not support passing
@@ -310,16 +324,7 @@ EGLDisplay mpegl_get_display(EGLenum platform, const char *platform_ext_name,
return EGL_NO_DISPLAY;
// Before we go through the EGL 1.4 BS, try if we can use native EGL 1.5
- // It appears that EGL 1.4 is specified to _require_ an initialized display
- // for EGL_VERSION, while EGL 1.5 is _required_ to return the EGL version.
- const char *ver = eglQueryString(EGL_NO_DISPLAY, EGL_VERSION);
- // Of course we have to go through the excruciating pain of parsing a
- // version string, since EGL provides no other way without a display. In
- // theory version!=NULL is already proof enough that it's 1.5, but be
- // extra defensive, since this should have been true for EGL_EXTENSIONS as
- // well, but then they added an extension that modified standard behavior.
- int ma = 0, mi = 0;
- if (ver && sscanf(ver, "%d.%d", &ma, &mi) == 2 && (ma > 1 || mi >= 5)) {
+ if (is_egl15()) {
// This is EGL 1.5. It must support querying standard functions through
// eglGetProcAddress(). Note that on EGL 1.4, even if the function is
// unknown, it could return non-NULL anyway (because EGL is crazy).
@@ -331,8 +336,7 @@ EGLDisplay mpegl_get_display(EGLenum platform, const char *platform_ext_name,
return GetPlatformDisplay(platform, native_display, NULL);
}
- // (It should be impossible to be missing, but uh.)
- if (!gl_check_extension(exts, "EGL_EXT_client_extensions"))
+ if (!gl_check_extension(exts, "EGL_EXT_platform_base"))
return EGL_NO_DISPLAY;
EGLDisplay (EGLAPIENTRYP GetPlatformDisplayEXT)(EGLenum, void*, const EGLint*)
@@ -344,3 +348,34 @@ EGLDisplay mpegl_get_display(EGLenum platform, const char *platform_ext_name,
return EGL_NO_DISPLAY;
}
+
+// The same mess but with eglCreatePlatformWindowSurface(EXT)
+// again no support for an attribute list because the type differs
+// Returns EGL_NO_SURFACE on failure.
+EGLSurface mpegl_create_window_surface(EGLDisplay dpy, EGLConfig config,
+ void *native_window)
+{
+ // Use the EGL 1.5 function if possible
+ if (is_egl15()) {
+ EGLSurface (EGLAPIENTRYP CreatePlatformWindowSurface)
+ (EGLDisplay, EGLConfig, void *, const EGLAttrib *) =
+ (void *)eglGetProcAddress("eglCreatePlatformWindowSurface");
+ // (It should be impossible to be NULL, but uh.)
+ if (CreatePlatformWindowSurface)
+ return CreatePlatformWindowSurface(dpy, config, native_window, NULL);
+ }
+
+ // Check the extension that provides the *EXT function
+ const char *exts = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
+ if (!gl_check_extension(exts, "EGL_EXT_platform_base"))
+ return EGL_NO_SURFACE;
+
+ EGLSurface (EGLAPIENTRYP CreatePlatformWindowSurfaceEXT)
+ (EGLDisplay, EGLConfig, void *, const EGLint *) =
+ (void *)eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT");
+ // (It should be impossible to be NULL, but uh.)
+ if (CreatePlatformWindowSurfaceEXT)
+ return CreatePlatformWindowSurfaceEXT(dpy, config, native_window, NULL);
+
+ return EGL_NO_SURFACE;
+}
diff --git a/video/out/opengl/egl_helpers.h b/video/out/opengl/egl_helpers.h
index bbd274e613..32ec5d12e4 100644
--- a/video/out/opengl/egl_helpers.h
+++ b/video/out/opengl/egl_helpers.h
@@ -32,4 +32,7 @@ void mpegl_load_functions(struct GL *gl, struct mp_log *log);
EGLDisplay mpegl_get_display(EGLenum platform, const char *platform_ext_name,
void *native_display);
+EGLSurface mpegl_create_window_surface(EGLDisplay dpy, EGLConfig config,
+ void *native_window);
+
#endif