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.
This commit is contained in:
parent
6a6dbaceca
commit
98fe5161c4
3 changed files with 76 additions and 34 deletions
|
@ -1,3 +1,12 @@
|
|||
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):
|
||||
|
|
70
src/image.c
70
src/image.c
|
@ -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))
|
||||
{
|
||||
struct image *img = c->images[i];
|
||||
if (img != NULL
|
||||
&& (NILP (filter) ? img->timestamp < old
|
||||
: (EQ (Qt, filter)
|
||||
|| !NILP (Fmember (filter, img->dependencies)))))
|
||||
/* Filter image cache. */
|
||||
for (i = 0; i < c->used; ++i)
|
||||
{
|
||||
free_image (f, img);
|
||||
++nfreed;
|
||||
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))
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
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
|
||||
|
|
31
src/xdisp.c
31
src/xdisp.c
|
@ -12499,23 +12499,26 @@ 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;
|
||||
}
|
||||
#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 */
|
||||
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 */
|
||||
|
||||
end_of_redisplay:
|
||||
unbind_to (count, Qnil);
|
||||
RESUME_POLLING;
|
||||
|
|
Loading…
Add table
Reference in a new issue