Mercurial > emacs
changeset 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 | e8b93cb7392a |
children | 664a09af03dc |
files | doc/lispref/display.texi etc/NEWS src/dispextern.h src/image.c src/xdisp.c src/xfaces.c |
diffstat | 6 files changed, 69 insertions(+), 63 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/lispref/display.texi Sun Feb 24 13:24:12 2008 +0000 +++ b/doc/lispref/display.texi Sun Feb 24 13:36:39 2008 +0000 @@ -4364,10 +4364,12 @@ displayed, Emacs will load the image again. @end defun -@defun clear-image-cache &optional frame -This function clears the entire image cache. If @var{frame} is -non-@code{nil}, only the cache for that frame is cleared. Otherwise, -all frames' caches are cleared. +@defun clear-image-cache &optional filter +This function clears the image cache. If @var{filter} is +a frame, only the cache for that frame is cleared. If omitted or +@code{nil}, clear the images on the selected frame. If @code{t}, +all frames' caches are cleared. Otherwise, @var{filter} is taken as +a file name and only images that reference this file will be flushed. @end defun If an image in the image cache has not been displayed for a specified
--- a/etc/NEWS Sun Feb 24 13:24:12 2008 +0000 +++ b/etc/NEWS Sun Feb 24 13:36:39 2008 +0000 @@ -596,6 +596,8 @@ * Lisp Changes in Emacs 23.1 +** `clear-image-cache' can be told to flush only images of a specific file. + ** clone-indirect-buffer now runs the clone-indirect-buffer-hook. ** `beginning-of-defun-function' now takes one argument, the count
--- a/src/dispextern.h Sun Feb 24 13:24:12 2008 +0000 +++ b/src/dispextern.h Sun Feb 24 13:36:39 2008 +0000 @@ -2487,6 +2487,11 @@ /* Lisp specification of this image. */ Lisp_Object spec; + /* List of "references" followed to build the image. + Typically will just contain the name of the image file. + Used to allow fine-grained cache flushing. */ + Lisp_Object dependencies; + /* Relief to draw around the image. */ int relief; @@ -2818,7 +2823,7 @@ void x_kill_gs_process P_ ((Pixmap, struct frame *)); struct image_cache *make_image_cache P_ ((void)); void free_image_cache P_ ((struct frame *)); -void clear_image_caches P_ ((int)); +void clear_image_caches P_ ((Lisp_Object)); void mark_image_cache P_ ((struct image_cache *)); int valid_image_p P_ ((Lisp_Object)); void prepare_image_for_display P_ ((struct frame *, struct image *));
--- a/src/image.c Sun Feb 24 13:24:12 2008 +0000 +++ b/src/image.c Sun Feb 24 13:36:39 2008 +0000 @@ -1184,9 +1184,11 @@ unsigned hash; { struct image *img = (struct image *) xmalloc (sizeof *img); + Lisp_Object file = image_spec_value (spec, QCfile, NULL); xassert (valid_image_p (spec)); bzero (img, sizeof *img); + img->dependencies = NILP (file) ? Qnil : list1 (file); img->type = lookup_image_type (image_spec_value (spec, QCtype, NULL)); xassert (img->type != NULL); img->spec = spec; @@ -1707,21 +1709,20 @@ } -/* Clear image cache of frame F. FORCE_P non-zero means free all - images. FORCE_P zero means clear only images that haven't been - displayed for some time. Should be called from time to time to - reduce the number of loaded images. If image-cache-eviction-delay - is non-nil, this frees images in the cache which weren't displayed - for at least that many seconds. */ +/* Clear image cache of frame F. FILTER=t means free all images. + FILTER=nil means clear only images that haven't been + displayed for some time. + Else, only free the images which have FILTER in their `dependencies'. + Should be called from time to time to reduce the number of loaded images. + If image-cache-eviction-delay is non-nil, this frees images in the cache + which weren't displayed for at least that many seconds. */ void -clear_image_cache (f, force_p) - struct frame *f; - int force_p; +clear_image_cache (struct frame *f, Lisp_Object filter) { struct image_cache *c = FRAME_IMAGE_CACHE (f); - if (c && INTEGERP (Vimage_cache_eviction_delay)) + if (c && (!NILP (filter) || INTEGERP (Vimage_cache_eviction_delay))) { EMACS_TIME t; unsigned long old; @@ -1738,7 +1739,9 @@ { struct image *img = c->images[i]; if (img != NULL - && (force_p || img->timestamp < old)) + && (NILP (filter) ? img->timestamp < old + : (EQ (Qt, filter) + || !NILP (Fmember (filter, img->dependencies))))) { free_image (f, img); ++nfreed; @@ -1768,7 +1771,7 @@ } void -clear_image_caches (int force_p) +clear_image_caches (Lisp_Object filter) { /* FIXME: We want to do * struct terminal *t; @@ -1777,21 +1780,23 @@ Lisp_Object tail, frame; FOR_EACH_FRAME (tail, frame) if (FRAME_WINDOW_P (XFRAME (frame))) - clear_image_cache (XFRAME (frame), force_p); + clear_image_cache (XFRAME (frame), filter); } DEFUN ("clear-image-cache", Fclear_image_cache, Sclear_image_cache, 0, 1, 0, - doc: /* Clear the image cache of FRAME. -FRAME nil or omitted means use the selected frame. -FRAME t means clear the image caches of all frames. */) - (frame) - Lisp_Object frame; -{ - if (EQ (frame, Qt)) - clear_image_caches (1); + doc: /* Clear the image cache. +FILTER nil or a frame means clear all images in the selected frame. +FILTER t means clear the image caches of all frames. +Anything else, means only clear those images which refer to FILTER, +which is then usually a filename. */) + (filter) + Lisp_Object filter; +{ + if (!(EQ (filter, Qnil) || FRAMEP (filter))) + clear_image_caches (filter); else - clear_image_cache (check_x_frame (frame), 1); + clear_image_cache (check_x_frame (filter), Qt); return Qnil; } @@ -2074,6 +2079,7 @@ struct image *img; { mark_object (img->spec); + mark_object (img->dependencies); if (!NILP (img->data.lisp_val)) mark_object (img->data.lisp_val);
--- a/src/xdisp.c Sun Feb 24 13:24:12 2008 +0000 +++ b/src/xdisp.c Sun Feb 24 13:36:39 2008 +0000 @@ -3229,7 +3229,7 @@ int pos; { int noverlays; - int endpos; + EMACS_INT endpos; Lisp_Object *overlays; int i; @@ -11042,27 +11042,20 @@ selected_frame = frame; - for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail)) - if (CONSP (XCAR (tail)) - && (sym = XCAR (XCAR (tail)), - SYMBOLP (sym)) - && (sym = indirect_variable (sym), - val = SYMBOL_VALUE (sym), - (BUFFER_LOCAL_VALUEP (val))) - && XBUFFER_LOCAL_VALUE (val)->check_frame) - /* Use find_symbol_value rather than Fsymbol_value - to avoid an error if it is void. */ - find_symbol_value (sym); - - for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail)) - if (CONSP (XCAR (tail)) - && (sym = XCAR (XCAR (tail)), - SYMBOLP (sym)) - && (sym = indirect_variable (sym), - val = SYMBOL_VALUE (sym), - (BUFFER_LOCAL_VALUEP (val))) - && XBUFFER_LOCAL_VALUE (val)->check_frame) - find_symbol_value (sym); + do + { + for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail)) + if (CONSP (XCAR (tail)) + && (sym = XCAR (XCAR (tail)), + SYMBOLP (sym)) + && (sym = indirect_variable (sym), + val = SYMBOL_VALUE (sym), + (BUFFER_LOCAL_VALUEP (val))) + && XBUFFER_LOCAL_VALUE (val)->check_frame) + /* Use find_symbol_value rather than Fsymbol_value + to avoid an error if it is void. */ + find_symbol_value (sym); + } while (!EQ (frame, old) && (frame = old, 1)); } @@ -11797,7 +11790,7 @@ #ifdef HAVE_WINDOW_SYSTEM if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT) { - clear_image_caches (0); + clear_image_caches (Qnil); clear_image_cache_count = 0; } #endif /* HAVE_WINDOW_SYSTEM */ @@ -14426,8 +14419,7 @@ /* Display must not have been paused, otherwise the current matrix is not up to date. */ - if (NILP (w->window_end_valid)) - abort (); + eassert (!NILP (w->window_end_valid)); /* A value of window_end_pos >= END_UNCHANGED means that the window end is in the range of changed text. If so, there is no @@ -14478,8 +14470,7 @@ } } - if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found)) - abort (); + eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found)); return row_found; } @@ -18104,8 +18095,8 @@ goto no_value; } - if (!NILP (w->base_line_number) - && !NILP (w->base_line_pos) + if (INTEGERP (w->base_line_number) + && INTEGERP (w->base_line_pos) && XFASTINT (w->base_line_pos) <= startpos) { line = XFASTINT (w->base_line_number);
--- a/src/xfaces.c Sun Feb 24 13:24:12 2008 +0000 +++ b/src/xfaces.c Sun Feb 24 13:36:39 2008 +0000 @@ -1011,7 +1011,7 @@ if (FRAME_WINDOW_P (f)) clear_face_gcs (FRAME_FACE_CACHE (f)); } - clear_image_caches (0); + clear_image_caches (Qnil); } #endif /* HAVE_WINDOW_SYSTEM */ } @@ -5481,10 +5481,10 @@ return (hash_string_case_insensitive (v[LFACE_FAMILY_INDEX]) ^ hash_string_case_insensitive (v[LFACE_FOREGROUND_INDEX]) ^ hash_string_case_insensitive (v[LFACE_BACKGROUND_INDEX]) - ^ XFASTINT (v[LFACE_WEIGHT_INDEX]) - ^ XFASTINT (v[LFACE_SLANT_INDEX]) - ^ XFASTINT (v[LFACE_SWIDTH_INDEX]) - ^ XFASTINT (v[LFACE_HEIGHT_INDEX])); + ^ XHASH (v[LFACE_WEIGHT_INDEX]) + ^ XHASH (v[LFACE_SLANT_INDEX]) + ^ XHASH (v[LFACE_SWIDTH_INDEX]) + ^ XHASH (v[LFACE_HEIGHT_INDEX])); } @@ -7755,7 +7755,7 @@ font_load_for_face (f, face); else #endif /* USE_FONT_BACKEND */ - load_face_font (f, face); + load_face_font (f, face); if (face->font) face->fontset = make_fontset_for_ascii_face (f, fontset, face); else @@ -8149,7 +8149,7 @@ /* Look at properties from overlays. */ { - int next_overlay; + EMACS_INT next_overlay; GET_OVERLAYS_AT (pos, overlay_vec, noverlays, &next_overlay, 0); if (next_overlay < endpos)