From 904354f93bc9d00501034325a67aa3cb5f863fde Mon Sep 17 00:00:00 2001 From: Brenden Matthews Date: Wed, 3 Jun 2009 13:24:53 -0600 Subject: [PATCH] Added some better cache control options for Imlib2. --- doc/config_settings.xml | 9 +++++++- doc/variables.xml | 4 ++-- src/conky.c | 5 +++++ src/imlib2.c | 48 ++++++++++++++++++++++++++++++++++++++--- src/imlib2.h | 1 + 5 files changed, 61 insertions(+), 6 deletions(-) diff --git a/doc/config_settings.xml b/doc/config_settings.xml index 7b442b4b..101b6b06 100644 --- a/doc/config_settings.xml +++ b/doc/config_settings.xml @@ -179,7 +179,14 @@ - IMLIB2 image cache size, in bytes. Defaults to 4MiB. Increase this value if you use $image lots. Set to 0 to disable the image cache. + Imlib2 image cache size, in bytes. Defaults to 4MiB. Increase this value if you use $image lots. Set to 0 to disable the image cache. + + + + + + + Interval (in seconds) to flush Imlib2 cache. diff --git a/doc/variables.xml b/doc/variables.xml index 748c62f5..75f48a23 100644 --- a/doc/variables.xml +++ b/doc/variables.xml @@ -1046,10 +1046,10 @@ - + - Renders an image from the path specified using IMLIB2. Takes 2 optional arguments, one being a position, the other an size. Changing the x,y position will move the position of the image, and changing the WxH will scale the image. Example: ${image /home/brenden/cheeseburger.jpg -p 20,20 -s 200x200} will render 'cheeseburger.jpg' at (20,20) scaled to 200x200 pixels. Conky does not make any attempt to adjust the position (or any other formatting) of images, they are just rendered as per the arguments passed. The only reason $image is part of the TEXT section, is to allow for runtime modifications, through $execp $lua_parse, $lua_read_parse, or some other method. + Renders an image from the path specified using Imlib2. Takes 4 optional arguments: a position, a size, a no-cache switch, and a cache flush interval. Changing the x,y position will move the position of the image, and changing the WxH will scale the image. If you specify the no-cache flag (-n), the image will not be cached. Alternately, you can specify the -f int switch to specify a cache flust interval for a particular image. Example: ${image /home/brenden/cheeseburger.jpg -p 20,20 -s 200x200} will render 'cheeseburger.jpg' at (20,20) scaled to 200x200 pixels. Conky does not make any attempt to adjust the position (or any other formatting) of images, they are just rendered as per the arguments passed. The only reason $image is part of the TEXT section, is to allow for runtime modifications, through $execp $lua_parse, $lua_read_parse, or some other method. diff --git a/src/conky.c b/src/conky.c index b4deb134..ea37bd3f 100644 --- a/src/conky.c +++ b/src/conky.c @@ -8033,6 +8033,11 @@ static void load_config_file(const char *f) cimlib_set_cache_size(atoi(value)); } } + CONF("imlib_cache_flush_interval") { + if (value) { + cimlib_set_cache_size(atoi(value)); + } + } #endif /* IMLIB2 */ #endif /* X11 */ CONF("update_interval") { diff --git a/src/imlib2.c b/src/imlib2.c index 8f2ef5f8..6b5c1085 100644 --- a/src/imlib2.c +++ b/src/imlib2.c @@ -29,12 +29,16 @@ #include #include #include +#include struct image_list_s { char name[DEFAULT_TEXT_BUFFER_SIZE]; Imlib_Image image; int x, y, w, h; int wh_set; + char no_cache; + int flush_interval; + int flush_last; struct image_list_s *next; }; @@ -47,6 +51,10 @@ Imlib_Image buffer, image; static int cache_size_set = 0; +/* flush the image cache ever X seconds */ +static int cimlib_cache_flush_interval = 0; +static int cimlib_cache_flush_last = 0; + #define DEFAULT_CACHE_SIZE 4096 * 1024 /* default cache size for loaded images */ void cimlib_set_cache_size(long size) @@ -55,6 +63,11 @@ void cimlib_set_cache_size(long size) cache_size_set = 1; } +void cimlib_set_cache_flush_interval(long interval) +{ + cimlib_cache_flush_interval = interval; +} + void cimlib_cleanup(void) { struct image_list_s *cur = image_list_start, *last = NULL; @@ -90,7 +103,7 @@ void cimlib_add_image(const char *args) memset(cur, 0, sizeof(struct image_list_s)); if (!sscanf(args, "%1024s", cur->name)) { - ERR("Invalid args for $image. Format is: ' (-p x,y) (-s WxH)' (got '%s')", args); + ERR("Invalid args for $image. Format is: ' (-p x,y) (-s WxH) (-n) (-f interval)' (got '%s')", args); } to_real_path(cur->name, cur->name); // now we check for optional args @@ -107,6 +120,19 @@ void cimlib_add_image(const char *args) } } + tmp = strstr(args, "-n"); + if (tmp) { + cur->no_cache = 1; + } + + tmp = strstr(args, "-f "); + if (tmp) { + tmp += 3; + if (sscanf(tmp, "%d", &cur->flush_interval)) { + cur->no_cache = 0; + } + } + if (image_list_end) { image_list_end->next = cur; image_list_end = cur; @@ -120,7 +146,8 @@ static void cimlib_draw_image(struct image_list_s *cur, int *clip_x, int *clip_y image = imlib_load_image(cur->name); if (image) { int w, h; - DBGP("Drawing image '%s' at (%i,%i) scaled to %ix%i", cur->name, cur->x, cur->y, cur->w, cur->h); + time_t now = time(NULL); + DBGP("Drawing image '%s' at (%i,%i) scaled to %ix%i, caching interval set to %i (with -n opt %i)", cur->name, cur->x, cur->y, cur->w, cur->h, cur->flush_interval, cur->no_cache); imlib_context_set_image(image); /* turn alpha channel on */ imlib_image_set_has_alpha(1); @@ -134,7 +161,12 @@ static void cimlib_draw_image(struct image_list_s *cur, int *clip_x, int *clip_y imlib_blend_image_onto_image(image, 1, 0, 0, w, h, cur->x, cur->y, cur->w, cur->h); imlib_context_set_image(image); - imlib_free_image(); + if (cur->no_cache || (cur->flush_interval && now - cur->flush_interval > cur->flush_last)) { + imlib_free_image_and_decache(); + cur->flush_last = now; + } else { + imlib_free_image(); + } if (cur->x < *clip_x) *clip_x = cur->x; if (cur->y < *clip_y) *clip_y = cur->y; if (cur->x + cur->w > *clip_x2) *clip_x2 = cur->x + cur->w; @@ -157,8 +189,18 @@ void cimlib_render(int x, int y, int width, int height) { int clip_x = INT_MAX, clip_y = INT_MAX; int clip_x2 = 0, clip_y2 = 0; + time_t now; if (!image_list_start) return; /* are we actually drawing anything? */ + + /* cheque if it's time to flush our cache */ + now = time(NULL); + if (cimlib_cache_flush_interval && now - cimlib_cache_flush_interval > cimlib_cache_flush_last) { + imlib_flush_loaders(); + cimlib_cache_flush_last = now; + DBGP("Flushing Imlib2 cache (%li)\n", now); + } + /* take all the little rectangles to redraw and merge them into * something sane for rendering */ buffer = imlib_create_image(width, height); diff --git a/src/imlib2.h b/src/imlib2.h index 69b9d1cc..9a6e1f8f 100644 --- a/src/imlib2.h +++ b/src/imlib2.h @@ -26,6 +26,7 @@ void cimlib_add_image(const char *name); void cimlib_set_cache_size(long size); +void cimlib_set_cache_flush_interval(long interval); void cimlib_init(Display *display, Window drawable, Visual *visual, Colormap colourmap); void cimlib_render(int x, int y, int width, int height); void cimlib_cleanup(void);