aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Monnier2008-02-24 13:36:39 +0000
committerStefan Monnier2008-02-24 13:36:39 +0000
commita2bc5bdd7db3f708b7489d91919336e775c3e6ca (patch)
treeca7e9efac023071ffcbeb514ab66fc4c0d76a8b9 /src
parent01dcf28448dab12ad7160942323144836467dd65 (diff)
downloademacs-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')
-rw-r--r--src/dispextern.h7
-rw-r--r--src/image.c50
-rw-r--r--src/xdisp.c49
-rw-r--r--src/xfaces.c14
4 files changed, 61 insertions, 59 deletions
diff --git a/src/dispextern.h b/src/dispextern.h
index 9e0e160c5bb..ea5a077d7b2 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2487,6 +2487,11 @@ struct image
2487 /* Lisp specification of this image. */ 2487 /* Lisp specification of this image. */
2488 Lisp_Object spec; 2488 Lisp_Object spec;
2489 2489
2490 /* List of "references" followed to build the image.
2491 Typically will just contain the name of the image file.
2492 Used to allow fine-grained cache flushing. */
2493 Lisp_Object dependencies;
2494
2490 /* Relief to draw around the image. */ 2495 /* Relief to draw around the image. */
2491 int relief; 2496 int relief;
2492 2497
@@ -2818,7 +2823,7 @@ extern Lisp_Object x_find_image_file P_ ((Lisp_Object));
2818void x_kill_gs_process P_ ((Pixmap, struct frame *)); 2823void x_kill_gs_process P_ ((Pixmap, struct frame *));
2819struct image_cache *make_image_cache P_ ((void)); 2824struct image_cache *make_image_cache P_ ((void));
2820void free_image_cache P_ ((struct frame *)); 2825void free_image_cache P_ ((struct frame *));
2821void clear_image_caches P_ ((int)); 2826void clear_image_caches P_ ((Lisp_Object));
2822void mark_image_cache P_ ((struct image_cache *)); 2827void mark_image_cache P_ ((struct image_cache *));
2823int valid_image_p P_ ((Lisp_Object)); 2828int valid_image_p P_ ((Lisp_Object));
2824void prepare_image_for_display P_ ((struct frame *, struct image *)); 2829void prepare_image_for_display P_ ((struct frame *, struct image *));
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
1717void 1720void
1718clear_image_cache (f, force_p) 1721clear_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
1770void 1773void
1771clear_image_caches (int force_p) 1774clear_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
1783DEFUN ("clear-image-cache", Fclear_image_cache, Sclear_image_cache, 1786DEFUN ("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.
1786FRAME nil or omitted means use the selected frame. 1789FILTER nil or a frame means clear all images in the selected frame.
1787FRAME t means clear the image caches of all frames. */) 1790FILTER t means clear the image caches of all frames.
1788 (frame) 1791Anything else, means only clear those images which refer to FILTER,
1789 Lisp_Object frame; 1792which 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);
diff --git a/src/xdisp.c b/src/xdisp.c
index 2006274489c..588d145e9e1 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -3229,7 +3229,7 @@ next_overlay_change (pos)
3229 int pos; 3229 int pos;
3230{ 3230{
3231 int noverlays; 3231 int noverlays;
3232 int endpos; 3232 EMACS_INT endpos;
3233 Lisp_Object *overlays; 3233 Lisp_Object *overlays;
3234 int i; 3234 int i;
3235 3235
@@ -11042,27 +11042,20 @@ select_frame_for_redisplay (frame)
11042 11042
11043 selected_frame = frame; 11043 selected_frame = frame;
11044 11044
11045 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail)) 11045 do
11046 if (CONSP (XCAR (tail)) 11046 {
11047 && (sym = XCAR (XCAR (tail)), 11047 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
11048 SYMBOLP (sym)) 11048 if (CONSP (XCAR (tail))
11049 && (sym = indirect_variable (sym), 11049 && (sym = XCAR (XCAR (tail)),
11050 val = SYMBOL_VALUE (sym), 11050 SYMBOLP (sym))
11051 (BUFFER_LOCAL_VALUEP (val))) 11051 && (sym = indirect_variable (sym),
11052 && XBUFFER_LOCAL_VALUE (val)->check_frame) 11052 val = SYMBOL_VALUE (sym),
11053 /* Use find_symbol_value rather than Fsymbol_value 11053 (BUFFER_LOCAL_VALUEP (val)))
11054 to avoid an error if it is void. */ 11054 && XBUFFER_LOCAL_VALUE (val)->check_frame)
11055 find_symbol_value (sym); 11055 /* Use find_symbol_value rather than Fsymbol_value
11056 11056 to avoid an error if it is void. */
11057 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail)) 11057 find_symbol_value (sym);
11058 if (CONSP (XCAR (tail)) 11058 } while (!EQ (frame, old) && (frame = old, 1));
11059 && (sym = XCAR (XCAR (tail)),
11060 SYMBOLP (sym))
11061 && (sym = indirect_variable (sym),
11062 val = SYMBOL_VALUE (sym),
11063 (BUFFER_LOCAL_VALUEP (val)))
11064 && XBUFFER_LOCAL_VALUE (val)->check_frame)
11065 find_symbol_value (sym);
11066} 11059}
11067 11060
11068 11061
@@ -11797,7 +11790,7 @@ redisplay_internal (preserve_echo_area)
11797#ifdef HAVE_WINDOW_SYSTEM 11790#ifdef HAVE_WINDOW_SYSTEM
11798 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT) 11791 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
11799 { 11792 {
11800 clear_image_caches (0); 11793 clear_image_caches (Qnil);
11801 clear_image_cache_count = 0; 11794 clear_image_cache_count = 0;
11802 } 11795 }
11803#endif /* HAVE_WINDOW_SYSTEM */ 11796#endif /* HAVE_WINDOW_SYSTEM */
@@ -14426,8 +14419,7 @@ find_first_unchanged_at_end_row (w, delta, delta_bytes)
14426 14419
14427 /* Display must not have been paused, otherwise the current matrix 14420 /* Display must not have been paused, otherwise the current matrix
14428 is not up to date. */ 14421 is not up to date. */
14429 if (NILP (w->window_end_valid)) 14422 eassert (!NILP (w->window_end_valid));
14430 abort ();
14431 14423
14432 /* A value of window_end_pos >= END_UNCHANGED means that the window 14424 /* A value of window_end_pos >= END_UNCHANGED means that the window
14433 end is in the range of changed text. If so, there is no 14425 end is in the range of changed text. If so, there is no
@@ -14478,8 +14470,7 @@ find_first_unchanged_at_end_row (w, delta, delta_bytes)
14478 } 14470 }
14479 } 14471 }
14480 14472
14481 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found)) 14473 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
14482 abort ();
14483 14474
14484 return row_found; 14475 return row_found;
14485} 14476}
@@ -18104,8 +18095,8 @@ decode_mode_spec (w, c, field_width, precision, multibyte, string)
18104 goto no_value; 18095 goto no_value;
18105 } 18096 }
18106 18097
18107 if (!NILP (w->base_line_number) 18098 if (INTEGERP (w->base_line_number)
18108 && !NILP (w->base_line_pos) 18099 && INTEGERP (w->base_line_pos)
18109 && XFASTINT (w->base_line_pos) <= startpos) 18100 && XFASTINT (w->base_line_pos) <= startpos)
18110 { 18101 {
18111 line = XFASTINT (w->base_line_number); 18102 line = XFASTINT (w->base_line_number);
diff --git a/src/xfaces.c b/src/xfaces.c
index d160d9e8c29..897d8383a49 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -1011,7 +1011,7 @@ clear_face_cache (clear_fonts_p)
1011 if (FRAME_WINDOW_P (f)) 1011 if (FRAME_WINDOW_P (f))
1012 clear_face_gcs (FRAME_FACE_CACHE (f)); 1012 clear_face_gcs (FRAME_FACE_CACHE (f));
1013 } 1013 }
1014 clear_image_caches (0); 1014 clear_image_caches (Qnil);
1015 } 1015 }
1016#endif /* HAVE_WINDOW_SYSTEM */ 1016#endif /* HAVE_WINDOW_SYSTEM */
1017} 1017}
@@ -5481,10 +5481,10 @@ lface_hash (v)
5481 return (hash_string_case_insensitive (v[LFACE_FAMILY_INDEX]) 5481 return (hash_string_case_insensitive (v[LFACE_FAMILY_INDEX])
5482 ^ hash_string_case_insensitive (v[LFACE_FOREGROUND_INDEX]) 5482 ^ hash_string_case_insensitive (v[LFACE_FOREGROUND_INDEX])
5483 ^ hash_string_case_insensitive (v[LFACE_BACKGROUND_INDEX]) 5483 ^ hash_string_case_insensitive (v[LFACE_BACKGROUND_INDEX])
5484 ^ XFASTINT (v[LFACE_WEIGHT_INDEX]) 5484 ^ XHASH (v[LFACE_WEIGHT_INDEX])
5485 ^ XFASTINT (v[LFACE_SLANT_INDEX]) 5485 ^ XHASH (v[LFACE_SLANT_INDEX])
5486 ^ XFASTINT (v[LFACE_SWIDTH_INDEX]) 5486 ^ XHASH (v[LFACE_SWIDTH_INDEX])
5487 ^ XFASTINT (v[LFACE_HEIGHT_INDEX])); 5487 ^ XHASH (v[LFACE_HEIGHT_INDEX]));
5488} 5488}
5489 5489
5490 5490
@@ -7755,7 +7755,7 @@ realize_x_face (cache, attrs)
7755 font_load_for_face (f, face); 7755 font_load_for_face (f, face);
7756 else 7756 else
7757#endif /* USE_FONT_BACKEND */ 7757#endif /* USE_FONT_BACKEND */
7758 load_face_font (f, face); 7758 load_face_font (f, face);
7759 if (face->font) 7759 if (face->font)
7760 face->fontset = make_fontset_for_ascii_face (f, fontset, face); 7760 face->fontset = make_fontset_for_ascii_face (f, fontset, face);
7761 else 7761 else
@@ -8149,7 +8149,7 @@ face_at_buffer_position (w, pos, region_beg, region_end,
8149 8149
8150 /* Look at properties from overlays. */ 8150 /* Look at properties from overlays. */
8151 { 8151 {
8152 int next_overlay; 8152 EMACS_INT next_overlay;
8153 8153
8154 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, &next_overlay, 0); 8154 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, &next_overlay, 0);
8155 if (next_overlay < endpos) 8155 if (next_overlay < endpos)