diff --git a/sub/osd.c b/sub/osd.c index e37b6cf106..bbc6d9a1e1 100644 --- a/sub/osd.c +++ b/sub/osd.c @@ -212,6 +212,33 @@ void osd_set_external2(struct osd_state *osd, struct sub_bitmaps *imgs) pthread_mutex_unlock(&osd->lock); } +static void check_obj_resize(struct osd_state *osd, struct mp_osd_res res, + struct osd_object *obj) +{ + if (!osd_res_equals(res, obj->vo_res)) { + obj->vo_res = res; + obj->force_redraw = true; + mp_client_broadcast_event(mp_client_api_get_core(osd->global->client_api), + MP_EVENT_WIN_RESIZE, NULL); + } +} + +// Optional. Can be called for faster reaction of OSD-generating scripts like +// osc.lua. This can achieve that the resize happens first, so that the OSD is +// generated at the correct resolution the first time the resized frame is +// rendered. Since the OSD doesn't (and can't) wait for the script, this +// increases the time in which the script can react, and also gets rid of the +// unavoidable redraw delay (though it will still be racy). +// Unnecessary for anything else. +void osd_resize(struct osd_state *osd, struct mp_osd_res res) +{ + pthread_mutex_lock(&osd->lock); + int types[] = {OSDTYPE_OSD, OSDTYPE_EXTERNAL, OSDTYPE_EXTERNAL2, -1}; + for (int n = 0; types[n] >= 0; n++) + check_obj_resize(osd, res, osd->objs[types[n]]); + pthread_mutex_unlock(&osd->lock); +} + static void render_object(struct osd_state *osd, struct osd_object *obj, struct mp_osd_res res, double video_pts, const bool sub_formats[SUBBITMAP_COUNT], @@ -226,12 +253,7 @@ static void render_object(struct osd_state *osd, struct osd_object *obj, *out_imgs = (struct sub_bitmaps) {0}; - if (!osd_res_equals(res, obj->vo_res)) { - obj->vo_res = res; - obj->force_redraw = true; - mp_client_broadcast_event(mp_client_api_get_core(osd->global->client_api), - MP_EVENT_WIN_RESIZE, NULL); - } + check_obj_resize(osd, res, obj); if (obj->type == OSDTYPE_SUB || obj->type == OSDTYPE_SUB2) { if (obj->sub) { diff --git a/sub/osd.h b/sub/osd.h index 494b534d5e..0c9dbc3e90 100644 --- a/sub/osd.h +++ b/sub/osd.h @@ -176,6 +176,8 @@ void osd_draw_on_image_p(struct osd_state *osd, struct mp_osd_res res, double video_pts, int draw_flags, struct mp_image_pool *pool, struct mp_image *dest); +void osd_resize(struct osd_state *osd, struct mp_osd_res res); + struct mp_image_params; struct mp_osd_res osd_res_from_image_params(const struct mp_image_params *p); diff --git a/video/out/opengl/osd.c b/video/out/opengl/osd.c index 215c83cbe7..c554425e0f 100644 --- a/video/out/opengl/osd.c +++ b/video/out/opengl/osd.c @@ -92,7 +92,7 @@ struct mpgl_osd { int64_t change_counter; // temporary int stereo_mode; - int display_size[2]; + struct mp_osd_res osd_res; void *scratch; }; @@ -382,8 +382,8 @@ void mpgl_osd_draw_part(struct mpgl_osd *ctx, int vp_w, int vp_h, int index) struct gl_transform t; gl_transform_ortho(&t, 0, vp_w, 0, vp_h); - float a_x = ctx->display_size[0] * x; - float a_y = ctx->display_size[1] * y; + float a_x = ctx->osd_res.w * x; + float a_y = ctx->osd_res.h * y; t.t[0] += a_x * t.m[0][0] + a_y * t.m[1][0]; t.t[1] += a_x * t.m[0][1] + a_y * t.m[1][1]; @@ -403,20 +403,25 @@ struct gl_vao *mpgl_osd_get_vao(struct mpgl_osd *ctx) return &ctx->vao; } +static void set_res(struct mpgl_osd *ctx, struct mp_osd_res res, int stereo_mode) +{ + int div[2]; + get_3d_side_by_side(stereo_mode, div); + + res.w /= div[0]; + res.h /= div[1]; + ctx->osd_res = res; +} + void mpgl_osd_generate(struct mpgl_osd *ctx, struct mp_osd_res res, double pts, int stereo_mode, int draw_flags) { for (int n = 0; n < MAX_OSD_PARTS; n++) ctx->parts[n]->num_subparts = 0; - int div[2]; - get_3d_side_by_side(stereo_mode, div); + set_res(ctx, res, stereo_mode); - struct mp_osd_res s_res = res; - ctx->display_size[0] = s_res.w = s_res.w / div[0]; - ctx->display_size[1] = s_res.h = s_res.h / div[1]; - - osd_draw(ctx->osd, s_res, pts, draw_flags, ctx->formats, gen_osd_cb, ctx); + osd_draw(ctx->osd, ctx->osd_res, pts, draw_flags, ctx->formats, gen_osd_cb, ctx); ctx->stereo_mode = stereo_mode; // Parts going away does not necessarily result in gen_osd_cb() being called @@ -429,6 +434,13 @@ void mpgl_osd_generate(struct mpgl_osd *ctx, struct mp_osd_res res, double pts, } } +// See osd_resize() for remarks. This function is an optional optimization too. +void mpgl_osd_resize(struct mpgl_osd *ctx, struct mp_osd_res res, int stereo_mode) +{ + set_res(ctx, res, stereo_mode); + osd_resize(ctx->osd, ctx->osd_res); +} + int64_t mpgl_get_change_counter(struct mpgl_osd *ctx) { return ctx->change_counter; diff --git a/video/out/opengl/osd.h b/video/out/opengl/osd.h index bd47f71764..34cbf2b383 100644 --- a/video/out/opengl/osd.h +++ b/video/out/opengl/osd.h @@ -14,6 +14,7 @@ void mpgl_osd_set_options(struct mpgl_osd *ctx, bool pbo); void mpgl_osd_generate(struct mpgl_osd *ctx, struct mp_osd_res res, double pts, int stereo_mode, int draw_flags); +void mpgl_osd_resize(struct mpgl_osd *ctx, struct mp_osd_res res, int stereo_mode); enum sub_bitmap_format mpgl_osd_get_part_format(struct mpgl_osd *ctx, int index); struct gl_vao *mpgl_osd_get_vao(struct mpgl_osd *ctx); void mpgl_osd_draw_part(struct mpgl_osd *ctx, int vp_w, int vp_h, int index); diff --git a/video/out/opengl/video.c b/video/out/opengl/video.c index 94e728912d..a1e98bef14 100644 --- a/video/out/opengl/video.c +++ b/video/out/opengl/video.c @@ -2448,6 +2448,8 @@ void gl_video_resize(struct gl_video *p, int vp_w, int vp_h, p->vp_h = vp_h; gl_video_reset_surfaces(p); + + mpgl_osd_resize(p->osd, p->osd_rect, p->image_params.stereo_out); } static bool unmap_image(struct gl_video *p, struct mp_image *mpi)