summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libmpv/opengl_cb.h10
-rw-r--r--video/out/opengl/x11egl.c18
-rw-r--r--wscript6
3 files changed, 33 insertions, 1 deletions
diff --git a/libmpv/opengl_cb.h b/libmpv/opengl_cb.h
index bd694b61d4..112f254a59 100644
--- a/libmpv/opengl_cb.h
+++ b/libmpv/opengl_cb.h
@@ -126,6 +126,16 @@ extern "C" {
* up until mpv_opengl_cb_uninit_gl() is called. If the name is not anything
* you know/expected, return NULL from the function.
*
+ * Windowing system interop on Linux
+ * ---------------------------------
+ *
+ * The new VAAPI OpenGL interop requires an EGL context. EGL provides no way
+ * to query the X11 Display associated to a specific EGL context, so this API
+ * is used to pass it through.
+ *
+ * glMPGetNativeDisplay("x11") should return a X11 "Display*", which then will
+ * be used to create the hardware decoder state. (On GLX, this is not needed.)
+ *
* Windowing system interop on MS win32
* ------------------------------------
*
diff --git a/video/out/opengl/x11egl.c b/video/out/opengl/x11egl.c
index 53cd5ae677..87e0e89fff 100644
--- a/video/out/opengl/x11egl.c
+++ b/video/out/opengl/x11egl.c
@@ -20,6 +20,8 @@
* version 2.1 of the License, or (at your option) any later version.
*/
+#include <assert.h>
+
#include <X11/Xlib.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
@@ -29,11 +31,21 @@
#include "common.h"
struct priv {
+ Display *x_display;
EGLDisplay egl_display;
EGLContext egl_context;
EGLSurface egl_surface;
};
+static _Thread_local struct priv *current_context;
+
+static void * GLAPIENTRY get_native_display(const char *name)
+{
+ if (current_context && strcmp(name, "x11") == 0)
+ return current_context->x_display;
+ return NULL;
+}
+
static EGLConfig select_fb_config_egl(struct MPGLContext *ctx, bool es)
{
struct priv *p = ctx->priv;
@@ -99,6 +111,8 @@ static bool config_window_x11_egl(struct MPGLContext *ctx, int flags)
struct vo *vo = ctx->vo;
bool es = flags & VOFLAG_GLES;
+ p->x_display = vo->x11->display;
+
if (!eglBindAPI(es ? EGL_OPENGL_ES_API : EGL_OPENGL_API)) {
MP_FATAL(vo, "Could not bind API (%s).\n", es ? "GLES" : "GL");
return false;
@@ -138,7 +152,10 @@ static bool config_window_x11_egl(struct MPGLContext *ctx, int flags)
void *(*gpa)(const GLubyte*) = (void *(*)(const GLubyte*))eglGetProcAddress;
mpgl_load_functions(ctx->gl, gpa, egl_exts, vo->log);
+ ctx->gl->MPGetNativeDisplay = get_native_display;
+ assert(!current_context);
+ current_context = p;
return true;
}
@@ -171,6 +188,7 @@ static void mpegl_uninit(MPGLContext *ctx)
eglDestroyContext(p->egl_display, p->egl_context);
}
p->egl_context = EGL_NO_CONTEXT;
+ current_context = NULL;
vo_x11_uninit(ctx->vo);
}
diff --git a/wscript b/wscript
index f23cf43500..22cc4693d1 100644
--- a/wscript
+++ b/wscript
@@ -173,6 +173,10 @@ main_dependencies = [
'func': check_true,
'deps_any': ['stdatomic', 'atomic-builtins', 'sync-builtins'],
}, {
+ 'name': 'c11-tls',
+ 'desc': 'C11 TLS support',
+ 'func': check_statement('stddef.h', 'static _Thread_local int x = 0'),
+ }, {
'name': 'librt',
'desc': 'linking with -lrt',
'deps': [ 'pthreads' ],
@@ -605,7 +609,7 @@ video_output_features = [
} , {
'name': '--egl-x11',
'desc': 'OpenGL X11 EGL Backend',
- 'deps': [ 'x11' ],
+ 'deps': [ 'x11', 'c11-tls' ],
'groups': [ 'gl' ],
'func': check_pkg_config('egl', 'gl'),
} , {