diff options
| author | Stefan Monnier | 2008-02-24 13:36:39 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2008-02-24 13:36:39 +0000 |
| commit | a2bc5bdd7db3f708b7489d91919336e775c3e6ca (patch) | |
| tree | ca7e9efac023071ffcbeb514ab66fc4c0d76a8b9 /src/image.c | |
| parent | 01dcf28448dab12ad7160942323144836467dd65 (diff) | |
| download | emacs-a2bc5bdd7db3f708b7489d91919336e775c3e6ca.tar.gz emacs-a2bc5bdd7db3f708b7489d91919336e775c3e6ca.zip | |
Allow fine-grained image-cache flushing.
* dispextern.h (struct image): Add `dependencies' field.
(clear_image_caches): Change arg to Lisp_Object.
* image.c (make_image): Initialize `dependencies' field.
(clear_image_cache): Change arg to allow fine-grained flushing.
Perform the flush even if image-cache-eviction-delay is nil.
(clear_image_caches): Change arg to Lisp_Object.
(Fclear_image_cache): Expand meaning of the argument.
(mark_image): Mark `dependencies' field.
* xfaces.c (clear_face_cache): Adapt arg to call to clear_image_caches.
(lface_hash): Use XHASH rather than XFASTINT.
(face_at_buffer_position): Fix int -> EMACS_INT position.
* xdisp.c (next_overlay_change): Fix int -> EMACS_INT position.
(select_frame_for_redisplay): Remove code duplication.
(redisplay_internal): Adapt arg to call to clear_image_caches.
Diffstat (limited to 'src/image.c')
| -rw-r--r-- | src/image.c | 50 |
1 files changed, 28 insertions, 22 deletions
diff --git a/src/image.c b/src/image.c index cce0024e835..81754ca68d2 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -1184,9 +1184,11 @@ make_image (spec, hash) | |||
| 1184 | unsigned hash; | 1184 | unsigned hash; |
| 1185 | { | 1185 | { |
| 1186 | struct image *img = (struct image *) xmalloc (sizeof *img); | 1186 | struct image *img = (struct image *) xmalloc (sizeof *img); |
| 1187 | Lisp_Object file = image_spec_value (spec, QCfile, NULL); | ||
| 1187 | 1188 | ||
| 1188 | xassert (valid_image_p (spec)); | 1189 | xassert (valid_image_p (spec)); |
| 1189 | bzero (img, sizeof *img); | 1190 | bzero (img, sizeof *img); |
| 1191 | img->dependencies = NILP (file) ? Qnil : list1 (file); | ||
| 1190 | img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL)); | 1192 | img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL)); |
| 1191 | xassert (img->type != NULL); | 1193 | xassert (img->type != NULL); |
| 1192 | img->spec = spec; | 1194 | img->spec = spec; |
| @@ -1707,21 +1709,20 @@ free_image_cache (f) | |||
| 1707 | } | 1709 | } |
| 1708 | 1710 | ||
| 1709 | 1711 | ||
| 1710 | /* Clear image cache of frame F. FORCE_P non-zero means free all | 1712 | /* Clear image cache of frame F. FILTER=t means free all images. |
| 1711 | images. FORCE_P zero means clear only images that haven't been | 1713 | FILTER=nil means clear only images that haven't been |
| 1712 | displayed for some time. Should be called from time to time to | 1714 | displayed for some time. |
| 1713 | reduce the number of loaded images. If image-cache-eviction-delay | 1715 | Else, only free the images which have FILTER in their `dependencies'. |
| 1714 | is non-nil, this frees images in the cache which weren't displayed | 1716 | Should be called from time to time to reduce the number of loaded images. |
| 1715 | for at least that many seconds. */ | 1717 | If image-cache-eviction-delay is non-nil, this frees images in the cache |
| 1718 | which weren't displayed for at least that many seconds. */ | ||
| 1716 | 1719 | ||
| 1717 | void | 1720 | void |
| 1718 | clear_image_cache (f, force_p) | 1721 | clear_image_cache (struct frame *f, Lisp_Object filter) |
| 1719 | struct frame *f; | ||
| 1720 | int force_p; | ||
| 1721 | { | 1722 | { |
| 1722 | struct image_cache *c = FRAME_IMAGE_CACHE (f); | 1723 | struct image_cache *c = FRAME_IMAGE_CACHE (f); |
| 1723 | 1724 | ||
| 1724 | if (c && INTEGERP (Vimage_cache_eviction_delay)) | 1725 | if (c && (!NILP (filter) || INTEGERP (Vimage_cache_eviction_delay))) |
| 1725 | { | 1726 | { |
| 1726 | EMACS_TIME t; | 1727 | EMACS_TIME t; |
| 1727 | unsigned long old; | 1728 | unsigned long old; |
| @@ -1738,7 +1739,9 @@ clear_image_cache (f, force_p) | |||
| 1738 | { | 1739 | { |
| 1739 | struct image *img = c->images[i]; | 1740 | struct image *img = c->images[i]; |
| 1740 | if (img != NULL | 1741 | if (img != NULL |
| 1741 | && (force_p || img->timestamp < old)) | 1742 | && (NILP (filter) ? img->timestamp < old |
| 1743 | : (EQ (Qt, filter) | ||
| 1744 | || !NILP (Fmember (filter, img->dependencies))))) | ||
| 1742 | { | 1745 | { |
| 1743 | free_image (f, img); | 1746 | free_image (f, img); |
| 1744 | ++nfreed; | 1747 | ++nfreed; |
| @@ -1768,7 +1771,7 @@ clear_image_cache (f, force_p) | |||
| 1768 | } | 1771 | } |
| 1769 | 1772 | ||
| 1770 | void | 1773 | void |
| 1771 | clear_image_caches (int force_p) | 1774 | clear_image_caches (Lisp_Object filter) |
| 1772 | { | 1775 | { |
| 1773 | /* FIXME: We want to do | 1776 | /* FIXME: We want to do |
| 1774 | * struct terminal *t; | 1777 | * struct terminal *t; |
| @@ -1777,21 +1780,23 @@ clear_image_caches (int force_p) | |||
| 1777 | Lisp_Object tail, frame; | 1780 | Lisp_Object tail, frame; |
| 1778 | FOR_EACH_FRAME (tail, frame) | 1781 | FOR_EACH_FRAME (tail, frame) |
| 1779 | if (FRAME_WINDOW_P (XFRAME (frame))) | 1782 | if (FRAME_WINDOW_P (XFRAME (frame))) |
| 1780 | clear_image_cache (XFRAME (frame), force_p); | 1783 | clear_image_cache (XFRAME (frame), filter); |
| 1781 | } | 1784 | } |
| 1782 | 1785 | ||
| 1783 | DEFUN ("clear-image-cache", Fclear_image_cache, Sclear_image_cache, | 1786 | DEFUN ("clear-image-cache", Fclear_image_cache, Sclear_image_cache, |
| 1784 | 0, 1, 0, | 1787 | 0, 1, 0, |
| 1785 | doc: /* Clear the image cache of FRAME. | 1788 | doc: /* Clear the image cache. |
| 1786 | FRAME nil or omitted means use the selected frame. | 1789 | FILTER nil or a frame means clear all images in the selected frame. |
| 1787 | FRAME t means clear the image caches of all frames. */) | 1790 | FILTER t means clear the image caches of all frames. |
| 1788 | (frame) | 1791 | Anything else, means only clear those images which refer to FILTER, |
| 1789 | Lisp_Object frame; | 1792 | which is then usually a filename. */) |
| 1790 | { | 1793 | (filter) |
| 1791 | if (EQ (frame, Qt)) | 1794 | Lisp_Object filter; |
| 1792 | clear_image_caches (1); | 1795 | { |
| 1796 | if (!(EQ (filter, Qnil) || FRAMEP (filter))) | ||
| 1797 | clear_image_caches (filter); | ||
| 1793 | else | 1798 | else |
| 1794 | clear_image_cache (check_x_frame (frame), 1); | 1799 | clear_image_cache (check_x_frame (filter), Qt); |
| 1795 | 1800 | ||
| 1796 | return Qnil; | 1801 | return Qnil; |
| 1797 | } | 1802 | } |
| @@ -2074,6 +2079,7 @@ mark_image (img) | |||
| 2074 | struct image *img; | 2079 | struct image *img; |
| 2075 | { | 2080 | { |
| 2076 | mark_object (img->spec); | 2081 | mark_object (img->spec); |
| 2082 | mark_object (img->dependencies); | ||
| 2077 | 2083 | ||
| 2078 | if (!NILP (img->data.lisp_val)) | 2084 | if (!NILP (img->data.lisp_val)) |
| 2079 | mark_object (img->data.lisp_val); | 2085 | mark_object (img->data.lisp_val); |