summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--video/out/gl_common.c77
-rw-r--r--video/out/gl_common.h6
-rw-r--r--video/out/gl_x11.c13
-rw-r--r--video/out/vo.c8
-rw-r--r--video/out/vo_opengl.c7
-rw-r--r--video/out/vo_opengl_old.c7
6 files changed, 55 insertions, 63 deletions
diff --git a/video/out/gl_common.c b/video/out/gl_common.c
index a8d08d1c4a..73b29c4495 100644
--- a/video/out/gl_common.c
+++ b/video/out/gl_common.c
@@ -98,27 +98,17 @@ struct feature {
static const struct feature features[] = {
{MPGL_CAP_GL_LEGACY, "Legacy OpenGL"},
- {MPGL_CAP_GL21, "OpenGL 2.1+"},
+ {MPGL_CAP_GL21, "OpenGL 2.1+ (or subset)"},
{MPGL_CAP_FB, "Framebuffers"},
{MPGL_CAP_VAO, "VAOs"},
{MPGL_CAP_SRGB_TEX, "sRGB textures"},
{MPGL_CAP_SRGB_FB, "sRGB framebuffers"},
{MPGL_CAP_FLOAT_TEX, "Float textures"},
{MPGL_CAP_TEX_RG, "RG textures"},
- {MPGL_CAP_NO_SW, "NO_SW"},
+ {MPGL_CAP_SW, "suspected software renderer"},
{0},
};
-static void list_features(int set, struct mp_log *log, int msgl, bool invert)
-{
- char b[1024] = {0};
- for (const struct feature *f = &features[0]; f->id; f++) {
- if (invert == !(f->id & set))
- mp_snprintf_cat(b, sizeof(b), " [%s]", f->name);
- }
- mp_msg(log, msgl, "%s\n", b);
-}
-
// This guesses if the current GL context is a suspected software renderer.
static bool is_software_gl(GL *gl)
{
@@ -649,11 +639,16 @@ void mpgl_load_functions2(GL *gl, void *(*get_fn)(void *ctx, const char *n),
gl->glsl_version = 150;
}
- if (!is_software_gl(gl))
- gl->mpgl_caps |= MPGL_CAP_NO_SW;
+ if (is_software_gl(gl))
+ gl->mpgl_caps |= MPGL_CAP_SW;
- mp_verbose(log, "Detected OpenGL features:");
- list_features(gl->mpgl_caps, log, MSGL_V, false);
+ if (gl->mpgl_caps) {
+ mp_verbose(log, "Detected OpenGL features:\n");
+ for (const struct feature *f = &features[0]; f->id; f++) {
+ if ((f->id & gl->mpgl_caps))
+ mp_verbose(log, " - %s\n", f->name);
+ }
+ }
// Provided for simpler handling if no framebuffer support is available.
if (!gl->BindFramebuffer)
@@ -906,13 +901,14 @@ static MPGLContext *init_backend(struct vo *vo, MPGLSetBackendFn set_backend,
.gl = talloc_zero(ctx, GL),
.vo = vo,
};
- vo->probing = probing;
+ bool old_probing = vo->probing;
+ vo->probing = probing; // hack; kill it once backends are separate
set_backend(ctx);
if (!ctx->vo_init(vo)) {
talloc_free(ctx);
ctx = NULL;
}
- vo->probing = false;
+ vo->probing = old_probing;
return ctx;
}
@@ -933,32 +929,37 @@ static MPGLContext *mpgl_create(struct vo *vo, const char *backend_name)
}
MPGLContext *mpgl_init(struct vo *vo, const char *backend_name,
- int gl_caps, int vo_flags)
+ int gl_flavor, int vo_flags)
{
MPGLContext *ctx = mpgl_create(vo, backend_name);
if (!ctx)
- return NULL;
+ goto cleanup;
+
+ // A bit strange; but <300 triggers legacy context creation in mpv code.
+ ctx->requested_gl_version = gl_flavor < 210 ? 210 : 300;
+
+ if (!ctx->config_window(ctx, vo_flags | VOFLAG_HIDDEN))
+ goto cleanup;
+
+ if (gl_flavor >= 210 && !(ctx->gl->mpgl_caps & MPGL_CAP_GL21)) {
+ MP_WARN(ctx->vo, "At least OpenGL 2.1 required.\n");
+ if (!vo->probing && (ctx->gl->mpgl_caps & MPGL_CAP_GL_LEGACY))
+ MP_WARN(ctx->vo, "Try with: --vo=opengl-old\n");
+ goto cleanup;
+ } else if (gl_flavor < 210 && !(ctx->gl->mpgl_caps & MPGL_CAP_GL_LEGACY)) {
+ MP_WARN(ctx->vo, "OpenGL context creation failed!\n");
+ goto cleanup;
+ }
- ctx->requested_gl_version = (gl_caps & MPGL_CAP_GL_LEGACY)
- ? MPGL_VER(2, 1) : MPGL_VER(3, 0);
-
- if (ctx->config_window(ctx, vo_flags | VOFLAG_HIDDEN)) {
- int missing = (ctx->gl->mpgl_caps & gl_caps) ^ gl_caps;
- if (!missing)
- return ctx;
-
- MP_WARN(ctx->vo, "Missing OpenGL features:");
- list_features(missing, ctx->vo->log, MSGL_WARN, false);
- if (missing == MPGL_CAP_NO_SW) {
- MP_WARN(ctx->vo, "Rejecting suspected software OpenGL renderer.\n");
- } else if ((missing & MPGL_CAP_GL21) &&
- (ctx->gl->mpgl_caps & MPGL_CAP_GL_LEGACY))
- {
- MP_WARN(ctx->vo, "OpenGL version too old. Try: --vo=opengl-old\n");
- }
+ if (ctx->gl->mpgl_caps & MPGL_CAP_SW) {
+ MP_WARN(ctx->vo, "Suspected software renderer or indirect context.\n");
+ if (vo->probing)
+ goto cleanup;
}
- MP_ERR(ctx->vo, "OpenGL context creation failed!\n");
+ return ctx;
+
+cleanup:
mpgl_uninit(ctx);
return NULL;
}
diff --git a/video/out/gl_common.h b/video/out/gl_common.h
index e391663b93..f70614972a 100644
--- a/video/out/gl_common.h
+++ b/video/out/gl_common.h
@@ -79,7 +79,7 @@ enum {
MPGL_CAP_TEX_RG = (1 << 10), // GL_ARB_texture_rg / GL 3.x
MPGL_CAP_VDPAU = (1 << 11), // GL_NV_vdpau_interop
MPGL_CAP_APPLE_RGB_422 = (1 << 12), // GL_APPLE_rgb_422
- MPGL_CAP_NO_SW = (1 << 30), // used to block sw. renderers
+ MPGL_CAP_SW = (1 << 30), // indirect or sw renderer
};
// E.g. 310 means 3.1
@@ -136,11 +136,11 @@ bool mpgl_is_thread_safe(MPGLContext *ctx);
// Create a VO window and create a GL context on it.
// (Calls config_window_gl3 or config_window+setGlWindow.)
-// gl_caps: bitfield of MPGL_CAP_* (required GL version and feature set)
+// gl_flavor: 110 for legacy GL, 210 for GL 2.1 or 3.x core
// flags: passed to the backend's create window function
// Returns success.
MPGLContext *mpgl_init(struct vo *vo, const char *backend_name,
- int gl_caps, int vo_flags);
+ int gl_flavor, int vo_flags);
void mpgl_uninit(MPGLContext *ctx);
// flags: passed to the backend function
diff --git a/video/out/gl_x11.c b/video/out/gl_x11.c
index 5fe43e54f7..67f87716bd 100644
--- a/video/out/gl_x11.c
+++ b/video/out/gl_x11.c
@@ -68,9 +68,6 @@ static bool create_context_x11_old(struct MPGLContext *ctx)
glx_ctx->context = new_context;
- if (!glXIsDirect(vo->x11->display, new_context))
- ctx->gl->mpgl_caps &= ~MPGL_CAP_NO_SW;
-
return true;
}
@@ -124,9 +121,6 @@ static bool create_context_x11_gl3(struct MPGLContext *ctx, bool debug)
mpgl_load_functions(ctx->gl, (void *)glXGetProcAddress, glxstr, vo->log);
- if (!glXIsDirect(vo->x11->display, context))
- ctx->gl->mpgl_caps &= ~MPGL_CAP_NO_SW;
-
return true;
}
@@ -260,14 +254,11 @@ static bool config_window_x11(struct MPGLContext *ctx, int flags)
success = create_context_x11_gl3(ctx, flags & VOFLAG_GL_DEBUG);
if (!success)
success = create_context_x11_old(ctx);
+ if (success && !glXIsDirect(vo->x11->display, glx_ctx->context))
+ ctx->gl->mpgl_caps |= MPGL_CAP_SW;
return success;
}
-
-/**
- * \brief free the VisualInfo and GLXContext of an OpenGL context.
- * \ingroup glcontext
- */
static void releaseGlContext_x11(MPGLContext *ctx)
{
struct glx_context *glx_ctx = ctx->priv;
diff --git a/video/out/vo.c b/video/out/vo.c
index f6dda92532..c2ec6c5813 100644
--- a/video/out/vo.c
+++ b/video/out/vo.c
@@ -202,7 +202,7 @@ static void dealloc_vo(struct vo *vo)
talloc_free(vo);
}
-static struct vo *vo_create(struct mpv_global *global,
+static struct vo *vo_create(bool probing, struct mpv_global *global,
struct input_ctx *input_ctx, struct osd_state *osd,
struct encode_lavc_context *encode_lavc_ctx,
char *name, char **args)
@@ -225,6 +225,7 @@ static struct vo *vo_create(struct mpv_global *global,
.osd = osd,
.event_fd = -1,
.monitor_par = 1,
+ .probing = probing,
.in = talloc(vo, struct vo_internal),
};
talloc_steal(vo, log);
@@ -271,7 +272,8 @@ struct vo *init_best_video_out(struct mpv_global *global,
// Something like "-vo name," allows fallback to autoprobing.
if (strlen(vo_list[n].name) == 0)
goto autoprobe;
- struct vo *vo = vo_create(global, input_ctx, osd, encode_lavc_ctx,
+ bool p = !!vo_list[n + 1].name;
+ struct vo *vo = vo_create(p, global, input_ctx, osd, encode_lavc_ctx,
vo_list[n].name, vo_list[n].attribs);
if (vo)
return vo;
@@ -281,7 +283,7 @@ struct vo *init_best_video_out(struct mpv_global *global,
autoprobe:
// now try the rest...
for (int i = 0; video_out_drivers[i]; i++) {
- struct vo *vo = vo_create(global, input_ctx, osd, encode_lavc_ctx,
+ struct vo *vo = vo_create(true, global, input_ctx, osd, encode_lavc_ctx,
(char *)video_out_drivers[i]->name, NULL);
if (vo)
return vo;
diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c
index ab7d2380c7..bc98f513a7 100644
--- a/video/out/vo_opengl.c
+++ b/video/out/vo_opengl.c
@@ -408,11 +408,10 @@ static int preinit(struct vo *vo)
if (p->use_gl_debug)
vo_flags |= VOFLAG_GL_DEBUG;
- int mpgl_caps = MPGL_CAP_GL21;
- if (!p->allow_sw)
- mpgl_caps |= MPGL_CAP_NO_SW;
+ if (p->allow_sw)
+ vo->probing = false;
- p->glctx = mpgl_init(vo, p->backend, mpgl_caps, vo_flags);
+ p->glctx = mpgl_init(vo, p->backend, 210, vo_flags);
if (!p->glctx)
goto err_out;
p->gl = p->glctx->gl;
diff --git a/video/out/vo_opengl_old.c b/video/out/vo_opengl_old.c
index a3a8b69c0a..bf117fdbd9 100644
--- a/video/out/vo_opengl_old.c
+++ b/video/out/vo_opengl_old.c
@@ -2168,11 +2168,10 @@ static int preinit(struct vo *vo)
if (p->stereo_mode == GL_3D_QUADBUFFER)
vo_flags |= VOFLAG_STEREO;
- int mpgl_caps = MPGL_CAP_GL_LEGACY;
- if (!p->allow_sw)
- mpgl_caps |= MPGL_CAP_NO_SW;
+ if (p->allow_sw)
+ vo->probing = false;
- p->glctx = mpgl_init(vo, p->backend_arg, mpgl_caps, vo_flags);
+ p->glctx = mpgl_init(vo, p->backend_arg, MPGL_CAP_GL_LEGACY, vo_flags);
if (!p->glctx)
goto err_out;
p->gl = p->glctx->gl;