From 93206ae819c64b9d83d75139eab5dba8e3f1d6f1 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Mon, 6 Jan 2025 07:27:30 +0100 Subject: [PATCH] lab_img: cache and reuse lab_img_data --- include/img/img.h | 8 ++++++ src/img/img.c | 70 ++++++++++++++++++++++++++++++++++++++++------- src/server.c | 2 ++ 3 files changed, 70 insertions(+), 10 deletions(-) diff --git a/include/img/img.h b/include/img/img.h index 5ad7c737..aff8a656 100644 --- a/include/img/img.h +++ b/include/img/img.h @@ -76,4 +76,12 @@ void lab_img_destroy(struct lab_img *img); */ bool lab_img_equal(struct lab_img *img_a, struct lab_img *img_b); +/** + * lab_img_invalidate_cache() - clear cache keys + * + * This should be called on reconfigure so new lab_imgs will not try to + * re-use outdated images which potentially have been changed on disk. + */ +void lab_img_invalidate_cache(void); + #endif /* LABWC_IMG_H */ diff --git a/src/img/img.c b/src/img/img.c index 8a7fe2f5..04960d4e 100644 --- a/src/img/img.c +++ b/src/img/img.c @@ -6,6 +6,7 @@ #include "config.h" #include "common/box.h" #include "common/graphic-helpers.h" +#include "common/list.h" #include "common/macros.h" #include "common/mem.h" #include "common/string-helpers.h" @@ -29,8 +30,16 @@ struct lab_img_data { #if HAVE_RSVG RsvgHandle *svg; /* for SVG image */ #endif + + /* Cache maintenance */ + struct { + char *path; + } cache_key; + struct wl_list link; }; +static struct wl_list img_data_cache = WL_LIST_INIT(&img_data_cache); + static struct lab_img * create_img(struct lab_img_data *img_data) { @@ -48,7 +57,26 @@ lab_img_load(enum lab_img_type type, const char *path, float *xbm_color) return NULL; } - struct lab_img_data *img_data = znew(*img_data); + struct lab_img_data *img_data; + wl_list_for_each(img_data, &img_data_cache, link) { + if (type == LAB_IMG_XBM) { + /* + * XBM is meaningless without also comparing the color. + * TODO: store and compare cache_key.xbm_color + */ + continue; + } + + const char *cache_path = img_data->cache_key.path; + if (!path || !cache_path || strcmp(path, cache_path) != 0) { + continue; + } + assert(type == img_data->type); + wlr_log(WLR_DEBUG, "Using cached image data for %s", path); + return create_img(img_data); + } + + img_data = znew(*img_data); img_data->type = type; switch (type) { @@ -75,6 +103,9 @@ lab_img_load(enum lab_img_type type, const char *path, float *xbm_color) #endif if (img_is_loaded) { + img_data->cache_key.path = xstrdup(path); + wl_list_insert(&img_data_cache, &img_data->link); + wlr_log(WLR_DEBUG, "Using new image data for %s", path); return create_img(img_data); } else { free(img_data); @@ -93,6 +124,7 @@ lab_img_load_from_bitmap(const char *bitmap, float *rgba) struct lab_img_data *img_data = znew(*img_data); img_data->type = LAB_IMG_XBM; img_data->buffer = buffer; + wl_list_insert(&img_data_cache, &img_data->link); return create_img(img_data); } @@ -193,6 +225,32 @@ lab_img_render(struct lab_img *img, int width, int height, int padding, return buffer; } +static void +lab_img_data_destroy(struct lab_img_data *img_data) +{ + assert(img_data->refcount == 0); + if (img_data->buffer) { + wlr_buffer_drop(&img_data->buffer->base); + } +#if HAVE_RSVG + if (img_data->svg) { + g_object_unref(img_data->svg); + } +#endif + wl_list_remove(&img_data->link); + free(img_data->cache_key.path); + free(img_data); +} + +void +lab_img_invalidate_cache(void) +{ + struct lab_img_data *img_data; + wl_list_for_each(img_data, &img_data_cache, link) { + zfree(img_data->cache_key.path); + } +} + void lab_img_destroy(struct lab_img *img) { @@ -202,15 +260,7 @@ lab_img_destroy(struct lab_img *img) img->data->refcount--; if (img->data->refcount == 0) { - if (img->data->buffer) { - wlr_buffer_drop(&img->data->buffer->base); - } -#if HAVE_RSVG - if (img->data->svg) { - g_object_unref(img->data->svg); - } -#endif - free(img->data); + lab_img_data_destroy(img->data); } wl_array_release(&img->modifiers); diff --git a/src/server.c b/src/server.c index e4cf2200..b32fd695 100644 --- a/src/server.c +++ b/src/server.c @@ -40,6 +40,7 @@ #endif #include "idle.h" +#include "img/img.h" #include "input/keyboard.h" #include "labwc.h" #include "layers.h" @@ -71,6 +72,7 @@ reload_config_and_theme(struct server *server) rcxml_finish(); rcxml_read(rc.config_file); theme_finish(server->theme); + lab_img_invalidate_cache(); theme_init(server->theme, server, rc.theme_name); #if HAVE_LIBSFDO