summaryrefslogtreecommitdiffstats
path: root/video/out
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-12-19 18:37:16 +0100
committerwm4 <wm4@nowhere>2014-12-19 18:54:39 +0100
commit88982f2855590cafb1fdce916384751ae728ba0c (patch)
treefbc954496ac649aef5f253f33002010f9a30086f /video/out
parentbebc323c6d6aab298f920cd462e7c0fe375925db (diff)
downloadmpv-88982f2855590cafb1fdce916384751ae728ba0c.tar.bz2
mpv-88982f2855590cafb1fdce916384751ae728ba0c.tar.xz
vo_opengl: better probe handling
Involve detection of software renderers in the probing properly. Other VOs could handle probing also more gracefully, and e.g. produce less noise if an API is unavailable. (Although other than the OpenGL VOs, only vo_wayland will.) Now the "sw" suboption for vo_opengl[_old] is strictly speaking not needed anymore. Doing "--vo=opengl" disables the probing logic, and will always force it, if possible. Includes some simplifications as well.
Diffstat (limited to 'video/out')
-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;