mirror of
https://github.com/mpv-player/mpv
synced 2025-03-06 06:08:23 +00:00
vo_opengl: add mechanism to retrieve Display from EGL context
The VAAPI EGL interop code will need access to the X11 Display. While GLX could return it from the current GLX context, EGL has no such mechanism. (At least no standard one supported by all implementations.) So mpv makes up such a mechanism. For internal purposes, this is very rather awkward solution, but it's needed for libmpv anyway.
This commit is contained in:
parent
d47dff3faa
commit
0e9cfa6b64
@ -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
|
||||
* ------------------------------------
|
||||
*
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
6
wscript
6
wscript
@ -172,6 +172,10 @@ main_dependencies = [
|
||||
'desc': 'compiler support for usable thread synchronization built-ins',
|
||||
'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',
|
||||
@ -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'),
|
||||
} , {
|
||||
|
Loading…
Reference in New Issue
Block a user