diff options
Diffstat (limited to 'video/out/opengl/context_glx.c')
-rw-r--r-- | video/out/opengl/context_glx.c | 161 |
1 files changed, 61 insertions, 100 deletions
diff --git a/video/out/opengl/context_glx.c b/video/out/opengl/context_glx.c index 4d9d993121..14f84d9dd7 100644 --- a/video/out/opengl/context_glx.c +++ b/video/out/opengl/context_glx.c @@ -25,7 +25,7 @@ #define GLX_CONTEXT_FLAGS_ARB 0x2094 #define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 #ifndef __APPLE__ -// These are respectively 0x00000001 and 0x00000002 on OSX +// These are respectively 0x00000001 and 0x00000002 on macOS #define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001 #define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 #endif @@ -38,9 +38,9 @@ #endif #include "osdep/timer.h" +#include "video/out/present_sync.h" #include "video/out/x11_common.h" #include "context.h" -#include "oml_sync.h" #include "utils.h" struct priv { @@ -48,9 +48,6 @@ struct priv { XVisualInfo *vinfo; GLXContext context; GLXFBConfig fbc; - - Bool (*XGetSyncValues)(Display*, GLXDrawable, int64_t*, int64_t*, int64_t*); - struct oml_sync sync; }; static void glx_uninit(struct ra_ctx *ctx) @@ -69,65 +66,28 @@ static void glx_uninit(struct ra_ctx *ctx) vo_x11_uninit(ctx->vo); } -static bool create_context_x11_old(struct ra_ctx *ctx, GL *gl) -{ - struct priv *p = ctx->priv; - Display *display = ctx->vo->x11->display; - struct vo *vo = ctx->vo; - - if (p->context) - return true; - - if (!p->vinfo) { - MP_FATAL(vo, "Can't create a legacy GLX context without X visual\n"); - return false; - } - - GLXContext new_context = glXCreateContext(display, p->vinfo, NULL, True); - if (!new_context) { - MP_FATAL(vo, "Could not create GLX context!\n"); - return false; - } - - if (!glXMakeCurrent(display, ctx->vo->x11->window, new_context)) { - MP_FATAL(vo, "Could not set GLX context!\n"); - glXDestroyContext(display, new_context); - return false; - } - - const char *glxstr = glXQueryExtensionsString(display, ctx->vo->x11->screen); - - mpgl_load_functions(gl, (void *)glXGetProcAddressARB, glxstr, vo->log); - - p->context = new_context; - - return true; -} - typedef GLXContext (*glXCreateContextAttribsARBProc) (Display*, GLXFBConfig, GLXContext, Bool, const int*); -static bool create_context_x11_gl3(struct ra_ctx *ctx, GL *gl, int gl_version, - bool es) +static bool create_context_x11(struct ra_ctx *ctx, GL *gl, bool es) { struct priv *p = ctx->priv; struct vo *vo = ctx->vo; - if (p->context) - return true; - - if (!ra_gl_ctx_test_version(ctx, gl_version, es)) - return false; - glXCreateContextAttribsARBProc glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc) glXGetProcAddressARB((const GLubyte *)"glXCreateContextAttribsARB"); const char *glxstr = glXQueryExtensionsString(vo->x11->display, vo->x11->screen); - bool have_ctx_ext = glxstr && !!strstr(glxstr, "GLX_ARB_create_context"); + if (!glxstr) { + MP_ERR(ctx, "GLX did not advertise any extensions\n"); + return false; + } - if (!(have_ctx_ext && glXCreateContextAttribsARB)) { + if (!gl_check_extension(glxstr, "GLX_ARB_create_context_profile") || + !glXCreateContextAttribsARB) { + MP_ERR(ctx, "GLX does not support GLX_ARB_create_context_profile\n"); return false; } @@ -136,22 +96,48 @@ static bool create_context_x11_gl3(struct ra_ctx *ctx, GL *gl, int gl_version, if (es) { profile_mask = GLX_CONTEXT_ES2_PROFILE_BIT_EXT; - if (!(glxstr && strstr(glxstr, "GLX_EXT_create_context_es2_profile"))) + if (!gl_check_extension(glxstr, "GLX_EXT_create_context_es2_profile")) return false; } int context_attribs[] = { - GLX_CONTEXT_MAJOR_VERSION_ARB, MPGL_VER_GET_MAJOR(gl_version), - GLX_CONTEXT_MINOR_VERSION_ARB, MPGL_VER_GET_MINOR(gl_version), + GLX_CONTEXT_MAJOR_VERSION_ARB, 0, + GLX_CONTEXT_MINOR_VERSION_ARB, 0, GLX_CONTEXT_PROFILE_MASK_ARB, profile_mask, GLX_CONTEXT_FLAGS_ARB, ctx_flags, None }; - vo_x11_silence_xlib(1); - GLXContext context = glXCreateContextAttribsARB(vo->x11->display, - p->fbc, 0, True, - context_attribs); - vo_x11_silence_xlib(-1); + + GLXContext context; + + if (!es) { + for (int n = 0; mpgl_min_required_gl_versions[n]; n++) { + int version = mpgl_min_required_gl_versions[n]; + MP_VERBOSE(ctx, "Creating OpenGL %d.%d context...\n", + MPGL_VER_P(version)); + + context_attribs[1] = MPGL_VER_GET_MAJOR(version); + context_attribs[3] = MPGL_VER_GET_MINOR(version); + + vo_x11_silence_xlib(1); + context = glXCreateContextAttribsARB(vo->x11->display, + p->fbc, 0, True, + context_attribs); + vo_x11_silence_xlib(-1); + + if (context) + break; + } + } else { + context_attribs[1] = 2; + + vo_x11_silence_xlib(1); + context = glXCreateContextAttribsARB(vo->x11->display, + p->fbc, 0, True, + context_attribs); + vo_x11_silence_xlib(-1); + } + if (!context) return false; @@ -165,14 +151,6 @@ static bool create_context_x11_gl3(struct ra_ctx *ctx, GL *gl, int gl_version, p->context = context; mpgl_load_functions(gl, (void *)glXGetProcAddressARB, glxstr, vo->log); - - if (gl_check_extension(glxstr, "GLX_OML_sync_control")) { - p->XGetSyncValues = - (void *)glXGetProcAddressARB((const GLubyte *)"glXGetSyncValuesOML"); - } - if (p->XGetSyncValues) - MP_VERBOSE(vo, "Using GLX_OML_sync_control.\n"); - return true; } @@ -220,34 +198,23 @@ static void set_glx_attrib(int *attribs, int name, int value) } } -static void update_vsync_oml(struct ra_ctx *ctx) +static bool glx_check_visible(struct ra_ctx *ctx) { - struct priv *p = ctx->priv; - - assert(p->XGetSyncValues); - - int64_t ust, msc, sbc; - if (!p->XGetSyncValues(ctx->vo->x11->display, ctx->vo->x11->window, - &ust, &msc, &sbc)) - ust = msc = sbc = -1; - - oml_sync_swap(&p->sync, ust, msc, sbc); + return vo_x11_check_visible(ctx->vo); } static void glx_swap_buffers(struct ra_ctx *ctx) { - struct priv *p = ctx->priv; - glXSwapBuffers(ctx->vo->x11->display, ctx->vo->x11->window); - - if (p->XGetSyncValues) - update_vsync_oml(ctx); + if (ctx->vo->x11->use_present) + present_sync_swap(ctx->vo->x11->present); } static void glx_get_vsync(struct ra_ctx *ctx, struct vo_vsync_info *info) { - struct priv *p = ctx->priv; - oml_sync_get_info(&p->sync, info); + struct vo_x11_state *x11 = ctx->vo->x11; + if (ctx->vo->x11->use_present) + present_sync_get_info(x11->present, info); } static bool glx_init(struct ra_ctx *ctx) @@ -312,26 +279,19 @@ static bool glx_init(struct ra_ctx *ctx) goto uninit; bool success = false; - for (int n = 0; mpgl_preferred_gl_versions[n]; n++) { - int version = mpgl_preferred_gl_versions[n]; - MP_VERBOSE(ctx, "Creating OpenGL %d.%d context...\n", - MPGL_VER_P(version)); - if (version >= 300) { - success = create_context_x11_gl3(ctx, gl, version, false); - } else { - success = create_context_x11_old(ctx, gl); - } - if (success) - break; - } - if (!success) // try again for GLES - success = create_context_x11_gl3(ctx, gl, 200, true); + enum gles_mode mode = ra_gl_ctx_get_glesmode(ctx); + + if (mode == GLES_NO || mode == GLES_AUTO) + success = create_context_x11(ctx, gl, false); + if (!success && (mode == GLES_YES || mode == GLES_AUTO)) + success = create_context_x11(ctx, gl, true); if (success && !glXIsDirect(vo->x11->display, p->context)) gl->mpgl_caps |= MPGL_CAP_SW; if (!success) goto uninit; struct ra_gl_ctx_params params = { + .check_visible = glx_check_visible, .swap_buffers = glx_swap_buffers, .get_vsync = glx_get_vsync, }; @@ -374,14 +334,15 @@ static void glx_wakeup(struct ra_ctx *ctx) vo_x11_wakeup(ctx->vo); } -static void glx_wait_events(struct ra_ctx *ctx, int64_t until_time_us) +static void glx_wait_events(struct ra_ctx *ctx, int64_t until_time_ns) { - vo_x11_wait_events(ctx->vo, until_time_us); + vo_x11_wait_events(ctx->vo, until_time_ns); } const struct ra_ctx_fns ra_ctx_glx = { .type = "opengl", .name = "x11", + .description = "X11/GLX", .reconfig = glx_reconfig, .control = glx_control, .wakeup = glx_wakeup, |