summaryrefslogtreecommitdiffstats
path: root/video/out/opengl/context_glx.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/opengl/context_glx.c')
-rw-r--r--video/out/opengl/context_glx.c161
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,