From 2b616c0682a894152b06ef7249b32ef17037b3e5 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 11 May 2017 17:41:54 +0200 Subject: 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. --- libmpv/opengl_cb.h | 2 +- video/out/opengl/common.c | 10 ++++++++++ video/out/opengl/common.h | 8 ++++++++ video/out/opengl/context.c | 35 +++++++---------------------------- video/out/opengl/hwdec_dxva2gldx.c | 6 +++--- video/out/opengl/hwdec_rpi.c | 3 +-- video/out/opengl/hwdec_vaegl.c | 8 +++----- wscript | 8 -------- 8 files changed, 33 insertions(+), 47 deletions(-) diff --git a/libmpv/opengl_cb.h b/libmpv/opengl_cb.h index 2c6219a462..fb8b928889 100644 --- a/libmpv/opengl_cb.h +++ b/libmpv/opengl_cb.h @@ -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 diff --git a/video/out/opengl/common.c b/video/out/opengl/common.c index 271214954a..fc0ec547db 100644 --- a/video/out/opengl/common.c +++ b/video/out/opengl/common.c @@ -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; +} diff --git a/video/out/opengl/common.h b/video/out/opengl/common.h index 3eb2a8ecf8..351624051f 100644 --- a/video/out/opengl/common.h +++ b/video/out/opengl/common.h @@ -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 *); diff --git a/video/out/opengl/context.c b/video/out/opengl/context.c index 117d7f830e..72311e11fa 100644 --- a/video/out/opengl/context.c +++ b/video/out/opengl/context.c @@ -126,34 +126,13 @@ 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) -{ - if (current_context && current_context->native_display_type && - name && strcmp(current_context->native_display_type, name) == 0) - return current_context->native_display; - return 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) +static void *get_native_display(void *pctx, const char *name) { + MPGLContext *ctx = pctx; + if (!ctx->native_display_type || !name) + return NULL; + return strcmp(ctx->native_display_type, name) == 0 ? ctx->native_display : NULL; } -#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); diff --git a/video/out/opengl/hwdec_dxva2gldx.c b/video/out/opengl/hwdec_dxva2gldx.c index c0bca283bb..eb44f2b38b 100644 --- a/video/out/opengl/hwdec_dxva2gldx.c +++ b/video/out/opengl/hwdec_dxva2gldx.c @@ -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); diff --git a/video/out/opengl/hwdec_rpi.c b/video/out/opengl/hwdec_rpi.c index 90a350eac1..8611217c79 100644 --- a/video/out/opengl/hwdec_rpi.c +++ b/video/out/opengl/hwdec_rpi.c @@ -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; diff --git a/video/out/opengl/hwdec_vaegl.c b/video/out/opengl/hwdec_vaegl.c index dc2645bf05..548d3678f3 100644 --- a/video/out/opengl/hwdec_vaegl.c +++ b/video/out/opengl/hwdec_vaegl.c @@ -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); diff --git a/wscript b/wscript index e051555545..75925c8098 100644 --- a/wscript +++ b/wscript @@ -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', -- cgit v1.2.3