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:
parent
c5e13cce52
commit
eca0fcb77a
@ -208,8 +208,8 @@ static bool upload_osd(struct mpgl_osd *ctx, struct mpgl_osd_part *osd,
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct mpgl_osd_part *osd_generate(struct mpgl_osd *ctx,
|
||||
struct sub_bitmaps *imgs)
|
||||
struct mpgl_osd_part *mpgl_osd_generate(struct mpgl_osd *ctx,
|
||||
struct sub_bitmaps *imgs)
|
||||
{
|
||||
if (imgs->num_parts == 0 || !ctx->formats[imgs->format])
|
||||
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);
|
||||
}
|
||||
|
||||
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 {
|
||||
float position[2];
|
||||
uint8_t color[4];
|
||||
@ -310,7 +262,7 @@ struct vertex {
|
||||
static void draw_legacy_cb(void *pctx, struct sub_bitmaps *imgs)
|
||||
{
|
||||
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)
|
||||
return;
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
struct mpgl_osd_part {
|
||||
enum sub_bitmap_format format;
|
||||
int bitmap_id, bitmap_pos_id;
|
||||
bool active;
|
||||
GLuint texture;
|
||||
int w, h;
|
||||
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);
|
||||
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_unset_gl_state(struct mpgl_osd *ctx, struct mpgl_osd_part *p);
|
||||
|
||||
void mpgl_osd_draw_legacy(struct mpgl_osd *ctx, double pts,
|
||||
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
|
||||
|
@ -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,
|
||||
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
|
||||
const struct m_sub_options gl_video_conf = {
|
||||
@ -1592,6 +1593,16 @@ void gl_video_render_frame(struct gl_video *p)
|
||||
p->frames_rendered++;
|
||||
|
||||
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)
|
||||
@ -1794,15 +1805,18 @@ struct mp_image *gl_video_download_image(struct gl_video *p)
|
||||
return image;
|
||||
}
|
||||
|
||||
static void draw_osd_cb(void *ctx, struct mpgl_osd_part *osd,
|
||||
struct sub_bitmaps *imgs)
|
||||
static void draw_osd_cb(void *ctx, struct sub_bitmaps *imgs)
|
||||
{
|
||||
struct gl_video *p = ctx;
|
||||
GL *gl = p->gl;
|
||||
|
||||
struct mpgl_osd_part *osd = mpgl_osd_generate(p->osd, imgs);
|
||||
if (!osd)
|
||||
return;
|
||||
|
||||
assert(osd->format != SUBBITMAP_EMPTY);
|
||||
|
||||
if (!osd->num_vertices && imgs) {
|
||||
if (!osd->num_vertices) {
|
||||
osd->vertices = talloc_realloc(osd, osd->vertices, struct vertex,
|
||||
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");
|
||||
}
|
||||
|
||||
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 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_h = h;
|
||||
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)
|
||||
|
@ -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_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_draw_osd(struct gl_video *p);
|
||||
void gl_video_upload_image(struct gl_video *p, struct mp_image *img);
|
||||
void gl_video_render_frame(struct gl_video *p);
|
||||
struct mp_image *gl_video_download_image(struct gl_video *p);
|
||||
|
@ -121,7 +121,6 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
|
||||
mpgl_lock(p->glctx);
|
||||
gl_video_upload_image(p->renderer, mpi);
|
||||
gl_video_render_frame(p->renderer);
|
||||
gl_video_draw_osd(p->renderer);
|
||||
mpgl_unlock(p->glctx);
|
||||
}
|
||||
|
||||
@ -370,7 +369,6 @@ static int control(struct vo *vo, uint32_t request, void *data)
|
||||
case VOCTRL_REDRAW_FRAME:
|
||||
mpgl_lock(p->glctx);
|
||||
gl_video_render_frame(p->renderer);
|
||||
gl_video_draw_osd(p->renderer);
|
||||
mpgl_unlock(p->glctx);
|
||||
return true;
|
||||
case VOCTRL_SET_COMMAND_LINE: {
|
||||
|
Loading…
Reference in New Issue
Block a user