diff options
| author | Chong Yidong | 2010-05-21 13:29:27 -0400 |
|---|---|---|
| committer | Chong Yidong | 2010-05-21 13:29:27 -0400 |
| commit | 98fe5161c42a5ec64df3d0418f918a5ab8c909d6 (patch) | |
| tree | bd9e7109dcc174cbdcbcb69149b14949c527ffec /src | |
| parent | 6a6dbaceca1daa7f5e86c05eb3e7d4d71dbf40fc (diff) | |
| download | emacs-98fe5161c42a5ec64df3d0418f918a5ab8c909d6.tar.gz emacs-98fe5161c42a5ec64df3d0418f918a5ab8c909d6.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 9 | ||||
| -rw-r--r-- | src/image.c | 70 | ||||
| -rw-r--r-- | src/xdisp.c | 29 |
3 files changed, 75 insertions, 33 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index d74fb712e6d..f0613a57405 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,12 @@ | |||
| 1 | 2010-05-21 Chong Yidong <cyd@stupidchicken.com> | ||
| 2 | |||
| 3 | * xdisp.c (redisplay_internal): Clear caches even if redisplaying | ||
| 4 | just one window. | ||
| 5 | |||
| 6 | * image.c (Vimage_cache_eviction_delay): Decrease to 300. | ||
| 7 | (clear_image_cache): If the number of cached images is unusually | ||
| 8 | large, decrease the cache eviction delay (Bug#6230). | ||
| 9 | |||
| 1 | 2010-05-21 Glenn Morris <rgm@gnu.org> | 10 | 2010-05-21 Glenn Morris <rgm@gnu.org> |
| 2 | 11 | ||
| 3 | * Makefile.in (${ns_appdir}, ${ns_appbindir}Emacs, ns-app): | 12 | * Makefile.in (${ns_appdir}, ${ns_appbindir}Emacs, ns-app): |
diff --git a/src/image.c b/src/image.c index 030e06ad77a..5d4f50ee85e 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -1582,29 +1582,56 @@ clear_image_cache (struct frame *f, Lisp_Object filter) | |||
| 1582 | { | 1582 | { |
| 1583 | struct image_cache *c = FRAME_IMAGE_CACHE (f); | 1583 | struct image_cache *c = FRAME_IMAGE_CACHE (f); |
| 1584 | 1584 | ||
| 1585 | if (c && (!NILP (filter) || INTEGERP (Vimage_cache_eviction_delay))) | 1585 | if (c) |
| 1586 | { | 1586 | { |
| 1587 | EMACS_TIME t; | 1587 | int i, nfreed = 0; |
| 1588 | unsigned long old; | ||
| 1589 | int i, nfreed; | ||
| 1590 | |||
| 1591 | EMACS_GET_TIME (t); | ||
| 1592 | old = EMACS_SECS (t) - XFASTINT (Vimage_cache_eviction_delay); | ||
| 1593 | 1588 | ||
| 1594 | /* Block input so that we won't be interrupted by a SIGIO | 1589 | /* Block input so that we won't be interrupted by a SIGIO |
| 1595 | while being in an inconsistent state. */ | 1590 | while being in an inconsistent state. */ |
| 1596 | BLOCK_INPUT; | 1591 | BLOCK_INPUT; |
| 1597 | 1592 | ||
| 1598 | for (i = nfreed = 0; i < c->used; ++i) | 1593 | if (!NILP (filter)) |
| 1594 | { | ||
| 1595 | /* Filter image cache. */ | ||
| 1596 | for (i = 0; i < c->used; ++i) | ||
| 1597 | { | ||
| 1598 | struct image *img = c->images[i]; | ||
| 1599 | if (img && (EQ (Qt, filter) | ||
| 1600 | || !NILP (Fmember (filter, img->dependencies)))) | ||
| 1601 | { | ||
| 1602 | free_image (f, img); | ||
| 1603 | ++nfreed; | ||
| 1604 | } | ||
| 1605 | } | ||
| 1606 | } | ||
| 1607 | else if (INTEGERP (Vimage_cache_eviction_delay)) | ||
| 1599 | { | 1608 | { |
| 1600 | struct image *img = c->images[i]; | 1609 | /* Free cache based on timestamp. */ |
| 1601 | if (img != NULL | 1610 | EMACS_TIME t; |
| 1602 | && (NILP (filter) ? img->timestamp < old | 1611 | unsigned long old; |
| 1603 | : (EQ (Qt, filter) | 1612 | int delay, nimages = 0; |
| 1604 | || !NILP (Fmember (filter, img->dependencies))))) | 1613 | |
| 1614 | for (i = 0; i < c->used; ++i) | ||
| 1615 | if (c->images[i]) | ||
| 1616 | nimages++; | ||
| 1617 | |||
| 1618 | /* If the number of cached images has grown unusually large, | ||
| 1619 | decrease the cache eviction delay (Bug#6230). */ | ||
| 1620 | delay = XFASTINT (Vimage_cache_eviction_delay); | ||
| 1621 | if (nimages > 40) | ||
| 1622 | delay = max (1, 1600 * delay / (nimages*nimages)); | ||
| 1623 | |||
| 1624 | EMACS_GET_TIME (t); | ||
| 1625 | old = EMACS_SECS (t) - delay; | ||
| 1626 | |||
| 1627 | for (i = 0; i < c->used; ++i) | ||
| 1605 | { | 1628 | { |
| 1606 | free_image (f, img); | 1629 | struct image *img = c->images[i]; |
| 1607 | ++nfreed; | 1630 | if (img && img->timestamp < old) |
| 1631 | { | ||
| 1632 | free_image (f, img); | ||
| 1633 | ++nfreed; | ||
| 1634 | } | ||
| 1608 | } | 1635 | } |
| 1609 | } | 1636 | } |
| 1610 | 1637 | ||
| @@ -8520,11 +8547,14 @@ A cross is always drawn on black & white displays. */); | |||
| 8520 | Vx_bitmap_file_path = decode_env_path ((char *) 0, PATH_BITMAPS); | 8547 | Vx_bitmap_file_path = decode_env_path ((char *) 0, PATH_BITMAPS); |
| 8521 | 8548 | ||
| 8522 | DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay, | 8549 | DEFVAR_LISP ("image-cache-eviction-delay", &Vimage_cache_eviction_delay, |
| 8523 | doc: /* Time after which cached images are removed from the cache. | 8550 | doc: /* Maximum time after which images are removed from the cache. |
| 8524 | When an image has not been displayed this many seconds, remove it | 8551 | When an image has not been displayed this many seconds, Emacs |
| 8525 | from the image cache. Value must be an integer or nil with nil | 8552 | automatically removes it from the image cache. If the cache contains |
| 8526 | meaning don't clear the cache. */); | 8553 | a large number of images, the actual eviction time may be shorter. |
| 8527 | Vimage_cache_eviction_delay = make_number (30 * 60); | 8554 | The value can also be nil, meaning the cache is never cleared. |
| 8555 | |||
| 8556 | The function `clear-image-cache' disregards this variable. */); | ||
| 8557 | Vimage_cache_eviction_delay = make_number (300); | ||
| 8528 | } | 8558 | } |
| 8529 | 8559 | ||
| 8530 | void | 8560 | void |
diff --git a/src/xdisp.c b/src/xdisp.c index 6b3097c9a1a..2ff12730b8a 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -12499,22 +12499,25 @@ redisplay_internal (preserve_echo_area) | |||
| 12499 | if (windows_or_buffers_changed && !pause) | 12499 | if (windows_or_buffers_changed && !pause) |
| 12500 | goto retry; | 12500 | goto retry; |
| 12501 | 12501 | ||
| 12502 | /* Clear the face cache eventually. */ | 12502 | /* Clear the face and image caches. |
| 12503 | if (consider_all_windows_p) | 12503 | |
| 12504 | We used to do this only if consider_all_windows_p. But the cache | ||
| 12505 | needs to be cleared if a timer creates images in the current | ||
| 12506 | buffer (e.g. the test case in Bug#6230). */ | ||
| 12507 | |||
| 12508 | if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT) | ||
| 12504 | { | 12509 | { |
| 12505 | if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT) | 12510 | clear_face_cache (0); |
| 12506 | { | 12511 | clear_face_cache_count = 0; |
| 12507 | clear_face_cache (0); | 12512 | } |
| 12508 | clear_face_cache_count = 0; | 12513 | |
| 12509 | } | ||
| 12510 | #ifdef HAVE_WINDOW_SYSTEM | 12514 | #ifdef HAVE_WINDOW_SYSTEM |
| 12511 | if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT) | 12515 | if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT) |
| 12512 | { | 12516 | { |
| 12513 | clear_image_caches (Qnil); | 12517 | clear_image_caches (Qnil); |
| 12514 | clear_image_cache_count = 0; | 12518 | clear_image_cache_count = 0; |
| 12515 | } | ||
| 12516 | #endif /* HAVE_WINDOW_SYSTEM */ | ||
| 12517 | } | 12519 | } |
| 12520 | #endif /* HAVE_WINDOW_SYSTEM */ | ||
| 12518 | 12521 | ||
| 12519 | end_of_redisplay: | 12522 | end_of_redisplay: |
| 12520 | unbind_to (count, Qnil); | 12523 | unbind_to (count, Qnil); |