diff options
| author | Lars Ingebrigtsen | 2022-07-14 11:40:49 +0200 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2022-07-14 11:49:47 +0200 |
| commit | 4738aa1e12460ecf55ef08b72c585cbbafe51520 (patch) | |
| tree | 3f385c353f9928689f10f06b7ce5851b5fbfb38d /src | |
| parent | 3ec7b278521c19b435a7168e55ddbdd918817edd (diff) | |
| download | emacs-4738aa1e12460ecf55ef08b72c585cbbafe51520.tar.gz emacs-4738aa1e12460ecf55ef08b72c585cbbafe51520.zip | |
Make clear-image-cache clear the animation cache
* src/dispextern.h: Declare image_prune_animation_caches for use
in gc.
* src/image.c (Fclear_image_cache): Clear animation cache.
(anim_prune_animation_cache, anim_get_animation_cache): Allow
clearing in addition to pruning.
(imagemagick_prune_animation_cache)
(imagemagick_get_animation_cache): Ditto.
(image_prune_animation_caches): New function (bug#56546).
Diffstat (limited to 'src')
| -rw-r--r-- | src/dispextern.h | 1 | ||||
| -rw-r--r-- | src/image.c | 41 |
2 files changed, 30 insertions, 12 deletions
diff --git a/src/dispextern.h b/src/dispextern.h index ca7834dec55..916dba53198 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -3540,6 +3540,7 @@ struct image_cache *make_image_cache (void); | |||
| 3540 | void free_image_cache (struct frame *); | 3540 | void free_image_cache (struct frame *); |
| 3541 | void clear_image_caches (Lisp_Object); | 3541 | void clear_image_caches (Lisp_Object); |
| 3542 | void mark_image_cache (struct image_cache *); | 3542 | void mark_image_cache (struct image_cache *); |
| 3543 | void image_prune_animation_caches (bool); | ||
| 3543 | bool valid_image_p (Lisp_Object); | 3544 | bool valid_image_p (Lisp_Object); |
| 3544 | void prepare_image_for_display (struct frame *, struct image *); | 3545 | void prepare_image_for_display (struct frame *, struct image *); |
| 3545 | ptrdiff_t lookup_image (struct frame *, Lisp_Object, int); | 3546 | ptrdiff_t lookup_image (struct frame *, Lisp_Object, int); |
diff --git a/src/image.c b/src/image.c index c0a7b85cb3b..aa7bb3ba667 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -2133,6 +2133,9 @@ which is then usually a filename. */) | |||
| 2133 | else | 2133 | else |
| 2134 | clear_image_cache (decode_window_system_frame (filter), Qt); | 2134 | clear_image_cache (decode_window_system_frame (filter), Qt); |
| 2135 | 2135 | ||
| 2136 | /* Also clear the animation caches. */ | ||
| 2137 | image_prune_animation_caches (true); | ||
| 2138 | |||
| 2136 | return Qnil; | 2139 | return Qnil; |
| 2137 | } | 2140 | } |
| 2138 | 2141 | ||
| @@ -3046,9 +3049,10 @@ anim_create_cache (Lisp_Object spec) | |||
| 3046 | return cache; | 3049 | return cache; |
| 3047 | } | 3050 | } |
| 3048 | 3051 | ||
| 3049 | /* Discard cached images that haven't been used for a minute. */ | 3052 | /* Discard cached images that haven't been used for a minute. If |
| 3053 | CLEAR, remove all animation cache entries. */ | ||
| 3050 | static void | 3054 | static void |
| 3051 | anim_prune_animation_cache (void) | 3055 | anim_prune_animation_cache (bool clear) |
| 3052 | { | 3056 | { |
| 3053 | struct anim_cache **pcache = &anim_cache; | 3057 | struct anim_cache **pcache = &anim_cache; |
| 3054 | struct timespec old = timespec_sub (current_timespec (), | 3058 | struct timespec old = timespec_sub (current_timespec (), |
| @@ -3057,9 +3061,7 @@ anim_prune_animation_cache (void) | |||
| 3057 | while (*pcache) | 3061 | while (*pcache) |
| 3058 | { | 3062 | { |
| 3059 | struct anim_cache *cache = *pcache; | 3063 | struct anim_cache *cache = *pcache; |
| 3060 | if (timespec_cmp (old, cache->update_time) <= 0) | 3064 | if (clear || timespec_cmp (old, cache->update_time) > 0) |
| 3061 | pcache = &cache->next; | ||
| 3062 | else | ||
| 3063 | { | 3065 | { |
| 3064 | if (cache->handle) | 3066 | if (cache->handle) |
| 3065 | cache->destructor (cache); | 3067 | cache->destructor (cache); |
| @@ -3068,6 +3070,8 @@ anim_prune_animation_cache (void) | |||
| 3068 | *pcache = cache->next; | 3070 | *pcache = cache->next; |
| 3069 | xfree (cache); | 3071 | xfree (cache); |
| 3070 | } | 3072 | } |
| 3073 | else | ||
| 3074 | pcache = &cache->next; | ||
| 3071 | } | 3075 | } |
| 3072 | } | 3076 | } |
| 3073 | 3077 | ||
| @@ -3077,7 +3081,7 @@ anim_get_animation_cache (Lisp_Object spec) | |||
| 3077 | struct anim_cache *cache; | 3081 | struct anim_cache *cache; |
| 3078 | struct anim_cache **pcache = &anim_cache; | 3082 | struct anim_cache **pcache = &anim_cache; |
| 3079 | 3083 | ||
| 3080 | anim_prune_animation_cache (); | 3084 | anim_prune_animation_cache (false); |
| 3081 | 3085 | ||
| 3082 | while (1) | 3086 | while (1) |
| 3083 | { | 3087 | { |
| @@ -10082,9 +10086,10 @@ imagemagick_create_cache (char *signature) | |||
| 10082 | return cache; | 10086 | return cache; |
| 10083 | } | 10087 | } |
| 10084 | 10088 | ||
| 10085 | /* Discard cached images that haven't been used for a minute. */ | 10089 | /* Discard cached images that haven't been used for a minute. If |
| 10090 | CLEAR, discard all cached animated images. */ | ||
| 10086 | static void | 10091 | static void |
| 10087 | imagemagick_prune_animation_cache (void) | 10092 | imagemagick_prune_animation_cache (bool clear) |
| 10088 | { | 10093 | { |
| 10089 | struct animation_cache **pcache = &animation_cache; | 10094 | struct animation_cache **pcache = &animation_cache; |
| 10090 | struct timespec old = timespec_sub (current_timespec (), | 10095 | struct timespec old = timespec_sub (current_timespec (), |
| @@ -10093,15 +10098,15 @@ imagemagick_prune_animation_cache (void) | |||
| 10093 | while (*pcache) | 10098 | while (*pcache) |
| 10094 | { | 10099 | { |
| 10095 | struct animation_cache *cache = *pcache; | 10100 | struct animation_cache *cache = *pcache; |
| 10096 | if (timespec_cmp (old, cache->update_time) <= 0) | 10101 | if (clear || timespec_cmp (old, cache->update_time) > 0) |
| 10097 | pcache = &cache->next; | ||
| 10098 | else | ||
| 10099 | { | 10102 | { |
| 10100 | if (cache->wand) | 10103 | if (cache->wand) |
| 10101 | DestroyMagickWand (cache->wand); | 10104 | DestroyMagickWand (cache->wand); |
| 10102 | *pcache = cache->next; | 10105 | *pcache = cache->next; |
| 10103 | xfree (cache); | 10106 | xfree (cache); |
| 10104 | } | 10107 | } |
| 10108 | else | ||
| 10109 | pcache = &cache->next; | ||
| 10105 | } | 10110 | } |
| 10106 | } | 10111 | } |
| 10107 | 10112 | ||
| @@ -10112,7 +10117,7 @@ imagemagick_get_animation_cache (MagickWand *wand) | |||
| 10112 | struct animation_cache *cache; | 10117 | struct animation_cache *cache; |
| 10113 | struct animation_cache **pcache = &animation_cache; | 10118 | struct animation_cache **pcache = &animation_cache; |
| 10114 | 10119 | ||
| 10115 | imagemagick_prune_animation_cache (); | 10120 | imagemagick_prune_animation_cache (false); |
| 10116 | 10121 | ||
| 10117 | while (1) | 10122 | while (1) |
| 10118 | { | 10123 | { |
| @@ -11951,6 +11956,18 @@ lookup_image_type (Lisp_Object type) | |||
| 11951 | return NULL; | 11956 | return NULL; |
| 11952 | } | 11957 | } |
| 11953 | 11958 | ||
| 11959 | /* Prune the animation caches. If CLEAR, remove all animation cache | ||
| 11960 | entries. */ | ||
| 11961 | void | ||
| 11962 | image_prune_animation_caches (bool clear) | ||
| 11963 | { | ||
| 11964 | #if defined (HAVE_WEBP) || defined (HAVE_GIF) | ||
| 11965 | anim_prune_animation_cache (clear); | ||
| 11966 | #endif | ||
| 11967 | #ifdef HAVE_IMAGEMAGICK | ||
| 11968 | imagemagick_prune_animation_cache (clear); | ||
| 11969 | #endif | ||
| 11970 | } | ||
| 11954 | 11971 | ||
| 11955 | void | 11972 | void |
| 11956 | syms_of_image (void) | 11973 | syms_of_image (void) |