summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-08-18 22:59:22 +0200
committerwm4 <wm4@nowhere>2015-08-18 23:09:37 +0200
commit5eb6466e54ac2e8d4a5265418b04644d15302ece (patch)
tree687fbf9a4bad1430542c5444908c4a31ef90b0ee
parent58ba2a9087dfa6bf6a81177c77f86e01acd33286 (diff)
downloadmpv-5eb6466e54ac2e8d4a5265418b04644d15302ece.tar.bz2
mpv-5eb6466e54ac2e8d4a5265418b04644d15302ece.tar.xz
vo_rpi: redraw subtitles only on change
Since vo_rpi uses MMAL for video output, which is completely independent from the GLES overlay, we can just not redraw the GLES screen if subtitles do not change. (As a furhter optimization, the dispmanx overlay could be removed if nothing is visible. But I'm not sure if adding and removing the overlay frequently is a good idea for performance, so this could just as well go the other way.)
-rw-r--r--video/out/gl_osd.c17
-rw-r--r--video/out/gl_osd.h1
-rw-r--r--video/out/vo_rpi.c19
3 files changed, 33 insertions, 4 deletions
diff --git a/video/out/gl_osd.c b/video/out/gl_osd.c
index c346a3e630..0307904c25 100644
--- a/video/out/gl_osd.c
+++ b/video/out/gl_osd.c
@@ -78,6 +78,7 @@ struct mpgl_osd_part {
int w, h;
GLuint buffer;
int num_subparts;
+ int prev_num_subparts;
struct sub_bitmap *subparts;
struct vertex *vertices;
struct bitmap_packer *packer;
@@ -93,6 +94,7 @@ struct mpgl_osd {
const struct osd_fmt_entry *fmt_table;
bool formats[SUBBITMAP_COUNT];
struct gl_vao vao;
+ int64_t change_counter;
// temporary
int stereo_mode;
int display_size[2];
@@ -288,6 +290,7 @@ static void gen_osd_cb(void *pctx, struct sub_bitmaps *imgs)
osd->packer->count = 0;
osd->change_id = imgs->change_id;
+ ctx->change_counter += 1;
}
osd->num_subparts = osd->packer->count;
@@ -420,4 +423,18 @@ void mpgl_osd_generate(struct mpgl_osd *ctx, struct mp_osd_res res, double pts,
osd_draw(ctx->osd, s_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
+ // (not even with num_parts==0), so check this separately.
+ for (int n = 0; n < MAX_OSD_PARTS; n++) {
+ struct mpgl_osd_part *part = ctx->parts[n];
+ if (part->num_subparts != part->prev_num_subparts)
+ ctx->change_counter += 1;
+ part->prev_num_subparts = part->num_subparts;
+ }
+}
+
+int64_t mpgl_get_change_counter(struct mpgl_osd *ctx)
+{
+ return ctx->change_counter;
}
diff --git a/video/out/gl_osd.h b/video/out/gl_osd.h
index 130008a58d..e00565aad7 100644
--- a/video/out/gl_osd.h
+++ b/video/out/gl_osd.h
@@ -17,5 +17,6 @@ void mpgl_osd_generate(struct mpgl_osd *ctx, struct mp_osd_res res, double pts,
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);
+int64_t mpgl_get_change_counter(struct mpgl_osd *ctx);
#endif
diff --git a/video/out/vo_rpi.c b/video/out/vo_rpi.c
index 95627d4073..f3dfab3af6 100644
--- a/video/out/vo_rpi.c
+++ b/video/out/vo_rpi.c
@@ -56,6 +56,7 @@ struct priv {
struct mp_egl_rpi egl;
struct gl_shader_cache *sc;
struct mpgl_osd *osd;
+ int64_t osd_change_counter;
MMAL_COMPONENT_T *renderer;
bool renderer_enabled;
@@ -117,6 +118,16 @@ static void update_osd(struct vo *vo)
mpgl_osd_generate(p->osd, p->osd_res, p->osd_pts, 0, 0);
+ int64_t osd_change_counter = mpgl_get_change_counter(p->osd);
+ if (p->osd_change_counter == osd_change_counter) {
+ p->skip_osd = true;
+ return;
+ }
+ p->osd_change_counter = osd_change_counter;
+
+ p->egl.gl->ClearColor(0, 0, 0, 0);
+ p->egl.gl->Clear(GL_COLOR_BUFFER_BIT);
+
for (int n = 0; n < MAX_OSD_PARTS; n++) {
enum sub_bitmap_format fmt = mpgl_osd_get_part_format(p->osd, n);
if (!fmt)
@@ -331,11 +342,9 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame)
// Redraw only if the OSD has meaningfully changed, which we assume it
// hasn't when a frame is merely repeated for display sync.
p->skip_osd = !frame->redraw && frame->repeat;
- if (!p->skip_osd && p->egl.gl) {
- p->egl.gl->ClearColor(0, 0, 0, 0);
- p->egl.gl->Clear(GL_COLOR_BUFFER_BIT);
+
+ if (!p->skip_osd && p->egl.gl)
update_osd(vo);
- }
p->display_synced = frame->display_synced;
@@ -519,8 +528,10 @@ static int control(struct vo *vo, uint32_t request, void *data)
case VOCTRL_SET_PANSCAN:
if (p->renderer_enabled)
resize(vo);
+ vo->want_redraw = true;
return VO_TRUE;
case VOCTRL_REDRAW_FRAME:
+ p->osd_change_counter = -1;
update_osd(vo);
return VO_TRUE;
case VOCTRL_SCREENSHOT_WIN: