1
mirror of https://github.com/mpv-player/mpv synced 2024-11-18 21:16:10 +01:00

vo_opengl: simplify redraw callback OSD handling

OSD used to be not thread-safe at all, so a track was used to get it
redrawn. This mostly reverts commit 6a2a8880, because OSD not being
thread-safe was the non-trivial part of it.

Mostly untested, because this code path is used on OSX only, and I don't
have OSX.
This commit is contained in:
wm4 2014-06-15 23:58:33 +02:00
parent c5e13cce52
commit eca0fcb77a
5 changed files with 23 additions and 82 deletions

View File

@ -208,8 +208,8 @@ static bool upload_osd(struct mpgl_osd *ctx, struct mpgl_osd_part *osd,
return true; return true;
} }
static struct mpgl_osd_part *osd_generate(struct mpgl_osd *ctx, struct mpgl_osd_part *mpgl_osd_generate(struct mpgl_osd *ctx,
struct sub_bitmaps *imgs) struct sub_bitmaps *imgs)
{ {
if (imgs->num_parts == 0 || !ctx->formats[imgs->format]) if (imgs->num_parts == 0 || !ctx->formats[imgs->format])
return NULL; return NULL;
@ -253,54 +253,6 @@ void mpgl_osd_unset_gl_state(struct mpgl_osd *ctx, struct mpgl_osd_part *p)
gl->BindTexture(GL_TEXTURE_2D, 0); gl->BindTexture(GL_TEXTURE_2D, 0);
} }
static void reset(struct mpgl_osd *ctx)
{
for (int n = 0; n < MAX_OSD_PARTS; n++) {
struct mpgl_osd_part *p = ctx->parts[n];
p->active = false;
}
}
struct draw_cb_closure {
struct mpgl_osd *ctx;
void (*cb)(void *ctx, struct mpgl_osd_part *part, struct sub_bitmaps *imgs);
void *cb_ctx;
};
static void draw_cb(void *pctx, struct sub_bitmaps *imgs)
{
struct draw_cb_closure *c = pctx;
struct mpgl_osd_part *part = osd_generate(c->ctx, imgs);
if (!part)
return;
part->active = true;
c->cb(c->cb_ctx, part, imgs);
}
void mpgl_osd_draw_cb(struct mpgl_osd *ctx,
double pts,
struct mp_osd_res res,
void (*cb)(void *ctx, struct mpgl_osd_part *part,
struct sub_bitmaps *imgs),
void *cb_ctx)
{
struct draw_cb_closure c = {ctx, cb, cb_ctx};
reset(ctx);
osd_draw(ctx->osd, res, pts, 0, ctx->formats, draw_cb, &c);
}
void mpgl_osd_redraw_cb(struct mpgl_osd *ctx,
void (*cb)(void *ctx, struct mpgl_osd_part *part,
struct sub_bitmaps *imgs),
void *cb_ctx)
{
for (int n = 0; n < MAX_OSD_PARTS; n++) {
struct mpgl_osd_part *p = ctx->parts[n];
if (p->active)
cb(cb_ctx, p, NULL);
}
}
struct vertex { struct vertex {
float position[2]; float position[2];
uint8_t color[4]; uint8_t color[4];
@ -310,7 +262,7 @@ struct vertex {
static void draw_legacy_cb(void *pctx, struct sub_bitmaps *imgs) static void draw_legacy_cb(void *pctx, struct sub_bitmaps *imgs)
{ {
struct mpgl_osd *ctx = pctx; struct mpgl_osd *ctx = pctx;
struct mpgl_osd_part *osd = osd_generate(ctx, imgs); struct mpgl_osd_part *osd = mpgl_osd_generate(ctx, imgs);
if (!osd) if (!osd)
return; return;

View File

@ -10,7 +10,6 @@
struct mpgl_osd_part { struct mpgl_osd_part {
enum sub_bitmap_format format; enum sub_bitmap_format format;
int bitmap_id, bitmap_pos_id; int bitmap_id, bitmap_pos_id;
bool active;
GLuint texture; GLuint texture;
int w, h; int w, h;
GLuint buffer; GLuint buffer;
@ -34,20 +33,13 @@ struct mpgl_osd {
struct mpgl_osd *mpgl_osd_init(GL *gl, struct mp_log *log, struct osd_state *osd); struct mpgl_osd *mpgl_osd_init(GL *gl, struct mp_log *log, struct osd_state *osd);
void mpgl_osd_destroy(struct mpgl_osd *ctx); void mpgl_osd_destroy(struct mpgl_osd *ctx);
struct mpgl_osd_part *mpgl_osd_generate(struct mpgl_osd *ctx,
struct sub_bitmaps *b);
void mpgl_osd_set_gl_state(struct mpgl_osd *ctx, struct mpgl_osd_part *p); void mpgl_osd_set_gl_state(struct mpgl_osd *ctx, struct mpgl_osd_part *p);
void mpgl_osd_unset_gl_state(struct mpgl_osd *ctx, struct mpgl_osd_part *p); void mpgl_osd_unset_gl_state(struct mpgl_osd *ctx, struct mpgl_osd_part *p);
void mpgl_osd_draw_legacy(struct mpgl_osd *ctx, double pts, void mpgl_osd_draw_legacy(struct mpgl_osd *ctx, double pts,
struct mp_osd_res res); struct mp_osd_res res);
void mpgl_osd_draw_cb(struct mpgl_osd *ctx,
double pts,
struct mp_osd_res res,
void (*cb)(void *ctx, struct mpgl_osd_part *part,
struct sub_bitmaps *imgs),
void *cb_ctx);
void mpgl_osd_redraw_cb(struct mpgl_osd *ctx,
void (*cb)(void *ctx, struct mpgl_osd_part *part,
struct sub_bitmaps *imgs),
void *cb_ctx);
#endif #endif

View File

@ -302,6 +302,7 @@ const struct gl_video_opts gl_video_opts_hq_def = {
static int validate_scaler_opt(struct mp_log *log, const m_option_t *opt, static int validate_scaler_opt(struct mp_log *log, const m_option_t *opt,
struct bstr name, struct bstr param); struct bstr name, struct bstr param);
static void draw_osd_cb(void *ctx, struct sub_bitmaps *imgs);
#define OPT_BASE_STRUCT struct gl_video_opts #define OPT_BASE_STRUCT struct gl_video_opts
const struct m_sub_options gl_video_conf = { const struct m_sub_options gl_video_conf = {
@ -1592,6 +1593,16 @@ void gl_video_render_frame(struct gl_video *p)
p->frames_rendered++; p->frames_rendered++;
debug_check_gl(p, "after video rendering"); debug_check_gl(p, "after video rendering");
assert(p->osd);
osd_draw(p->osd_state, p->osd_rect, p->osd_pts, 0, p->osd->formats,
draw_osd_cb, p);
// The playloop calls this last before waiting some time until it decides
// to call flip_page(). Tell OpenGL to start execution of the GPU commands
// while we sleep (this happens asynchronously).
gl->Flush();
} }
static void update_window_sized_objects(struct gl_video *p) static void update_window_sized_objects(struct gl_video *p)
@ -1794,15 +1805,18 @@ struct mp_image *gl_video_download_image(struct gl_video *p)
return image; return image;
} }
static void draw_osd_cb(void *ctx, struct mpgl_osd_part *osd, static void draw_osd_cb(void *ctx, struct sub_bitmaps *imgs)
struct sub_bitmaps *imgs)
{ {
struct gl_video *p = ctx; struct gl_video *p = ctx;
GL *gl = p->gl; GL *gl = p->gl;
struct mpgl_osd_part *osd = mpgl_osd_generate(p->osd, imgs);
if (!osd)
return;
assert(osd->format != SUBBITMAP_EMPTY); assert(osd->format != SUBBITMAP_EMPTY);
if (!osd->num_vertices && imgs) { if (!osd->num_vertices) {
osd->vertices = talloc_realloc(osd, osd->vertices, struct vertex, osd->vertices = talloc_realloc(osd, osd->vertices, struct vertex,
osd->packer->count * VERTICES_PER_QUAD); osd->packer->count * VERTICES_PER_QUAD);
@ -1837,19 +1851,6 @@ static void draw_osd_cb(void *ctx, struct mpgl_osd_part *osd,
debug_check_gl(p, "after drawing osd"); debug_check_gl(p, "after drawing osd");
} }
void gl_video_draw_osd(struct gl_video *p)
{
GL *gl = p->gl;
assert(p->osd);
mpgl_osd_draw_cb(p->osd, p->osd_pts, p->osd_rect, draw_osd_cb, p);
// The playloop calls this last before waiting some time until it decides
// to call flip_page(). Tell OpenGL to start execution of the GPU commands
// while we sleep (this happens asynchronously).
gl->Flush();
}
static bool test_fbo(struct gl_video *p, GLenum format) static bool test_fbo(struct gl_video *p, GLenum format)
{ {
static const float vals[] = { static const float vals[] = {
@ -2315,7 +2316,6 @@ void gl_video_resize_redraw(struct gl_video *p, int w, int h)
p->vp_w = w; p->vp_w = w;
p->vp_h = h; p->vp_h = h;
gl_video_render_frame(p); gl_video_render_frame(p);
mpgl_osd_redraw_cb(p->osd, draw_osd_cb, p);
} }
void gl_video_set_hwdec(struct gl_video *p, struct gl_hwdec *hwdec) void gl_video_set_hwdec(struct gl_video *p, struct gl_hwdec *hwdec)

View File

@ -62,7 +62,6 @@ bool gl_video_check_format(struct gl_video *p, int mp_format);
void gl_video_config(struct gl_video *p, struct mp_image_params *params); void gl_video_config(struct gl_video *p, struct mp_image_params *params);
void gl_video_set_output_depth(struct gl_video *p, int r, int g, int b); void gl_video_set_output_depth(struct gl_video *p, int r, int g, int b);
void gl_video_set_lut3d(struct gl_video *p, struct lut3d *lut3d); void gl_video_set_lut3d(struct gl_video *p, struct lut3d *lut3d);
void gl_video_draw_osd(struct gl_video *p);
void gl_video_upload_image(struct gl_video *p, struct mp_image *img); void gl_video_upload_image(struct gl_video *p, struct mp_image *img);
void gl_video_render_frame(struct gl_video *p); void gl_video_render_frame(struct gl_video *p);
struct mp_image *gl_video_download_image(struct gl_video *p); struct mp_image *gl_video_download_image(struct gl_video *p);

View File

@ -121,7 +121,6 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
mpgl_lock(p->glctx); mpgl_lock(p->glctx);
gl_video_upload_image(p->renderer, mpi); gl_video_upload_image(p->renderer, mpi);
gl_video_render_frame(p->renderer); gl_video_render_frame(p->renderer);
gl_video_draw_osd(p->renderer);
mpgl_unlock(p->glctx); mpgl_unlock(p->glctx);
} }
@ -370,7 +369,6 @@ static int control(struct vo *vo, uint32_t request, void *data)
case VOCTRL_REDRAW_FRAME: case VOCTRL_REDRAW_FRAME:
mpgl_lock(p->glctx); mpgl_lock(p->glctx);
gl_video_render_frame(p->renderer); gl_video_render_frame(p->renderer);
gl_video_draw_osd(p->renderer);
mpgl_unlock(p->glctx); mpgl_unlock(p->glctx);
return true; return true;
case VOCTRL_SET_COMMAND_LINE: { case VOCTRL_SET_COMMAND_LINE: {