Commit 98fe5161 authored by Chong Yidong's avatar Chong Yidong

Improve image cache clearing logic (Bug#6230).

* xdisp.c (redisplay_internal): Clear caches even if redisplaying
just one window.

* image.c (Vimage_cache_eviction_delay): Decrease to 300.
(clear_image_cache): If the number of cached images is unusually
large, decrease the cache eviction delay.
parent 6a6dbace
2010-05-21 Chong Yidong <cyd@stupidchicken.com>
* xdisp.c (redisplay_internal): Clear caches even if redisplaying
just one window.
* image.c (Vimage_cache_eviction_delay): Decrease to 300.
(clear_image_cache): If the number of cached images is unusually
large, decrease the cache eviction delay (Bug#6230).
2010-05-21 Glenn Morris <rgm@gnu.org>
* Makefile.in (${ns_appdir}, ${ns_appbindir}Emacs, ns-app):
......
......@@ -1582,29 +1582,56 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
{
struct image_cache *c = FRAME_IMAGE_CACHE (f);
if (c && (!NILP (filter) || INTEGERP (Vimage_cache_eviction_delay)))
if (c)
{
EMACS_TIME t;
unsigned long old;
int i, nfreed;
EMACS_GET_TIME (t);
old = EMACS_SECS (t) - XFASTINT (Vimage_cache_eviction_delay);
int i, nfreed = 0;
/* Block input so that we won't be interrupted by a SIGIO
while being in an inconsistent state. */
BLOCK_INPUT;
for (i = nfreed = 0; i < c->used; ++i)
if (!NILP (filter))
{
/* Filter image cache. */
for (i = 0; i < c->used; ++i)
{
struct image *img = c->images[i];
if (img && (EQ (Qt, filter)
|| !NILP (Fmember (filter, img->dependencies))))
{
free_image (f, img);
++nfreed;
}
}
}
else if (INTEGERP (Vimage_cache_eviction_delay))
{
struct image *img = c->images[i];
if (img != NULL
&& (NILP (filter) ? img->timestamp < old
: (EQ (Qt, filter)
|| !NILP (Fmember (filter, img->dependencies)))))
/* Free cache based on timestamp. */
EMACS_TIME t;
unsigned long old;
int delay, nimages = 0;
for (i = 0; i < c->used; ++i)
if (c->images[i])
nimages++;
/* If the number of cached images has grown unusually large,
decrease the cache eviction delay (Bug#6230). */
delay = XFASTINT (Vimage_cache_eviction_delay);
if (nimages > 40)
delay = max (1, 1600 * delay / (nimages*nimages));
EMACS_GET_TIME (t);
old = EMACS_SECS (t) - delay;
for (i = 0; i < c->used; ++i)
{
free_image (f, img);
++nfreed;
struct image *img = c->images[i];
if (img && img->timestamp < old)
{
free_image (f, img);
++nfreed;
}
}
}
......@@ -8520,11 +8547,14 @@ A cross is always drawn on black & white displays. */);
Vx_bitmap_file_path = decode_env_path ((char *) 0, PATH_BITMAPS);
DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay,
doc: /* Time after which cached images are removed from the cache.
When an image has not been displayed this many seconds, remove it
from the image cache. Value must be an integer or nil with nil
meaning don't clear the cache. */);
Vimage_cache_eviction_delay = make_number (30 * 60);
doc: /* Maximum time after which images are removed from the cache.
When an image has not been displayed this many seconds, Emacs
automatically removes it from the image cache. If the cache contains
a large number of images, the actual eviction time may be shorter.
The value can also be nil, meaning the cache is never cleared.
The function `clear-image-cache' disregards this variable. */);
Vimage_cache_eviction_delay = make_number (300);
}
void
......
......@@ -12499,22 +12499,25 @@ redisplay_internal (preserve_echo_area)
if (windows_or_buffers_changed && !pause)
goto retry;
/* Clear the face cache eventually. */
if (consider_all_windows_p)
/* Clear the face and image caches.
We used to do this only if consider_all_windows_p. But the cache
needs to be cleared if a timer creates images in the current
buffer (e.g. the test case in Bug#6230). */
if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
{
if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
{
clear_face_cache (0);
clear_face_cache_count = 0;
}
clear_face_cache (0);
clear_face_cache_count = 0;
}
#ifdef HAVE_WINDOW_SYSTEM
if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
{
clear_image_caches (Qnil);
clear_image_cache_count = 0;
}
#endif /* HAVE_WINDOW_SYSTEM */
if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
{
clear_image_caches (Qnil);
clear_image_cache_count = 0;
}
#endif /* HAVE_WINDOW_SYSTEM */
end_of_redisplay:
unbind_to (count, Qnil);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment