comparison src/image.c @ 92150:1c088baa9d2d

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.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Sun, 24 Feb 2008 13:36:39 +0000
parents 458c8171667a
children 4e76a03232e5
comparison
equal deleted inserted replaced
92149:e8b93cb7392a 92150:1c088baa9d2d
1182 make_image (spec, hash) 1182 make_image (spec, hash)
1183 Lisp_Object spec; 1183 Lisp_Object spec;
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;
1193 img->data.lisp_val = Qnil; 1195 img->data.lisp_val = Qnil;
1194 img->ascent = DEFAULT_IMAGE_ASCENT; 1196 img->ascent = DEFAULT_IMAGE_ASCENT;
1705 FRAME_IMAGE_CACHE (f) = NULL; 1707 FRAME_IMAGE_CACHE (f) = NULL;
1706 } 1708 }
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;
1728 int i, nfreed; 1729 int i, nfreed;
1729 1730
1736 1737
1737 for (i = nfreed = 0; i < c->used; ++i) 1738 for (i = nfreed = 0; i < c->used; ++i)
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;
1745 } 1748 }
1746 } 1749 }
1766 UNBLOCK_INPUT; 1769 UNBLOCK_INPUT;
1767 } 1770 }
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;
1775 * for (t = terminal_list; t; t = t->next_terminal) 1778 * for (t = terminal_list; t; t = t->next_terminal)
1776 * clear_image_cache (t, filter); */ 1779 * clear_image_cache (t, filter); */
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 }
1798 1803
1799 1804
2072 static void 2077 static void
2073 mark_image (img) 2078 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);
2080 } 2086 }
2081 2087