summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--video/out/gl_osd.c54
-rw-r--r--video/out/gl_osd.h14
-rw-r--r--video/out/gl_video.c24
-rw-r--r--video/out/gl_video.h1
4 files changed, 80 insertions, 13 deletions
diff --git a/video/out/gl_osd.c b/video/out/gl_osd.c
index 81485cabe9..3317062311 100644
--- a/video/out/gl_osd.c
+++ b/video/out/gl_osd.c
@@ -202,8 +202,8 @@ static bool upload_osd(struct mpgl_osd *ctx, struct mpgl_osd_part *osd,
return true;
}
-struct mpgl_osd_part *mpgl_osd_generate(struct mpgl_osd *ctx,
- struct sub_bitmaps *imgs)
+static struct mpgl_osd_part *osd_generate(struct mpgl_osd *ctx,
+ struct sub_bitmaps *imgs)
{
if (imgs->num_parts == 0 || !ctx->formats[imgs->format])
return NULL;
@@ -241,6 +241,54 @@ 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,
+ struct osd_state *osd,
+ 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(osd, res, osd->vo_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];
@@ -250,7 +298,7 @@ struct vertex {
static void draw_legacy_cb(void *pctx, struct sub_bitmaps *imgs)
{
struct mpgl_osd *ctx = pctx;
- struct mpgl_osd_part *osd = mpgl_osd_generate(ctx, imgs);
+ struct mpgl_osd_part *osd = osd_generate(ctx, imgs);
if (!osd)
return;
diff --git a/video/out/gl_osd.h b/video/out/gl_osd.h
index cf3182ffb2..91c7a6f552 100644
--- a/video/out/gl_osd.h
+++ b/video/out/gl_osd.h
@@ -10,6 +10,7 @@
struct mpgl_osd_part {
enum sub_bitmap_format format;
int bitmap_id, bitmap_pos_id;
+ bool active;
GLuint texture;
int w, h;
GLuint buffer;
@@ -31,13 +32,20 @@ struct mpgl_osd {
struct mpgl_osd *mpgl_osd_init(GL *gl, bool legacy);
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, struct osd_state *osd,
struct mp_osd_res res);
+void mpgl_osd_draw_cb(struct mpgl_osd *ctx,
+ struct osd_state *osd,
+ 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
diff --git a/video/out/gl_video.c b/video/out/gl_video.c
index a000624f9c..f0a6f60d84 100644
--- a/video/out/gl_video.c
+++ b/video/out/gl_video.c
@@ -1425,18 +1425,15 @@ struct mp_image *gl_video_download_image(struct gl_video *p)
return image;
}
-static void draw_osd_cb(void *ctx, struct sub_bitmaps *imgs)
+static void draw_osd_cb(void *ctx, struct mpgl_osd_part *osd,
+ 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) {
+ if (!osd->num_vertices && imgs) {
osd->vertices = talloc_realloc(osd, osd->vertices, struct vertex,
osd->packer->count * VERTICES_PER_QUAD);
@@ -1476,7 +1473,7 @@ void gl_video_draw_osd(struct gl_video *p, struct osd_state *osd)
GL *gl = p->gl;
assert(p->osd);
- osd_draw(osd, p->osd_rect, osd->vo_pts, 0, p->osd->formats, draw_osd_cb, p);
+ mpgl_osd_draw_cb(p->osd, osd, 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
@@ -1831,3 +1828,16 @@ static int validate_scaler_opt(const m_option_t *opt, struct bstr name,
snprintf(s, sizeof(s), "%.*s", BSTR_P(param));
return handle_scaler_opt(s) ? 1 : M_OPT_INVALID;
}
+
+// Resize and redraw the contents of the window without further configuration.
+// Intended to be used in situations where the frontend can't really be
+// involved with reconfiguring the VO properly.
+// gl_video_resize() should be called when user interaction is done.
+void gl_video_resize_redraw(struct gl_video *p, int w, int h)
+{
+ p->gl->Viewport(p->vp_x, p->vp_y, w, h);
+ p->vp_w = w;
+ p->vp_h = h;
+ gl_video_render_frame(p);
+ mpgl_osd_redraw_cb(p->osd, draw_osd_cb, p);
+}
diff --git a/video/out/gl_video.h b/video/out/gl_video.h
index 985db9b9cc..8418df1bc1 100644
--- a/video/out/gl_video.h
+++ b/video/out/gl_video.h
@@ -66,6 +66,7 @@ bool gl_video_set_equalizer(struct gl_video *p, const char *name, int val);
bool gl_video_get_equalizer(struct gl_video *p, const char *name, int *val);
void gl_video_set_debug(struct gl_video *p, bool enable);
+void gl_video_resize_redraw(struct gl_video *p, int w, int h);
bool gl_video_check_format(int mp_format);