From 5eb6466e54ac2e8d4a5265418b04644d15302ece Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 18 Aug 2015 22:59:22 +0200 Subject: 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.) --- video/out/gl_osd.c | 17 +++++++++++++++++ video/out/gl_osd.h | 1 + video/out/vo_rpi.c | 19 +++++++++++++++---- 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: -- cgit v1.2.3