vo_opengl: drop TLS usage

TLS is a headache. We should avoid it if we can.

The involved mechanism is unfortunately entangled with the unfortunate
libmpv API for returning pointers to host API objects. This has to be
kept until we change the API somehow.

Practically untested out of pure laziness. I'm sure I'll get a bunch of
reports if it's broken.
This commit is contained in:
wm4 2017-05-11 17:41:54 +02:00
parent f2961425e7
commit 2b616c0682
8 changed files with 33 additions and 47 deletions

View File

@ -176,7 +176,7 @@ extern "C" {
*
* The RPI uses no proper interop, but hardware overlays instead. To place the
* overlay correctly, you can communicate the window parameters as follows to
* libmpv. gl->MPGetNativeDisplay("MPV_RPI_WINDOW") return an array of type int
* libmpv. glMPGetNativeDisplay("MPV_RPI_WINDOW") returns an array of type int
* with the following 4 elements:
* 0: display number (default 0)
* 1: layer number of the GL layer - video will be placed in the layer

View File

@ -610,3 +610,13 @@ void mpgl_load_functions(GL *gl, void *(*getProcAddress)(const GLubyte *),
{
mpgl_load_functions2(gl, get_procaddr_wrapper, getProcAddress, ext2, log);
}
void *mpgl_get_native_display(struct GL *gl, const char *name)
{
void *res = NULL;
if (gl->get_native_display)
res = gl->get_native_display(gl->get_native_display_ctx, name);
if (!res && gl->MPGetNativeDisplay)
res = gl->MPGetNativeDisplay(name);
return res;
}

View File

@ -74,6 +74,9 @@ void mpgl_load_functions2(GL *gl, void *(*get_fn)(void *ctx, const char *n),
typedef void (GLAPIENTRY *MP_GLDEBUGPROC)(GLenum, GLenum, GLuint, GLenum,
GLsizei, const GLchar *,const void *);
// Return a named host API reference (e.g. "wl" -> wl_display).
void *mpgl_get_native_display(struct GL *gl, const char *name);
//function pointers loaded from the OpenGL library
struct GL {
int version; // MPGL_VER() mangled (e.g. 210 for 2.1)
@ -83,6 +86,11 @@ struct GL {
int mpgl_caps; // Bitfield of MPGL_CAP_* constants
bool debug_context; // use of e.g. GLX_CONTEXT_DEBUG_BIT_ARB
// Use mpgl_get_native_display() instead. Also, this is set to use the
// fields in MPGLContext by default (if set).
void *get_native_display_ctx;
void *(*get_native_display)(void *ctx, const char *name);
void (GLAPIENTRY *Viewport)(GLint, GLint, GLsizei, GLsizei);
void (GLAPIENTRY *Clear)(GLbitfield);
void (GLAPIENTRY *GenTextures)(GLsizei, GLuint *);

View File

@ -126,35 +126,14 @@ int mpgl_validate_backend_opt(struct mp_log *log, const struct m_option *opt,
return mpgl_find_backend(s) >= -1 ? 1 : M_OPT_INVALID;
}
#if HAVE_C11_TLS
#define MP_TLS _Thread_local
#elif HAVE_GCC_TLS
#define MP_TLS __thread
#endif
#ifdef MP_TLS
static MP_TLS MPGLContext *current_context;
static void * GLAPIENTRY get_native_display(const char *name)
static void *get_native_display(void *pctx, const char *name)
{
if (current_context && current_context->native_display_type &&
name && strcmp(current_context->native_display_type, name) == 0)
return current_context->native_display;
return NULL;
MPGLContext *ctx = pctx;
if (!ctx->native_display_type || !name)
return NULL;
return strcmp(ctx->native_display_type, name) == 0 ? ctx->native_display : NULL;
}
static void set_current_context(MPGLContext *context)
{
current_context = context;
if (context && !context->gl->MPGetNativeDisplay)
context->gl->MPGetNativeDisplay = get_native_display;
}
#else
static void set_current_context(MPGLContext *context)
{
}
#endif
static MPGLContext *init_backend(struct vo *vo, const struct mpgl_driver *driver,
bool probing, int vo_flags)
{
@ -195,7 +174,8 @@ static MPGLContext *init_backend(struct vo *vo, const struct mpgl_driver *driver
ctx->gl->debug_context = !!(vo_flags & VOFLAG_GL_DEBUG);
set_current_context(ctx);
ctx->gl->get_native_display_ctx = ctx;
ctx->gl->get_native_display = get_native_display;
return ctx;
@ -253,7 +233,6 @@ void mpgl_swap_buffers(struct MPGLContext *ctx)
void mpgl_uninit(MPGLContext *ctx)
{
set_current_context(NULL);
if (ctx)
ctx->driver->uninit(ctx);
talloc_free(ctx);

View File

@ -82,7 +82,7 @@ static void destroy(struct gl_hwdec *hw)
static int create(struct gl_hwdec *hw)
{
GL *gl = hw->gl;
if (!gl->MPGetNativeDisplay || !(gl->mpgl_caps & MPGL_CAP_DXINTEROP))
if (!(gl->mpgl_caps & MPGL_CAP_DXINTEROP))
return -1;
struct priv *p = talloc_zero(hw, struct priv);
@ -90,12 +90,12 @@ static int create(struct gl_hwdec *hw)
// AMD drivers won't open multiple dxinterop HANDLES on the same D3D device,
// so we request the one already in use by context_dxinterop
p->device_h = gl->MPGetNativeDisplay("dxinterop_device_HANDLE");
p->device_h = mpgl_get_native_display(gl, "dxinterop_device_HANDLE");
if (!p->device_h)
return -1;
// But we also still need the actual D3D device
p->device = gl->MPGetNativeDisplay("IDirect3DDevice9Ex");
p->device = mpgl_get_native_display(gl, "IDirect3DDevice9Ex");
if (!p->device)
return -1;
IDirect3DDevice9Ex_AddRef(p->device);

View File

@ -135,8 +135,7 @@ static void update_overlay(struct gl_hwdec *hw, bool check_window_only)
return;
int defs[4] = {0, 0, 0, 0};
int *z =
gl->MPGetNativeDisplay ? gl->MPGetNativeDisplay("MPV_RPI_WINDOW") : NULL;
int *z = mpgl_get_native_display(gl, "MPV_RPI_WINDOW");
if (!z)
z = defs;

View File

@ -56,7 +56,7 @@ typedef void *EGLImageKHR;
static VADisplay *create_x11_va_display(GL *gl)
{
Display *x11 = gl->MPGetNativeDisplay("x11");
Display *x11 = mpgl_get_native_display(gl, "x11");
return x11 ? vaGetDisplay(x11) : NULL;
}
#endif
@ -66,7 +66,7 @@ static VADisplay *create_x11_va_display(GL *gl)
static VADisplay *create_wayland_va_display(GL *gl)
{
struct wl_display *wl = gl->MPGetNativeDisplay("wl");
struct wl_display *wl = mpgl_get_native_display(gl, "wl");
return wl ? vaGetDisplayWl(wl) : NULL;
}
#endif
@ -76,7 +76,7 @@ static VADisplay *create_wayland_va_display(GL *gl)
static VADisplay *create_drm_va_display(GL *gl)
{
int drm_fd = (intptr_t)gl->MPGetNativeDisplay("drm");
int drm_fd = (intptr_t)mpgl_get_native_display(gl, "drm");
// Note: yes, drm_fd==0 could be valid - but it's rare and doesn't fit with
// our slightly crappy way of passing it through, so consider 0 not
// valid.
@ -103,8 +103,6 @@ static const struct va_create_native create_native_cbs[] = {
static VADisplay *create_native_va_display(GL *gl, struct mp_log *log)
{
if (!gl->MPGetNativeDisplay)
return NULL;
for (int n = 0; n < MP_ARRAY_SIZE(create_native_cbs); n++) {
const struct va_create_native *disp = &create_native_cbs[n];
mp_verbose(log, "Trying to open a %s VA display...\n", disp->name);

View File

@ -176,14 +176,6 @@ main_dependencies = [
'func': check_true,
'req': True,
'deps_any': ['stdatomic', 'gnuc'],
}, {
'name': 'c11-tls',
'desc': 'C11 TLS support',
'func': check_statement('stddef.h', 'static _Thread_local int x = 0'),
}, {
'name': 'gcc-tls',
'desc': 'GCC TLS support',
'func': check_statement('stddef.h', 'static __thread int x = 0'),
}, {
'name': 'librt',
'desc': 'linking with -lrt',