diff --git a/apps/gui/bitmap/list-skinned.c b/apps/gui/bitmap/list-skinned.c index 64a7f49ad6..b9bd18c2d1 100644 --- a/apps/gui/bitmap/list-skinned.c +++ b/apps/gui/bitmap/list-skinned.c @@ -281,8 +281,7 @@ bool skinlist_draw(struct screen *display, struct gui_synclist *list) } current_column = -1; current_row = -1; - display->set_viewport(parent); - display->update_viewport(); + skin_render_deferred(display, parent); current_drawing_line = list->selected_item; return true; } diff --git a/apps/gui/bitmap/list.c b/apps/gui/bitmap/list.c index 1d4942839a..34ae79e316 100644 --- a/apps/gui/bitmap/list.c +++ b/apps/gui/bitmap/list.c @@ -446,8 +446,7 @@ void list_draw(struct screen *display, struct gui_synclist *list) callback_draw_item(&list_info); } - display->set_viewport(parent); - display->update_viewport(); + skin_render_deferred(display, parent); display->set_viewport(last_vp); } diff --git a/apps/gui/quickscreen.c b/apps/gui/quickscreen.c index b76a4fd386..a5712ed66c 100644 --- a/apps/gui/quickscreen.c +++ b/apps/gui/quickscreen.c @@ -242,8 +242,7 @@ static void gui_quickscreen_draw(const struct gui_quickscreen *qs, (vp_icons->width/2) - 4, vp_icons->height - 8, 7, 8); } - display->set_viewport(parent); - display->update_viewport(); + skin_render_deferred(display, parent); display->set_viewport(last_vp); } diff --git a/apps/gui/skin_engine/skin_engine.h b/apps/gui/skin_engine/skin_engine.h index fbaf1bf68a..f753dc8087 100644 --- a/apps/gui/skin_engine/skin_engine.h +++ b/apps/gui/skin_engine/skin_engine.h @@ -51,6 +51,11 @@ void skin_disarm_touchregions(struct gui_wps *gwps); void skin_update(enum skinnable_screens skin, enum screen_type screen, unsigned int update_type); +/* Defer updates in skin_render */ +void skin_defer_rendering(bool deferred); +/* Render viewport together with deferred updates */ +void skin_render_deferred(struct screen *display, struct viewport *vp); + bool skin_has_sbs(struct gui_wps *gwps); diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c index 77443eb8eb..8a7cea5414 100644 --- a/apps/gui/skin_engine/skin_render.c +++ b/apps/gui/skin_engine/skin_render.c @@ -84,6 +84,8 @@ static void skin_render_playlistviewer(struct playlistviewer* viewer, unsigned long refresh_type); static char* skin_buffer; +static bool defer_rendering; +static bool dirty; static inline struct skin_element* get_child(OFFSETTYPE(struct skin_element**) children, int child) @@ -841,6 +843,27 @@ void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps, wps_display_images(gwps, &skin_viewport->vp); } +void skin_defer_rendering(bool deferred) +{ + defer_rendering = deferred; +} + +void skin_render_deferred(struct screen *display, struct viewport *vp) +{ + if (dirty) + { + dirty = false; + display->set_viewport(NULL); + display->update(); + sb_skin_force_next_update(); + } + else + { + display->set_viewport(vp); + display->update_viewport(); + } +} + void skin_render(struct gui_wps *gwps, unsigned refresh_mode) { const int vp_is_appearing = (VP_DRAW_WASHIDDEN|VP_DRAW_HIDEABLE); @@ -940,7 +963,10 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode) } /* Restore the default viewport */ display->set_viewport_ex(NULL, VP_FLAG_VP_SET_CLEAN); - display->update(); + if (defer_rendering) + dirty = true; + else + display->update(); } static __attribute__((noinline)) diff --git a/apps/gui/viewport.c b/apps/gui/viewport.c index b50cba7d74..6bc51401f5 100644 --- a/apps/gui/viewport.c +++ b/apps/gui/viewport.c @@ -154,7 +154,11 @@ static void toggle_theme(enum screen_type screen, bool force) } intptr_t force = first_boot?0:1; + skin_defer_rendering(true); send_event(GUI_EVENT_ACTIONUPDATE, (void*)force); + skin_defer_rendering(false); + if (!first_boot) + sb_skin_force_next_update(); } else { diff --git a/apps/gui/wps.c b/apps/gui/wps.c index 0e52323dc2..6d8597d495 100644 --- a/apps/gui/wps.c +++ b/apps/gui/wps.c @@ -533,7 +533,11 @@ static void gwps_leave_wps(bool theme_enabled) viewports drawn by the WPS. May need further thought... */ struct wps_data *sbs = skin_get_gwps(CUSTOM_STATUSBAR, i)->data; if (gwps->data->use_extra_framebuffer && sbs->use_extra_framebuffer) + { + skin_defer_rendering(true); skin_update(CUSTOM_STATUSBAR, i, SKIN_REFRESH_ALL); + skin_defer_rendering(false); + } #endif viewportmanager_theme_undo(i, skin_has_sbs(gwps)); } diff --git a/apps/misc.c b/apps/misc.c index 1780ccd9fe..0c5d73d2ee 100644 --- a/apps/misc.c +++ b/apps/misc.c @@ -65,6 +65,7 @@ #include "list.h" #include "fixedpoint.h" #include "open_plugin.h" +#include "statusbar-skinned.h" #include "debug.h" @@ -1795,8 +1796,14 @@ static void push_current_activity_refresh(enum current_activity screen, bool ref { skinlist_set_cfg(i, NULL); if (refresh) + { + skin_defer_rendering(true); skin_update(CUSTOM_STATUSBAR, i, SKIN_REFRESH_ALL); + skin_defer_rendering(false); + } } + if (refresh) + sb_skin_force_next_update(); } static void pop_current_activity_refresh(bool refresh) @@ -1806,8 +1813,14 @@ static void pop_current_activity_refresh(bool refresh) { skinlist_set_cfg(i, NULL); if (refresh) + { + skin_defer_rendering(true); skin_update(CUSTOM_STATUSBAR, i, SKIN_REFRESH_ALL); + skin_defer_rendering(false); + } } + if (refresh) + sb_skin_force_next_update(); } void push_current_activity(enum current_activity screen) diff --git a/apps/plugin.c b/apps/plugin.c index 57f0cb3d97..6c689b21e6 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -1022,8 +1022,11 @@ int plugin_load(const char* plugin, const void* parameter) pop_current_activity_without_refresh(); if (get_current_activity() != ACTIVITY_WPS) { + skin_defer_rendering(true); FOR_NB_SCREENS(i) skin_update(CUSTOM_STATUSBAR, i, SKIN_REFRESH_ALL); + skin_defer_rendering(false); + sb_skin_force_next_update(); } if (!pfn_tsr_exit)