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 | |
| 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.
| -rw-r--r-- | doc/lispref/display.texi | 10 | ||||
| -rw-r--r-- | etc/NEWS | 2 | ||||
| -rw-r--r-- | src/dispextern.h | 7 | ||||
| -rw-r--r-- | src/image.c | 50 | ||||
| -rw-r--r-- | src/xdisp.c | 49 | ||||
| -rw-r--r-- | src/xfaces.c | 14 |
6 files changed, 69 insertions, 63 deletions
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index ee3c828857a..c647111047c 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi | |||
| @@ -4364,10 +4364,12 @@ This works by removing all image with image specifications matching | |||
| 4364 | displayed, Emacs will load the image again. | 4364 | displayed, Emacs will load the image again. |
| 4365 | @end defun | 4365 | @end defun |
| 4366 | 4366 | ||
| 4367 | @defun clear-image-cache &optional frame | 4367 | @defun clear-image-cache &optional filter |
| 4368 | This function clears the entire image cache. If @var{frame} is | 4368 | This function clears the image cache. If @var{filter} is |
| 4369 | non-@code{nil}, only the cache for that frame is cleared. Otherwise, | 4369 | a frame, only the cache for that frame is cleared. If omitted or |
| 4370 | all frames' caches are cleared. | 4370 | @code{nil}, clear the images on the selected frame. If @code{t}, |
| 4371 | all frames' caches are cleared. Otherwise, @var{filter} is taken as | ||
| 4372 | a file name and only images that reference this file will be flushed. | ||
| 4371 | @end defun | 4373 | @end defun |
| 4372 | 4374 | ||
| 4373 | If an image in the image cache has not been displayed for a specified | 4375 | If an image in the image cache has not been displayed for a specified |
| @@ -596,6 +596,8 @@ functions and variables (formerly used for Tamil script). | |||
| 596 | 596 | ||
| 597 | * Lisp Changes in Emacs 23.1 | 597 | * Lisp Changes in Emacs 23.1 |
| 598 | 598 | ||
| 599 | ** `clear-image-cache' can be told to flush only images of a specific file. | ||
| 600 | |||
| 599 | ** clone-indirect-buffer now runs the clone-indirect-buffer-hook. | 601 | ** clone-indirect-buffer now runs the clone-indirect-buffer-hook. |
| 600 | 602 | ||
| 601 | ** `beginning-of-defun-function' now takes one argument, the count | 603 | ** `beginning-of-defun-function' now takes one argument, the count |
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)); | |||
| 2818 | void x_kill_gs_process P_ ((Pixmap, struct frame *)); | 2823 | void x_kill_gs_process P_ ((Pixmap, struct frame *)); |
| 2819 | struct image_cache *make_image_cache P_ ((void)); | 2824 | struct image_cache *make_image_cache P_ ((void)); |
| 2820 | void free_image_cache P_ ((struct frame *)); | 2825 | void free_image_cache P_ ((struct frame *)); |
| 2821 | void clear_image_caches P_ ((int)); | 2826 | void clear_image_caches P_ ((Lisp_Object)); |
| 2822 | void mark_image_cache P_ ((struct image_cache *)); | 2827 | void mark_image_cache P_ ((struct image_cache *)); |
| 2823 | int valid_image_p P_ ((Lisp_Object)); | 2828 | int valid_image_p P_ ((Lisp_Object)); |
| 2824 | void prepare_image_for_display P_ ((struct frame *, struct image *)); | 2829 | void 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 | ||
| 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); |
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) |