From 56616b0b013cbeae69555ae95ff577482e82bb1f Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 16 Sep 2016 17:17:32 +0200 Subject: osd: fix OSD getting stuck with --blend-subtitles=yes If --blend-subtitles=yes is given, vo_opengl will call osd_draw() multiple times, once for subtitles, and once for OSD. This meant that the want_redraw flag was reset before the OSD was rendered, which in turn meant that update_osd() was never called. It seems like removing the per-OSD object want_redraw wasn't such a good idea. Fix it by reintroducing such a flag for OSDTYPE_OSD only. Also, the want_redraw flag is now unused, so kill it. Another regression caused by commit 9c9cf125. Fixes #3535. --- sub/osd.c | 27 ++++++++++++++------------- sub/osd_libass.c | 5 +++-- sub/osd_state.h | 5 +---- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/sub/osd.c b/sub/osd.c index 1f743792da..caefd648ce 100644 --- a/sub/osd.c +++ b/sub/osd.c @@ -146,12 +146,6 @@ void osd_free(struct osd_state *osd) talloc_free(osd); } -void osd_changed_unlocked(struct osd_state *osd) -{ - osd->want_redraw = true; - osd->want_redraw_notification = true; -} - void osd_set_text(struct osd_state *osd, const char *text) { pthread_mutex_lock(&osd->lock); @@ -161,7 +155,8 @@ void osd_set_text(struct osd_state *osd, const char *text) if (strcmp(osd_obj->text, text) != 0) { talloc_free(osd_obj->text); osd_obj->text = talloc_strdup(osd_obj, text); - osd_changed_unlocked(osd); + osd_obj->osd_changed = true; + osd->want_redraw_notification = true; } pthread_mutex_unlock(&osd->lock); } @@ -174,7 +169,7 @@ void osd_set_sub(struct osd_state *osd, int index, struct dec_sub *dec_sub) obj->sub = dec_sub; obj->vo_change_id += 1; } - osd_changed_unlocked(osd); + osd->want_redraw_notification = true; pthread_mutex_unlock(&osd->lock); } @@ -203,7 +198,8 @@ void osd_set_progbar(struct osd_state *osd, struct osd_progbar_state *s) MP_TARRAY_GROW(osd_obj, osd_obj->progbar_state.stops, s->num_stops); memcpy(osd_obj->progbar_state.stops, s->stops, sizeof(osd_obj->progbar_state.stops[0]) * s->num_stops); - osd_changed_unlocked(osd); + osd_obj->osd_changed = true; + osd->want_redraw_notification = true; pthread_mutex_unlock(&osd->lock); } @@ -212,7 +208,7 @@ void osd_set_external2(struct osd_state *osd, struct sub_bitmaps *imgs) pthread_mutex_lock(&osd->lock); osd->objs[OSDTYPE_EXTERNAL2]->external2 = imgs; osd->objs[OSDTYPE_EXTERNAL2]->vo_change_id += 1; - osd_changed_unlocked(osd); + osd->want_redraw_notification = true; pthread_mutex_unlock(&osd->lock); } @@ -221,7 +217,6 @@ static void check_obj_resize(struct osd_state *osd, struct mp_osd_res res, { if (!osd_res_equals(res, obj->vo_res)) { obj->vo_res = res; - osd->want_redraw = true; mp_client_broadcast_event(mp_client_api_get_core(osd->global->client_api), MP_EVENT_WIN_RESIZE, NULL); } @@ -324,8 +319,12 @@ void osd_draw(struct osd_state *osd, struct mp_osd_res res, sub_unlock(obj->sub); } + // If this is called with OSD_DRAW_SUB_ONLY or OSD_DRAW_OSD_ONLY set, assume + // it will always draw the complete OSD by doing multiple osd_draw() calls. + // OSD_DRAW_SUB_FILTER on the other hand is an evil special-case, and we + // must not reset the flag when it happens. if (!(draw_flags & OSD_DRAW_SUB_FILTER)) - osd->want_redraw = osd->want_redraw_notification = false; + osd->want_redraw_notification = false; pthread_mutex_unlock(&osd->lock); } @@ -383,10 +382,12 @@ struct mp_osd_res osd_res_from_image_params(const struct mp_image_params *p) }; } +// Typically called to react to OSD style changes. void osd_changed(struct osd_state *osd) { pthread_mutex_lock(&osd->lock); - osd_changed_unlocked(osd); + osd->objs[OSDTYPE_OSD]->osd_changed = true; + osd->want_redraw_notification = true; pthread_mutex_unlock(&osd->lock); } diff --git a/sub/osd_libass.c b/sub/osd_libass.c index 9b634f5214..49edafbcf5 100644 --- a/sub/osd_libass.c +++ b/sub/osd_libass.c @@ -431,6 +431,7 @@ static void update_progbar(struct osd_state *osd, struct osd_object *obj) static void update_osd(struct osd_state *osd, struct osd_object *obj) { + obj->osd_changed = false; clear_ass(&obj->ass); update_osd_text(osd, obj); update_progbar(osd, obj); @@ -501,7 +502,7 @@ void osd_set_external(struct osd_state *osd, void *id, int res_x, int res_y, entry->res_y = res_y; update_external(osd, obj, entry); obj->changed = true; - osd_changed_unlocked(osd); + osd->want_redraw_notification = true; } done: @@ -527,7 +528,7 @@ static void append_ass(struct ass_state *ass, struct mp_osd_res *res, void osd_object_get_bitmaps(struct osd_state *osd, struct osd_object *obj, int format, struct sub_bitmaps *out_imgs) { - if (osd->want_redraw && obj->type == OSDTYPE_OSD) + if (obj->type == OSDTYPE_OSD && obj->osd_changed) update_osd(osd, obj); if (!obj->ass_packer) diff --git a/sub/osd_state.h b/sub/osd_state.h index d054f3d06d..fbccd85e70 100644 --- a/sub/osd_state.h +++ b/sub/osd_state.h @@ -29,9 +29,8 @@ struct osd_object { bool is_sub; // OSDTYPE_OSD + bool osd_changed; char *text; - - // OSDTYPE_OSD struct osd_progbar_state progbar_state; // OSDTYPE_SUB/OSDTYPE_SUB2 @@ -79,6 +78,4 @@ struct osd_state { struct mp_draw_sub_cache *draw_cache; }; -void osd_changed_unlocked(struct osd_state *osd); - #endif -- cgit v1.2.3