From 7bce19452ee1c9ce1274f5a72950205f1873568a Mon Sep 17 00:00:00 2001 From: o9000 Date: Sun, 10 May 2015 12:43:58 +0200 Subject: [PATCH] Reduce memory footprint --- src/launcher/icon-theme-common.c | 15 ++++- src/launcher/launcher.c | 105 ++++++++++++++++--------------- src/launcher/launcher.h | 3 +- 3 files changed, 66 insertions(+), 57 deletions(-) diff --git a/src/launcher/icon-theme-common.c b/src/launcher/icon-theme-common.c index 331b973..f81d21e 100644 --- a/src/launcher/icon-theme-common.c +++ b/src/launcher/icon-theme-common.c @@ -536,6 +536,9 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size) char *next_larger = NULL; GSList *next_larger_theme = NULL; + int file_name_size = 4096; + char *file_name = calloc(file_name_size, 1); + for (theme = themes; theme; theme = g_slist_next(theme)) { ((IconTheme*)theme->data)->list_directories = g_slist_sort_with_data(((IconTheme*)theme->data)->list_directories, compare_theme_directories, @@ -560,8 +563,13 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size) char *theme_name = ((IconTheme*)theme->data)->name; char *dir_name = ((IconThemeDir*)dir->data)->name; char *extension = (char*) ext->data; - char *file_name = calloc(strlen(base_name) + strlen(theme_name) + - strlen(dir_name) + strlen(icon_name) + strlen(extension) + 100, 1); + if (strlen(base_name) + strlen(theme_name) + + strlen(dir_name) + strlen(icon_name) + strlen(extension) + 100 > file_name_size) { + file_name_size = strlen(base_name) + strlen(theme_name) + + strlen(dir_name) + strlen(icon_name) + strlen(extension) + 100; + file_name = realloc(file_name, file_name_size); + } + file_name[0] = 0; // filename = directory/$(themename)/subdirectory/iconname.extension sprintf(file_name, "%s/%s/%s/%s%s", base_name, theme_name, dir_name, icon_name, extension); if (DEBUG_ICON_SEARCH) @@ -596,11 +604,12 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size) printf("next_larger = %s; next_larger_size = %d\n", next_larger, next_larger_size); } } - free(file_name); } } } } + free(file_name); + file_name = NULL; if (next_larger) { g_slist_free(extensions); free(best_file_name); diff --git a/src/launcher/launcher.c b/src/launcher/launcher.c index f501a7a..7f4fa3f 100644 --- a/src/launcher/launcher.c +++ b/src/launcher/launcher.c @@ -31,6 +31,8 @@ #include #include #include +#include +#include #ifdef HAVE_RSVG #include @@ -150,8 +152,7 @@ void cleanup_launcher_theme(Launcher *launcher) for (l = launcher->list_icons; l ; l = l->next) { LauncherIcon *launcherIcon = (LauncherIcon*)l->data; if (launcherIcon) { - free_icon(launcherIcon->icon_scaled); - free_icon(launcherIcon->icon_original); + free_icon(launcherIcon->image); free(launcherIcon->icon_name); free(launcherIcon->icon_path); free(launcherIcon->cmd); @@ -186,7 +187,7 @@ int resize_launcher(void *obj) // Resize icons if necessary for (l = launcher->list_icons; l ; l = l->next) { LauncherIcon *launcherIcon = (LauncherIcon *)l->data; - if (launcherIcon->icon_size != icon_size || !launcherIcon->icon_original) { + if (launcherIcon->icon_size != icon_size || !launcherIcon->image) { launcherIcon->icon_size = icon_size; launcherIcon->area.width = launcherIcon->icon_size; launcherIcon->area.height = launcherIcon->icon_size; @@ -195,69 +196,69 @@ int resize_launcher(void *obj) char *new_icon_path = get_icon_path(launcher->list_themes, launcherIcon->icon_name, launcherIcon->icon_size); if (!new_icon_path) { // Draw a blank icon - free_icon(launcherIcon->icon_original); - launcherIcon->icon_original = NULL; - free_icon(launcherIcon->icon_scaled); - launcherIcon->icon_scaled = NULL; + free_icon(launcherIcon->image); + launcherIcon->image = NULL; continue; } - if (launcherIcon->icon_path && strcmp(new_icon_path, launcherIcon->icon_path) == 0) { - // If it's the same file just rescale - free_icon(launcherIcon->icon_scaled); - launcherIcon->icon_scaled = scale_icon(launcherIcon->icon_original, icon_size); - free(new_icon_path); - fprintf(stderr, "launcher.c %d: Using icon %s\n", __LINE__, launcherIcon->icon_path); - } else { - // Free the old files - free_icon(launcherIcon->icon_original); - free_icon(launcherIcon->icon_scaled); - launcherIcon->icon_original = launcherIcon->icon_scaled = NULL; - // Load the new file and scale - launcherIcon->icon_original = imlib_load_image_immediately(new_icon_path); + + // Free the old files + free_icon(launcherIcon->image); + launcherIcon->image = NULL; + // Load the new file and scale + launcherIcon->image = imlib_load_image_immediately(new_icon_path); #ifdef HAVE_RSVG - if (!launcherIcon->icon_original && g_str_has_suffix(new_icon_path, ".svg")) { + if (!launcherIcon->image && g_str_has_suffix(new_icon_path, ".svg")) { + char suffix[128]; + sprintf(suffix, "tmpicon-%d.png", getpid()); + // We fork here because librsvg allocates memory like crazy + pid_t pid = fork(); + if (pid == 0) { + // Child GError* err = NULL; RsvgHandle* svg = rsvg_handle_new_from_file(new_icon_path, &err); if (err != NULL) { fprintf(stderr, "Could not load svg image!: %s", err->message); g_error_free(err); - launcherIcon->icon_original = NULL; + launcherIcon->image = NULL; } else { - char suffix[128]; - sprintf(suffix, "tmpicon-%d.png", getpid()); gchar *name = g_build_filename(g_get_user_config_dir(), "tint2", suffix, NULL); GdkPixbuf *pixbuf = rsvg_handle_get_pixbuf(svg); gdk_pixbuf_save(pixbuf, name, "png", NULL, NULL); - launcherIcon->icon_original = imlib_load_image_immediately_without_cache(name); - g_remove(name); - g_free(name); - g_object_unref(G_OBJECT(pixbuf)); - g_object_unref(G_OBJECT(svg)); } - } else -#endif - { - launcherIcon->icon_original = imlib_load_image_immediately(new_icon_path); - } - // On loading error, fallback to default - if (!launcherIcon->icon_original) { - free(new_icon_path); - new_icon_path = get_icon_path(launcher->list_themes, DEFAULT_ICON, launcherIcon->icon_size); - if (new_icon_path) - launcherIcon->icon_original = imlib_load_image_immediately(new_icon_path); - } - - if (!launcherIcon->icon_original) { - // Loading default icon failed, draw a blank icon - free(new_icon_path); + exit(0); } else { - // Loaded icon successfully - launcherIcon->icon_scaled = scale_icon(launcherIcon->icon_original, launcherIcon->icon_size); - free(launcherIcon->icon_path); - launcherIcon->icon_path = new_icon_path; - fprintf(stderr, "launcher.c %d: Using icon %s\n", __LINE__, launcherIcon->icon_path); + // Parent + waitpid(pid, 0, 0); + gchar *name = g_build_filename(g_get_user_config_dir(), "tint2", suffix, NULL); + launcherIcon->image = imlib_load_image_immediately_without_cache(name); + g_remove(name); + g_free(name); } + } else +#endif + { + launcherIcon->image = imlib_load_image_immediately(new_icon_path); + } + // On loading error, fallback to default + if (!launcherIcon->image) { + free(new_icon_path); + new_icon_path = get_icon_path(launcher->list_themes, DEFAULT_ICON, launcherIcon->icon_size); + if (new_icon_path) + launcherIcon->image = imlib_load_image_immediately(new_icon_path); + } + + if (!launcherIcon->image) { + // Loading default icon failed, draw a blank icon + free(new_icon_path); + } else { + // Loaded icon successfully + Imlib_Image original = launcherIcon->image; + launcherIcon->image = scale_icon(launcherIcon->image, launcherIcon->icon_size); + free_icon(original); + free(launcherIcon->icon_path); + launcherIcon->icon_path = new_icon_path; + fprintf(stderr, "launcher.c %d: Using icon %s\n", __LINE__, launcherIcon->icon_path); } } } @@ -331,6 +332,7 @@ int resize_launcher(void *obj) } } } + return 1; } @@ -355,9 +357,8 @@ void draw_launcher_icon(void *obj, cairo_t *c) { LauncherIcon *launcherIcon = (LauncherIcon*)obj; - Imlib_Image icon_scaled = launcherIcon->icon_scaled; // Render - imlib_context_set_image(icon_scaled); + imlib_context_set_image(launcherIcon->image); if (server.real_transparency) { render_image(launcherIcon->area.pix, 0, 0); } else { diff --git a/src/launcher/launcher.h b/src/launcher/launcher.h index 47a341d..4503a69 100644 --- a/src/launcher/launcher.h +++ b/src/launcher/launcher.h @@ -23,8 +23,7 @@ typedef struct Launcher { typedef struct LauncherIcon { // always start with area Area area; - Imlib_Image icon_scaled; - Imlib_Image icon_original; + Imlib_Image image; char *cmd; char *icon_name; char *icon_path;