1
0
mirror of https://github.com/mpv-player/mpv synced 2025-01-21 23:23:19 +00:00

vo_opengl_cb: don't render OSD while VO is not created

Unlike other VOs, this rendered OSD even while no VO was created
(because the renderer lives as long as the API user wants). Change this,
and refactor the code so that the OSD object is accessible only while
the VO is created.

(There is a short time where the OSD can still be accessed even after VO
destruction - this is not a race condition, though it's inelegant and
unfortunately unavoidable.)
This commit is contained in:
wm4 2015-03-23 16:32:59 +01:00
parent 67bdad9a43
commit 167b75c50c
6 changed files with 26 additions and 17 deletions

View File

@ -1685,7 +1685,7 @@ static mpv_opengl_cb_context *opengl_cb_get_context(mpv_handle *ctx)
{
mpv_opengl_cb_context *cb = ctx->mpctx->gl_cb_ctx;
if (!cb) {
cb = mp_opengl_create(ctx->mpctx->global, ctx->mpctx->osd, ctx->clients);
cb = mp_opengl_create(ctx->mpctx->global, ctx->clients);
ctx->mpctx->gl_cb_ctx = cb;
}
return cb;

View File

@ -42,7 +42,6 @@ struct mpv_opengl_cb_context;
struct mpv_global;
struct osd_state;
struct mpv_opengl_cb_context *mp_opengl_create(struct mpv_global *g,
struct osd_state *osd,
struct mp_client_api *client_api);
void kill_video(struct mp_client_api *client_api);

View File

@ -506,11 +506,13 @@ static inline int fbosurface_wrap(int id)
static void recreate_osd(struct gl_video *p)
{
if (p->osd)
mpgl_osd_destroy(p->osd);
p->osd = NULL;
if (p->osd_state) {
p->osd = mpgl_osd_init(p->gl, p->log, p->osd_state);
mpgl_osd_set_options(p->osd, p->opts.pbo);
}
}
static void reinit_rendering(struct gl_video *p)
{
@ -1916,6 +1918,7 @@ void gl_video_render_frame(struct gl_video *p, int fbo, struct frame_timing *t)
gl->BindFramebuffer(GL_FRAMEBUFFER, fbo);
if (p->osd)
draw_osd(p);
gl->UseProgram(0);
@ -2389,7 +2392,15 @@ void gl_video_set_output_depth(struct gl_video *p, int r, int g, int b)
p->depth_g = g;
}
struct gl_video *gl_video_init(GL *gl, struct mp_log *log, struct osd_state *osd)
void gl_video_set_osd_source(struct gl_video *p, struct osd_state *osd)
{
mpgl_osd_destroy(p->osd);
p->osd = NULL;
p->osd_state = osd;
recreate_osd(p);
}
struct gl_video *gl_video_init(GL *gl, struct mp_log *log)
{
if (gl->version < 210 && gl->es < 200) {
mp_err(log, "At least OpenGL 2.1 or OpenGL ES 2.0 required.\n");
@ -2400,7 +2411,6 @@ struct gl_video *gl_video_init(GL *gl, struct mp_log *log, struct osd_state *osd
*p = (struct gl_video) {
.gl = gl,
.log = log,
.osd_state = osd,
.opts = gl_video_opts_def,
.gl_target = GL_TEXTURE_2D,
.texture_16bit_depth = 16,

View File

@ -64,8 +64,9 @@ extern const struct gl_video_opts gl_video_opts_def;
struct gl_video;
struct gl_video *gl_video_init(GL *gl, struct mp_log *log, struct osd_state *osd);
struct gl_video *gl_video_init(GL *gl, struct mp_log *log);
void gl_video_uninit(struct gl_video *p);
void gl_video_set_osd_source(struct gl_video *p, struct osd_state *osd);
void gl_video_set_options(struct gl_video *p, struct gl_video_opts *opts,
int *queue_size);
bool gl_video_check_format(struct gl_video *p, int mp_format);

View File

@ -454,9 +454,10 @@ static int preinit(struct vo *vo)
if (p->gl->SwapInterval)
p->gl->SwapInterval(p->swap_interval);
p->renderer = gl_video_init(p->gl, vo->log, vo->osd);
p->renderer = gl_video_init(p->gl, vo->log);
if (!p->renderer)
goto err_out;
gl_video_set_osd_source(p->renderer, vo->osd);
gl_video_set_output_depth(p->renderer, p->glctx->depth_r, p->glctx->depth_g,
p->glctx->depth_b);
int queue = 0;

View File

@ -87,7 +87,6 @@ struct mpv_opengl_cb_context {
// --- Immutable or semi-threadsafe.
struct osd_state *osd;
const char *hwapi;
struct vo *active;
@ -162,7 +161,6 @@ static void free_ctx(void *ptr)
}
struct mpv_opengl_cb_context *mp_opengl_create(struct mpv_global *g,
struct osd_state *osd,
struct mp_client_api *client_api)
{
mpv_opengl_cb_context *ctx = talloc_zero(NULL, mpv_opengl_cb_context);
@ -172,7 +170,6 @@ struct mpv_opengl_cb_context *mp_opengl_create(struct mpv_global *g,
ctx->gl = talloc_zero(ctx, GL);
ctx->log = mp_log_new(ctx, g->log, "opengl-cb");
ctx->osd = osd;
ctx->client_api = client_api;
switch (g->opts->hwdec_api) {
@ -220,7 +217,7 @@ int mpv_opengl_cb_init_gl(struct mpv_opengl_cb_context *ctx, const char *exts,
mpgl_load_functions2(ctx->gl, get_proc_address, get_proc_address_ctx,
exts, ctx->log);
ctx->renderer = gl_video_init(ctx->gl, ctx->log, ctx->osd);
ctx->renderer = gl_video_init(ctx->gl, ctx->log);
if (!ctx->renderer)
return MPV_ERROR_UNSUPPORTED;
@ -300,8 +297,10 @@ int mpv_opengl_cb_render(struct mpv_opengl_cb_context *ctx, int fbo, int vp[4])
gl_video_resize(ctx->renderer, vp_w, vp_h, &src, &dst, &osd);
}
if (ctx->reconfigured)
if (ctx->reconfigured) {
gl_video_set_osd_source(ctx->renderer, vo ? vo->osd : NULL);
gl_video_config(ctx->renderer, &ctx->img_params);
}
if (ctx->update_new_opts) {
struct vo_priv *p = vo ? vo->priv : NULL;
struct vo_priv *opts = ctx->new_opts ? ctx->new_opts : p;
@ -523,7 +522,6 @@ static int preinit(struct vo *vo)
}
p->ctx->active = vo;
p->ctx->reconfigured = true;
assert(vo->osd == p->ctx->osd);
copy_vo_opts(vo);
pthread_mutex_unlock(&p->ctx->lock);