gui: simplify screen updates
rockbox-gerrit-noreply--- via rockbox-cvs <[email protected]> Mon, 25 May 2026 07:33:53 -0400
| Newsgroups | gmane.comp.systems.archos.rockbox.cvs |
|---|---|
| Message-ID | <[email protected]> |
commit c0a8303a9c98c87c0a68bb288f0d1664dca9cc31 Author: Christian Soffke <[email protected]> Date: Sun May 24 20:04:28 2026 +0200 gui: simplify screen updates Eliminate the somewhat circuitous skin_defer_rendering and skin_render_deferred functions introduced in commit c145d19e85. skin_render (and thus skin_update and sb_skin_update), along with skinlist_draw, list_draw (and thus gui_synclist_draw), and quickscreen_draw, will never update the screen anymore. Instead, the skin is only marked as dirty now. GUI_EVENT_ACTIONUPDATE redraws the skin as necessary, and updates the screen afterwards, if the skin is dirty. This event is sent from get_action, just like before. A new event, GUI_EVENT_ACTIONREDRAW allows you to redraw the skin without causing an immediate update at the same time. Change-Id: Ib20644853ead901e32f639000f044d6935135bae diff --git a/apps/appevents.h b/apps/appevents.h index 1efd8035e3..2af2c2cb26 100644 --- a/apps/appevents.h +++ b/apps/appevents.h @@ -73,11 +73,13 @@ enum { /** Generic GUI class events **/ enum { - GUI_EVENT_STATUSBAR_TOGGLE = (EVENT_CLASS_GUI|1), + /* Redraw skin as needed (or by force) */ + GUI_EVENT_ACTIONREDRAW = (EVENT_CLASS_GUI|1), + /* Redraw skin, and update the screen if it's dirty */ GUI_EVENT_ACTIONUPDATE, GUI_EVENT_THEME_CHANGED, /* Called when the UI viewport is cleared in the skin engine to - * notify the current screen that it needs to do an update */ + * notify the current screen that it needs to redraw itself */ GUI_EVENT_NEED_UI_UPDATE, }; diff --git a/apps/gui/bitmap/list-skinned.c b/apps/gui/bitmap/list-skinned.c index b9bd18c2d1..505525f3b2 100644 --- a/apps/gui/bitmap/list-skinned.c +++ b/apps/gui/bitmap/list-skinned.c @@ -281,7 +281,6 @@ bool skinlist_draw(struct screen *display, struct gui_synclist *list) } current_column = -1; current_row = -1; - 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 34ae79e316..db18f125e7 100644 --- a/apps/gui/bitmap/list.c +++ b/apps/gui/bitmap/list.c @@ -446,7 +446,6 @@ void list_draw(struct screen *display, struct gui_synclist *list) callback_draw_item(&list_info); } - skin_render_deferred(display, parent); display->set_viewport(last_vp); } diff --git a/apps/gui/list.c b/apps/gui/list.c index f5f02f2cb8..28d4bacc7e 100644 --- a/apps/gui/list.c +++ b/apps/gui/list.c @@ -238,9 +238,9 @@ void gui_synclist_draw(struct gui_synclist *gui_list) { sb_title_is_dirty = theme_enabled = false; - /* tell skin engine to refresh, then call us back */ + /* Redraw skin, and make skin engine call us back */ add_event_ex(GUI_EVENT_NEED_UI_UPDATE, true, sb_title_cb, gui_list); - send_event(GUI_EVENT_ACTIONUPDATE, (void*)1); + send_event(GUI_EVENT_ACTIONREDRAW, (void*)1); remove_event_ex(GUI_EVENT_NEED_UI_UPDATE, sb_title_cb, gui_list); /* sb_title_cb was only called if theme is enabled */ @@ -258,6 +258,7 @@ void gui_synclist_draw(struct gui_synclist *gui_list) { if (!skinlist_draw(&screens[i], gui_list)) list_draw(&screens[i], gui_list); + skin_mark_dirty(i); } } diff --git a/apps/gui/quickscreen.c b/apps/gui/quickscreen.c index b0d74d43a5..3841268023 100644 --- a/apps/gui/quickscreen.c +++ b/apps/gui/quickscreen.c @@ -40,6 +40,7 @@ #include "debug.h" #include "shortcuts.h" #include "appevents.h" +#include "statusbar-skinned.h" /* 1 top, 1 bottom, 2 on either side, 1 for the icons * if enough space, top and bottom have 2 lines */ @@ -233,7 +234,7 @@ static void quickscreen_draw(struct quickscreen *qs, enum screen_type screen) (vp_icons->width/2) - 4, vp_icons->height - 8, 7, 8); } - skin_render_deferred(display, parent); + skin_mark_dirty(display->screen_type); display->set_viewport(last_vp); } @@ -418,13 +419,11 @@ static void quickscreen_run(struct quickscreen * qs) can_quit = true; else if (button == ACTION_QS_VOLUP) { adjust_volume(1); - FOR_NB_SCREENS(i) - skin_update(CUSTOM_STATUSBAR, i, SKIN_REFRESH_NON_STATIC); + sb_skin_force_next_update(); } else if (button == ACTION_QS_VOLDOWN) { adjust_volume(-1); - FOR_NB_SCREENS(i) - skin_update(CUSTOM_STATUSBAR, i, SKIN_REFRESH_NON_STATIC); + sb_skin_force_next_update(); } else if (button == ACTION_STD_CONTEXT) { diff --git a/apps/gui/skin_engine/skin_display.c b/apps/gui/skin_engine/skin_display.c index 2a6f8072ec..4fbe9ac805 100644 --- a/apps/gui/skin_engine/skin_display.c +++ b/apps/gui/skin_engine/skin_display.c @@ -71,8 +71,20 @@ #include "statusbar-skinned.h" #include "skin_display.h" +static bool dirty[NB_SCREENS]; + void skin_render(struct gui_wps *gwps, unsigned refresh_mode); +bool skin_is_dirty(enum screen_type screen) +{ + return dirty[screen] && !(dirty[screen] = false); +} + +void skin_mark_dirty(enum screen_type screen) +{ + dirty[screen] = true; +} + /* update a skinned screen, update_type is WPS_REFRESH_* values. * Usually it should only be WPS_REFRESH_NON_STATIC * A full update will be done if required (skin_do_full_update() == true) @@ -90,6 +102,7 @@ void skin_update(enum skinnable_screens skin, enum screen_type screen, skin_render(gwps, skin_do_full_update(skin, screen) ? SKIN_REFRESH_ALL : update_type); + skin_mark_dirty(screen); } #ifdef AB_REPEAT_ENABLE diff --git a/apps/gui/skin_engine/skin_engine.h b/apps/gui/skin_engine/skin_engine.h index f753dc8087..b819d56773 100644 --- a/apps/gui/skin_engine/skin_engine.h +++ b/apps/gui/skin_engine/skin_engine.h @@ -50,12 +50,8 @@ void skin_disarm_touchregions(struct gui_wps *gwps); /* Do a update_type update of the skinned screen */ 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); - +void skin_mark_dirty(enum screen_type screen); +bool skin_is_dirty(enum screen_type screen); 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 eefbc80ee7..486b7caa0b 100644 --- a/apps/gui/skin_engine/skin_render.c +++ b/apps/gui/skin_engine/skin_render.c @@ -84,8 +84,6 @@ static void skin_render_playlistviewer(struct playlistviewer* viewer, unsigned long refresh_type); static char* skin_buffer; -static bool defer_rendering; -static bool dirty[NB_SCREENS]; static inline struct skin_element* get_child(OFFSETTYPE(struct skin_element**) children, int child) @@ -843,29 +841,6 @@ 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 (defer_rendering) - return; - - if (dirty[display->screen_type]) - { - dirty[display->screen_type] = false; - display->set_viewport(NULL); - display->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); @@ -957,19 +932,14 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode) skin_backdrop_show(data->backdrop_id); #endif - dirty[display->screen_type] = defer_rendering; if (((refresh_mode&SKIN_REFRESH_ALL) == SKIN_REFRESH_ALL)) { - defer_rendering = true; /* If this is the UI viewport then let the UI know * to redraw itself */ send_event(GUI_EVENT_NEED_UI_UPDATE, NULL); - defer_rendering = dirty[display->screen_type]; } /* Restore the default viewport */ display->set_viewport_ex(NULL, VP_FLAG_VP_SET_CLEAN); - if (!defer_rendering) - display->update(); } static __attribute__((noinline)) diff --git a/apps/gui/viewport.c b/apps/gui/viewport.c index 6bc51401f5..0c52b7afe3 100644 --- a/apps/gui/viewport.c +++ b/apps/gui/viewport.c @@ -83,7 +83,7 @@ static void evt_toggle(bool enable, unsigned short id, static void toggle_events(bool enable) { - evt_toggle(enable, GUI_EVENT_ACTIONUPDATE, viewportmanager_redraw); + evt_toggle(enable, GUI_EVENT_ACTIONREDRAW, viewportmanager_redraw); evt_toggle(enable, PLAYBACK_EVENT_TRACK_CHANGE, do_sbs_update_callback); evt_toggle(enable, PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE, do_sbs_update_callback); #if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP) @@ -119,8 +119,7 @@ static void toggle_theme(enum screen_type screen, bool force) { last_vp = screens[screen].set_viewport(NULL); bool first_boot = theme_stack_top[screen] == 0; - /* remove the left overs from the previous screen. - * could cause a tiny flicker. Redo your screen code if that happens */ + /* Remove the left overs from the previous screen */ #ifdef HAVE_BACKDROP_IMAGE skin_backdrop_show(sb_get_backdrop(screen)); #endif @@ -154,9 +153,7 @@ 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); + send_event(GUI_EVENT_ACTIONREDRAW, (void*)force); if (!first_boot) sb_skin_force_next_update(); } @@ -167,6 +164,7 @@ static void toggle_theme(enum screen_type screen, bool force) #endif screens[screen].scroll_stop(); skinlist_set_cfg(screen, NULL); + skin_is_dirty(screen); /* remove dirty flag */ } /* let list initialize viewport in case viewport dimensions is changed. */ send_event(GUI_EVENT_THEME_CHANGED, NULL); @@ -219,10 +217,16 @@ static void viewportmanager_redraw(unsigned short id, void* data) { (void)id; FOR_NB_SCREENS(i) - { if (is_theme_enabled(i)) sb_skin_update(i, NULL != data); - } +} + +static void viewportmanager_update(unsigned short id, void* data) +{ + viewportmanager_redraw(id, data); + FOR_NB_SCREENS(i) + if (skin_is_dirty(i)) + screens[i].update(); } void viewportmanager_init(void) @@ -233,6 +237,7 @@ void viewportmanager_init(void) /* We always want the theme enabled by default... */ viewportmanager_theme_enable(i, true, NULL); } + add_event(GUI_EVENT_ACTIONUPDATE, viewportmanager_update); } void viewportmanager_theme_changed(const int which) diff --git a/apps/gui/wps.c b/apps/gui/wps.c index 99a1f6917e..a5e7ad3029 100644 --- a/apps/gui/wps.c +++ b/apps/gui/wps.c @@ -533,11 +533,7 @@ 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)); } @@ -599,11 +595,7 @@ static void gwps_enter_wps(bool theme_enabled) skin_backdrop_show(gwps->data->backdrop_id); #endif display->clear_display(); - if (skin_has_sbs(gwps)) - skin_defer_rendering(true); skin_update(WPS, i, SKIN_REFRESH_ALL); - skin_defer_rendering(false); - } #ifdef HAVE_TOUCHSCREEN gwps = skin_get_gwps(WPS, SCREEN_MAIN); @@ -611,7 +603,7 @@ static void gwps_enter_wps(bool theme_enabled) if (gwps->data->touchregions < 0) touchscreen_set_mode(TOUCHSCREEN_BUTTON); #endif - /* force statusbar/skin update since we just cleared the whole screen */ + /* Screen was cleared, so redraw SBS if enabled, and update screen */ send_event(GUI_EVENT_ACTIONUPDATE, (void*)1); } diff --git a/apps/misc.c b/apps/misc.c index 7a11afdce1..f54c84beee 100644 --- a/apps/misc.c +++ b/apps/misc.c @@ -1807,11 +1807,7 @@ 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(); @@ -1824,11 +1820,7 @@ 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(); diff --git a/apps/plugin.c b/apps/plugin.c index 98aa34c924..151fd4be4a 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -1023,10 +1023,8 @@ 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); + skin_update(CUSTOM_STATUSBAR, i, SKIN_REFRESH_ALL); sb_skin_force_next_update(); } diff --git a/apps/plugins/disktidy.c b/apps/plugins/disktidy.c index 258ba95217..d2080b3cf1 100644 --- a/apps/plugins/disktidy.c +++ b/apps/plugins/disktidy.c @@ -329,7 +329,7 @@ static enum plugin_status display_run_stats(void) if (sbs_has_title) { #endif - rb->send_event(GUI_EVENT_ACTIONUPDATE, (void*)1); + rb->send_event(GUI_EVENT_ACTIONREDRAW, (void*)1); } rb->viewport_set_defaults(&vp, SCREEN_MAIN); @@ -603,7 +603,7 @@ static enum plugin_status tidy_do(void) sbs_has_title = rb->sb_set_title_text(CLEANING_STR, Icon_NOICON, SCREEN_MAIN); if (sbs_has_title) - rb->send_event(GUI_EVENT_ACTIONUPDATE, (void*)1); + rb->send_event(GUI_EVENT_ACTIONREDRAW, (void*)1); run_stats.files_removed = 0; run_stats.dirs_removed = 0; diff --git a/apps/plugins/lib/simple_viewer.c b/apps/plugins/lib/simple_viewer.c index 27a30ef0b5..3cfe4b020f 100644 --- a/apps/plugins/lib/simple_viewer.c +++ b/apps/plugins/lib/simple_viewer.c @@ -299,9 +299,9 @@ int view_text(const char *title, const char *text) /* handle themes that draw over the UI viewport */ rb->add_event_ex(GUI_EVENT_NEED_UI_UPDATE, false, ui_update_cb, &info); - /* skin engine needs to render title and redraw screen */ + /* skin engine needs to draw title */ if (info.sbs_has_title) - rb->send_event(GUI_EVENT_ACTIONUPDATE, (void*)1); + rb->send_event(GUI_EVENT_ACTIONREDRAW, (void*)1); else draw_text(&info); diff --git a/apps/plugins/text_viewer/tv_window.c b/apps/plugins/text_viewer/tv_window.c index cbef2e0ef7..919f562f0b 100644 --- a/apps/plugins/text_viewer/tv_window.c +++ b/apps/plugins/text_viewer/tv_window.c @@ -57,7 +57,7 @@ static void tv_draw_bookmarks(const struct tv_screen_pos *top_pos) void tv_update_sbs_title(void) { if (tv_set_sbs_title()) - rb->send_event(GUI_EVENT_ACTIONUPDATE, (void*)1); + rb->send_event(GUI_EVENT_ACTIONREDRAW, (void*)1); } void tv_draw_window(void) -- rockbox-cvs mailing list [email protected] https://lists.haxx.se/mailman/listinfo/rockbox-cvs