summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2017-05-11 17:41:54 +0200
committerwm4 <wm4@nowhere>2017-05-11 17:47:33 +0200
commit2b616c0682a894152b06ef7249b32ef17037b3e5 (patch)
treed2714deb7052e11b32437d66c348fa2b2ac6562e
parentf2961425e770defe7cedc14ee2d4c9d4a53ab203 (diff)
downloadmpv-2b616c0682a894152b06ef7249b32ef17037b3e5.tar.bz2
mpv-2b616c0682a894152b06ef7249b32ef17037b3e5.tar.xz
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.
-rw-r--r--libmpv/opengl_cb.h2
-rw-r--r--video/out/opengl/common.c10
-rw-r--r--video/out/opengl/common.h8
-rw-r--r--video/out/opengl/context.c35
-rw-r--r--video/out/opengl/hwdec_dxva2gldx.c6
-rw-r--r--video/out/opengl/hwdec_rpi.c3
-rw-r--r--video/out/opengl/hwdec_vaegl.c8
-rw-r--r--wscript8
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
@@ -177,14 +177,6 @@ main_dependencies = [
'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',
'deps': [ 'pthreads' ],