summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sub/osd.c34
-rw-r--r--sub/osd.h2
-rw-r--r--video/out/opengl/osd.c32
-rw-r--r--video/out/opengl/osd.h1
-rw-r--r--video/out/opengl/video.c2
5 files changed, 55 insertions, 16 deletions
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);
-
- 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];
+ set_res(ctx, res, stereo_mode);
- 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)