Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

skinengine: Rework skin loading so skins can be un/loaded individually. This also means that loading a .cfg which doesnt change themes shouldnt have them reloaded

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31037 a1c6a512-1295-4272-9138-f99709370657

+175 -140
+34 -22
apps/gui/skin_engine/skin_backdrops.c
··· 37 37 enum screen_type screen; 38 38 bool loaded; 39 39 int buflib_handle; 40 + int ref_count; 40 41 } backdrops[NB_BDROPS]; 41 42 42 43 #define NB_BDROPS SKINNABLE_SCREENS_COUNT*NB_SCREENS ··· 63 64 static bool first_go = true; 64 65 void skin_backdrop_init(void) 65 66 { 66 - for (int i=0; i<NB_BDROPS; i++) 67 + if (first_go) 67 68 { 68 - if (first_go) 69 + for (int i=0; i<NB_BDROPS; i++) 70 + { 69 71 backdrops[i].buflib_handle = -1; 70 - else 71 - skin_backdrop_unload(i); 72 - backdrops[i].name[0] = '\0'; 73 - backdrops[i].buffer = NULL; 74 - backdrops[i].loaded = false; 75 - 72 + backdrops[i].name[0] = '\0'; 73 + backdrops[i].buffer = NULL; 74 + backdrops[i].loaded = false; 75 + backdrops[i].ref_count = 0; 76 + } 77 + FOR_NB_SCREENS(i) 78 + current_lcd_backdrop[i] = -1; 79 + handle_being_loaded = -1; 80 + first_go = false; 76 81 } 77 - first_go = false; 78 - FOR_NB_SCREENS(i) 79 - current_lcd_backdrop[i] = -1; 80 - handle_being_loaded = -1; 81 82 } 82 83 83 84 int skin_backdrop_assign(char* backdrop, char *bmpdir, ··· 101 102 for (i=0; i<NB_BDROPS; i++) 102 103 { 103 104 if (!backdrops[i].name[0] && free < 0) 105 + { 104 106 free = i; 105 - if (!strcmp(backdrops[i].name, filename) && backdrops[i].screen == screen) 107 + break; 108 + } 109 + else if (!strcmp(backdrops[i].name, filename) && backdrops[i].screen == screen) 106 110 { 111 + backdrops[i].ref_count++; 107 112 break; 108 113 } 109 114 } 110 - if (i < NB_BDROPS) 111 - return i; 112 - else if (free >= 0) 115 + if (free >= 0) 113 116 { 114 - strlcpy(backdrops[free].name, filename, 115 - sizeof (backdrops[free].name)); 117 + strlcpy(backdrops[free].name, filename, MAX_PATH); 116 118 backdrops[free].buffer = NULL; 117 119 backdrops[free].screen = screen; 120 + backdrops[free].ref_count = 1; 118 121 return free; 119 122 } 123 + else if (i < NB_BDROPS) 124 + return i; 120 125 return -1; 121 126 } 122 127 ··· 188 193 189 194 void skin_backdrop_unload(int backdrop_id) 190 195 { 191 - if (backdrops[backdrop_id].buflib_handle > 0) 192 - core_free(backdrops[backdrop_id].buflib_handle); 193 - backdrops[backdrop_id].buffer = NULL; 194 - backdrops[backdrop_id].buflib_handle = -1; 196 + backdrops[backdrop_id].ref_count--; 197 + if (backdrops[backdrop_id].ref_count <= 0) 198 + { 199 + if (backdrops[backdrop_id].buflib_handle > 0) 200 + core_free(backdrops[backdrop_id].buflib_handle); 201 + backdrops[backdrop_id].buffer = NULL; 202 + backdrops[backdrop_id].buflib_handle = -1; 203 + backdrops[backdrop_id].loaded = false; 204 + backdrops[backdrop_id].name[0] = '\0'; 205 + backdrops[backdrop_id].ref_count = 0; 206 + } 195 207 } 196 208 197 209 void skin_backdrop_load_setting(void)
+133 -112
apps/gui/skin_engine/skin_engine.c
··· 38 38 #include "skin_buffer.h" 39 39 #include "statusbar-skinned.h" 40 40 41 - static bool skins_initialising = true; 42 - 43 - /* App uses the host malloc to manage the buffer */ 44 - void theme_init_buffer(void) 45 - { 46 - skins_initialising = false; 47 - } 41 + #define FAILSAFENAME "rockbox_failsafe" 48 42 49 43 void skin_data_free_buflib_allocs(struct wps_data *wps_data); 50 44 char* wps_default_skin(enum screen_type screen); 51 45 char* default_radio_skin(enum screen_type screen); 52 46 47 + static char* get_skin_filename(char *buf, size_t buf_size, 48 + enum skinnable_screens skin, enum screen_type screen); 49 + 53 50 struct wps_state wps_state = { .id3 = NULL }; 54 51 static struct gui_skin_helper { 55 52 int (*preproccess)(enum screen_type screen, struct wps_data *data); ··· 62 59 [FM_SCREEN] = { NULL, NULL, default_radio_skin } 63 60 #endif 64 61 }; 65 - 62 + 66 63 static struct gui_skin { 64 + char filename[MAX_PATH]; 67 65 struct gui_wps gui_wps; 68 66 struct wps_data data; 69 67 char *buffer_start; 70 68 size_t buffer_usage; 71 - 69 + bool failsafe_loaded; 70 + 72 71 bool needs_full_update; 73 72 } skins[SKINNABLE_SCREENS_COUNT][NB_SCREENS]; 74 73 75 74 76 - void gui_sync_skin_init(void) 75 + void gui_skin_reset(struct gui_skin *skin) 77 76 { 78 - int j; 79 - for(j=0; j<SKINNABLE_SCREENS_COUNT; j++) 80 - { 81 - FOR_NB_SCREENS(i) 82 - { 83 - skins[j][i].buffer_start = NULL; 84 - skins[j][i].needs_full_update = true; 85 - skins[j][i].gui_wps.data = &skins[j][i].data; 86 - skins[j][i].gui_wps.display = &screens[i]; 87 - memset(skins[j][i].gui_wps.data, 0, sizeof(struct wps_data)); 88 - skins[j][i].data.wps_loaded = false; 89 - skins[j][i].data.buflib_handle = -1; 90 - skins[j][i].data.tree = -1; 77 + skin->filename[0] = '\0'; 78 + skin->buffer_start = NULL; 79 + skin->failsafe_loaded = false; 80 + skin->needs_full_update = true; 81 + skin->gui_wps.data = &skin->data; 82 + memset(skin->gui_wps.data, 0, sizeof(struct wps_data)); 83 + skin->data.wps_loaded = false; 84 + skin->data.buflib_handle = -1; 85 + skin->data.tree = -1; 91 86 #ifdef HAVE_TOUCHSCREEN 92 - skins[j][i].data.touchregions = -1; 87 + skin->data.touchregions = -1; 93 88 #endif 94 89 #ifdef HAVE_SKIN_VARIABLES 95 - skins[j][i].data.skinvars = -1; 90 + skin->data.skinvars = -1; 96 91 #endif 97 92 #ifdef HAVE_LCD_BITMAP 98 - skins[j][i].data.font_ids = -1; 99 - skins[j][i].data.images = -1; 93 + skin->data.font_ids = -1; 94 + skin->data.images = -1; 100 95 #endif 101 96 #ifdef HAVE_ALBUMART 102 - skins[j][i].data.albumart = -1; 103 - skins[j][i].data.playback_aa_slot = -1; 97 + skin->data.albumart = -1; 98 + skin->data.playback_aa_slot = -1; 99 + #endif 100 + #ifdef HAVE_BACKDROP_IMAGE 101 + skin->gui_wps.data->backdrop_id = -1; 104 102 #endif 105 - } 106 - } 107 103 } 108 104 109 - void skin_unload_all(void) 105 + void gui_sync_skin_init(void) 110 106 { 111 107 int j; 112 - 113 108 for(j=0; j<SKINNABLE_SCREENS_COUNT; j++) 114 109 { 115 110 FOR_NB_SCREENS(i) 111 + { 116 112 skin_data_free_buflib_allocs(&skins[j][i].data); 113 + gui_skin_reset(&skins[j][i]); 114 + skins[j][i].gui_wps.display = &screens[i]; 115 + } 117 116 } 117 + } 118 118 119 - #ifdef HAVE_LCD_BITMAP 120 - skin_backdrop_init(); 121 - #endif 119 + void skin_unload_all(void) 120 + { 122 121 gui_sync_skin_init(); 123 122 } 124 123 125 124 void settings_apply_skins(void) 126 125 { 127 126 int i; 127 + char filename[MAX_PATH]; 128 + static bool first_run = true; 128 129 129 - skin_unload_all(); 130 + #ifdef HAVE_LCD_BITMAP 131 + skin_backdrop_init(); 132 + #endif 130 133 /* Make sure each skin is loaded */ 131 134 for (i=0; i<SKINNABLE_SCREENS_COUNT; i++) 132 135 { 133 136 FOR_NB_SCREENS(j) 134 - skin_get_gwps(i, j); 135 - } 137 + { 138 + bool load = false; 139 + get_skin_filename(filename, MAX_PATH, i,j); 140 + 141 + if (filename[0] && (strcmp(filename, skins[i][j].filename) || skins[i][j].failsafe_loaded)) 142 + load = true; 143 + else if (first_run || (!filename[0] && !skins[i][j].failsafe_loaded)) 144 + load = true; 145 + 146 + if (load) 147 + { 148 + if (!first_run) 149 + { 150 + skin_data_free_buflib_allocs(&skins[i][j].data); 136 151 #ifdef HAVE_BACKDROP_IMAGE 137 - skin_backdrops_preload(); /* should maybe check the retval here... */ 152 + if (skins[i][j].data.backdrop_id >= 0) 153 + skin_backdrop_unload(skins[i][j].data.backdrop_id); 138 154 #endif 155 + } 156 + gui_skin_reset(&skins[i][j]); 157 + skins[i][j].gui_wps.display = &screens[j]; 158 + skin_get_gwps(i, j); 159 + } 160 + } 161 + } 162 + first_run = false; 139 163 viewportmanager_theme_changed(THEME_STATUSBAR); 140 164 #ifdef HAVE_BACKDROP_IMAGE 165 + skin_backdrops_preload(); /* should maybe check the retval here... */ 141 166 FOR_NB_SCREENS(i) 142 167 skin_backdrop_show(sb_get_backdrop(i)); 143 168 #endif ··· 147 172 const char *buf, bool isfile) 148 173 { 149 174 bool loaded = false; 150 - 175 + 151 176 if (skin_helpers[skin].preproccess) 152 177 skin_helpers[skin].preproccess(screen, &skins[skin][screen].data); 153 - 178 + 154 179 if (buf && *buf) 155 180 loaded = skin_data_load(screen, &skins[skin][screen].data, buf, isfile); 181 + if (loaded) 182 + strcpy(skins[skin][screen].filename, buf); 156 183 157 184 if (!loaded && skin_helpers[skin].default_skin) 185 + { 158 186 loaded = skin_data_load(screen, &skins[skin][screen].data, 159 187 skin_helpers[skin].default_skin(screen), false); 160 - 188 + skins[skin][screen].failsafe_loaded = loaded; 189 + } 190 + 161 191 skins[skin][screen].needs_full_update = true; 162 192 if (skin_helpers[skin].postproccess) 163 193 skin_helpers[skin].postproccess(screen, &skins[skin][screen].data); 164 194 } 165 195 166 - static bool loading_a_sbs = false; 167 - struct gui_wps *skin_get_gwps(enum skinnable_screens skin, enum screen_type screen) 196 + static char* get_skin_filename(char *buf, size_t buf_size, 197 + enum skinnable_screens skin, enum screen_type screen) 168 198 { 169 - if (!loading_a_sbs && skins[skin][screen].data.wps_loaded == false) 199 + (void)screen; 200 + char *setting = NULL, *ext = NULL; 201 + switch (skin) 170 202 { 171 - char buf[MAX_PATH*2]; 172 - char *setting = NULL, *ext = NULL; 173 - switch (skin) 174 - { 175 - case CUSTOM_STATUSBAR: 176 - #ifdef HAVE_LCD_BITMAP 177 - if (skins_initialising) 178 - { 179 - /* still loading, buffers not initialised yet, 180 - * viewport manager calls into the sbs code, not really 181 - * caring if the sbs has loaded or not, so just return 182 - * the gwps, this is safe. */ 183 - return &skins[skin][screen].gui_wps; 184 - } 185 - /* during the sbs load it will call skin_get_gwps() a few times 186 - * which will eventually stkov the viewportmanager, so make 187 - * sure we don't let that happen */ 188 - loading_a_sbs = true; 203 + case CUSTOM_STATUSBAR: 189 204 #if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1 190 - if (screen == SCREEN_REMOTE) 191 - { 192 - setting = global_settings.rsbs_file; 193 - ext = "rsbs"; 194 - } 195 - else 205 + if (screen == SCREEN_REMOTE) 206 + { 207 + setting = global_settings.rsbs_file; 208 + ext = "rsbs"; 209 + } 210 + else 196 211 #endif 197 - { 198 - setting = global_settings.sbs_file; 199 - ext = "sbs"; 200 - } 201 - #else 202 - return &skins[skin][screen].gui_wps; 203 - #endif /* HAVE_LCD_BITMAP */ 204 - break; 205 - case WPS: 212 + { 213 + setting = global_settings.sbs_file; 214 + ext = "sbs"; 215 + } 216 + break; 217 + case WPS: 206 218 #if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1 207 - if (screen == SCREEN_REMOTE) 208 - { 209 - setting = global_settings.rwps_file; 210 - ext = "rwps"; 211 - } 212 - else 219 + if (screen == SCREEN_REMOTE) 220 + { 221 + setting = global_settings.rwps_file; 222 + ext = "rwps"; 223 + } 224 + else 213 225 #endif 214 - { 215 - setting = global_settings.wps_file; 216 - ext = "wps"; 217 - } 218 - break; 226 + { 227 + setting = global_settings.wps_file; 228 + ext = "wps"; 229 + } 230 + break; 219 231 #if CONFIG_TUNER 220 - case FM_SCREEN: 232 + case FM_SCREEN: 221 233 #if defined(HAVE_REMOTE_LCD) && NB_SCREENS > 1 222 - if (screen == SCREEN_REMOTE) 223 - { 224 - setting = global_settings.rfms_file; 225 - ext = "rfms"; 226 - } 227 - else 234 + if (screen == SCREEN_REMOTE) 235 + { 236 + setting = global_settings.rfms_file; 237 + ext = "rfms"; 238 + } 239 + else 228 240 #endif 229 - { 230 - setting = global_settings.fms_file; 231 - ext = "fms"; 232 - } 233 - break; 241 + { 242 + setting = global_settings.fms_file; 243 + ext = "fms"; 244 + } 245 + break; 234 246 #endif 235 - default: 236 - return NULL; 237 - } 238 - 239 - buf[0] = '\0'; /* force it to reload the default */ 240 - if (strcmp(setting, "rockbox_failsafe")) 241 - { 242 - snprintf(buf, sizeof buf, WPS_DIR "/%s.%s", setting, ext); 243 - } 247 + default: 248 + return NULL; 249 + } 250 + 251 + buf[0] = '\0'; /* force it to reload the default */ 252 + if (strcmp(setting, FAILSAFENAME) && strcmp(setting, "-")) 253 + { 254 + snprintf(buf, buf_size, WPS_DIR "/%s.%s", setting, ext); 255 + } 256 + return buf; 257 + } 258 + 259 + struct gui_wps *skin_get_gwps(enum skinnable_screens skin, enum screen_type screen) 260 + { 261 + if (skins[skin][screen].data.wps_loaded == false) 262 + { 263 + char filename[MAX_PATH]; 264 + char *buf = get_skin_filename(filename, MAX_PATH, skin, screen); 244 265 cpu_boost(true); 266 + skins[skin][screen].filename[0] = '\0'; 245 267 skin_load(skin, screen, buf, true); 246 268 cpu_boost(false); 247 - loading_a_sbs = false; 248 269 } 249 270 return &skins[skin][screen].gui_wps; 250 271 }
+2 -2
apps/gui/skin_engine/skin_parser.c
··· 1687 1687 list = SKINOFFSETTOPTR(skin_buffer, list->next); 1688 1688 } 1689 1689 1690 - #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) 1690 + #ifdef HAVE_BACKDROP_IMAGE 1691 1691 wps_data->backdrop_id = skin_backdrop_assign(backdrop_filename, bmpdir, curr_screen); 1692 1692 #endif /* has backdrop support */ 1693 1693 return retval; ··· 1986 1986 case SKIN_TOKEN_FILE_DIRECTORY: 1987 1987 token->value.i = get_param(element, 0)->data.number; 1988 1988 break; 1989 - #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1)) 1989 + #ifdef HAVE_BACKDROP_IMAGE 1990 1990 case SKIN_TOKEN_VIEWPORT_FGCOLOUR: 1991 1991 case SKIN_TOKEN_VIEWPORT_BGCOLOUR: 1992 1992 function = parse_viewportcolour;
+5
apps/gui/statusbar-skinned.c
··· 50 50 static bool sbs_has_title[NB_SCREENS]; 51 51 static char* sbs_title[NB_SCREENS]; 52 52 static enum themable_icons sbs_icon[NB_SCREENS]; 53 + static bool sbs_loaded[NB_SCREENS] = { false }; 53 54 54 55 bool sb_set_title_text(char* title, enum themable_icons icon, enum screen_type screen) 55 56 { ··· 76 77 int sb_preproccess(enum screen_type screen, struct wps_data *data) 77 78 { 78 79 (void)data; 80 + sbs_loaded[screen] = false; 79 81 sbs_has_title[screen] = false; 80 82 viewportmanager_theme_enable(screen, false, NULL); 81 83 return 1; ··· 101 103 vp->hidden_flags = VP_NEVER_VISIBLE; 102 104 } 103 105 sb_set_info_vp(screen, VP_DEFAULT_LABEL); 106 + sbs_loaded[screen] = true; 104 107 } 105 108 viewportmanager_theme_undo(screen, false); 106 109 return 1; ··· 115 118 116 119 struct viewport *sb_skin_get_info_vp(enum screen_type screen) 117 120 { 121 + if (sbs_loaded[screen] == false) 122 + return NULL; 118 123 struct wps_data *data = skin_get_gwps(CUSTOM_STATUSBAR, screen)->data; 119 124 struct skin_viewport *vp = NULL; 120 125 char *label;
-2
apps/main.c
··· 393 393 tree_mem_init(); 394 394 filetype_init(); 395 395 playlist_init(); 396 - theme_init_buffer(); 397 396 shortcuts_init(); 398 397 399 398 #if CONFIG_CODEC != SWCODEC ··· 678 677 tree_mem_init(); 679 678 filetype_init(); 680 679 scrobbler_init(); 681 - theme_init_buffer(); 682 680 shortcuts_init(); 683 681 684 682 #if CONFIG_CODEC != SWCODEC
-1
apps/settings.h
··· 222 222 * skin buffer is reset properly 223 223 */ 224 224 void settings_apply_skins(void); 225 - void theme_init_buffer(void); 226 225 227 226 void settings_apply(bool read_disk); 228 227 void settings_apply_pm_range(void);
+1 -1
apps/settings_list.c
··· 203 203 /* Default theme settings */ 204 204 #define DEFAULT_WPSNAME "cabbiev2" 205 205 #define DEFAULT_SBSNAME "-" 206 - #define DEFAULT_FMS_NAME DEFAULT_WPSNAME 206 + #define DEFAULT_FMS_NAME "-" 207 207 208 208 #ifdef HAVE_LCD_BITMAP 209 209