diff options
| author | Po Lu | 2024-06-20 17:03:36 +0800 |
|---|---|---|
| committer | Po Lu | 2024-06-20 17:03:36 +0800 |
| commit | cebca072c33937b84995a62c35c16441d23bb86d (patch) | |
| tree | e1bf28f6453a63a4d0eafa4757e4f65230e2338f /src | |
| parent | 374f4235d5e78def23d92b05f3d0257c1f609725 (diff) | |
| download | emacs-cebca072c33937b84995a62c35c16441d23bb86d.tar.gz emacs-cebca072c33937b84995a62c35c16441d23bb86d.zip | |
Correctly cache images when frames vary in their font metrics
* src/alloc.c (mark_frame): Mark this frame's image cache, if it
exist.
(mark_terminals): Cease marking T->image_cache.
* src/androidfns.c (unwind_create_frame, Fx_create_frame)
(android_create_tip_frame):
* src/haikufns.c (unwind_create_frame, haiku_create_frame)
(haiku_create_tip_frame):
* src/nsfns.m (unwind_create_frame):
* src/pgtkfns.c (unwind_create_frame, Fx_create_frame)
(x_create_tip_frame):
* src/xfns.c (unwind_create_frame, Fx_create_frame)
(x_create_tip_frame):
* src/w32fns.c (unwind_create_frame, Fx_create_frame)
(w32_create_tip_frame): Remove adjustments of the frame image
cache's reference count rendered redundant by the assignment of
image caches to individual frames rather than terminals.
* src/dispextern.h (struct image_cache) <scaling_col_width>: New
field.
* src/frame.c (gui_set_font): In lieu of clearing F's image
cache unconditionally, establish whether the column width as
considered by compute_image_size has changed, and if so, adjust
or reassign the frame's image cache.
(make_frame): Clear F->image_cache.
* src/frame.h (struct frame) <image_cache>: New field.
(FRAME_IMAGE_CACHE): Return F->image_cache.
* src/image.c (make_image_cache): Clear C->scaling_col_width.
(cache_image): Adjust to new means of assigning image caches to
frames.
* src/termhooks.h (struct terminal) <image_cache>: Delete field.
* src/xfaces.c (init_frame_faces): Do image cache assignment
with all new frames.
Diffstat (limited to 'src')
| -rw-r--r-- | src/alloc.c | 13 | ||||
| -rw-r--r-- | src/androidfns.c | 21 | ||||
| -rw-r--r-- | src/dispextern.h | 8 | ||||
| -rw-r--r-- | src/frame.c | 34 | ||||
| -rw-r--r-- | src/frame.h | 8 | ||||
| -rw-r--r-- | src/haikufns.c | 30 | ||||
| -rw-r--r-- | src/image.c | 7 | ||||
| -rw-r--r-- | src/nsfns.m | 23 | ||||
| -rw-r--r-- | src/pgtkfns.c | 19 | ||||
| -rw-r--r-- | src/termhooks.h | 5 | ||||
| -rw-r--r-- | src/w32fns.c | 20 | ||||
| -rw-r--r-- | src/xfaces.c | 39 | ||||
| -rw-r--r-- | src/xfns.c | 25 |
13 files changed, 92 insertions, 160 deletions
diff --git a/src/alloc.c b/src/alloc.c index 9304e4e42bb..666f77bfce1 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -7055,6 +7055,13 @@ mark_frame (struct Lisp_Vector *ptr) | |||
| 7055 | for (tem = f->conversion.actions; tem; tem = tem->next) | 7055 | for (tem = f->conversion.actions; tem; tem = tem->next) |
| 7056 | mark_object (tem->data); | 7056 | mark_object (tem->data); |
| 7057 | #endif | 7057 | #endif |
| 7058 | |||
| 7059 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 7060 | /* Mark this frame's image cache, though it might be common to several | ||
| 7061 | frames with the same font size. */ | ||
| 7062 | if (FRAME_IMAGE_CACHE (f)) | ||
| 7063 | mark_image_cache (FRAME_IMAGE_CACHE (f)); | ||
| 7064 | #endif /* HAVE_WINDOW_SYSTEM */ | ||
| 7058 | } | 7065 | } |
| 7059 | 7066 | ||
| 7060 | static void | 7067 | static void |
| @@ -7515,12 +7522,6 @@ mark_terminals (void) | |||
| 7515 | for (t = terminal_list; t; t = t->next_terminal) | 7522 | for (t = terminal_list; t; t = t->next_terminal) |
| 7516 | { | 7523 | { |
| 7517 | eassert (t->name != NULL); | 7524 | eassert (t->name != NULL); |
| 7518 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 7519 | /* If a terminal object is reachable from a stacpro'ed object, | ||
| 7520 | it might have been marked already. Make sure the image cache | ||
| 7521 | gets marked. */ | ||
| 7522 | mark_image_cache (t->image_cache); | ||
| 7523 | #endif /* HAVE_WINDOW_SYSTEM */ | ||
| 7524 | if (!vectorlike_marked_p (&t->header)) | 7525 | if (!vectorlike_marked_p (&t->header)) |
| 7525 | mark_vectorlike (&t->header); | 7526 | mark_vectorlike (&t->header); |
| 7526 | } | 7527 | } |
diff --git a/src/androidfns.c b/src/androidfns.c index 84558350dc0..7595e176618 100644 --- a/src/androidfns.c +++ b/src/androidfns.c | |||
| @@ -32,9 +32,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 32 | 32 | ||
| 33 | #ifndef ANDROID_STUBIFY | 33 | #ifndef ANDROID_STUBIFY |
| 34 | 34 | ||
| 35 | /* Some kind of reference count for the image cache. */ | ||
| 36 | static ptrdiff_t image_cache_refcount; | ||
| 37 | |||
| 38 | /* The frame of the currently visible tooltip, or nil if none. */ | 35 | /* The frame of the currently visible tooltip, or nil if none. */ |
| 39 | static Lisp_Object tip_frame; | 36 | static Lisp_Object tip_frame; |
| 40 | 37 | ||
| @@ -654,17 +651,6 @@ unwind_create_frame (Lisp_Object frame) | |||
| 654 | /* If frame is ``official'', nothing to do. */ | 651 | /* If frame is ``official'', nothing to do. */ |
| 655 | if (NILP (Fmemq (frame, Vframe_list))) | 652 | if (NILP (Fmemq (frame, Vframe_list))) |
| 656 | { | 653 | { |
| 657 | /* If the frame's image cache refcount is still the same as our | ||
| 658 | private shadow variable, it means we are unwinding a frame | ||
| 659 | for which we didn't yet call init_frame_faces, where the | ||
| 660 | refcount is incremented. Therefore, we increment it here, so | ||
| 661 | that free_frame_faces, called in x_free_frame_resources | ||
| 662 | below, will not mistakenly decrement the counter that was not | ||
| 663 | incremented yet to account for this new frame. */ | ||
| 664 | if (FRAME_IMAGE_CACHE (f) != NULL | ||
| 665 | && FRAME_IMAGE_CACHE (f)->refcount == image_cache_refcount) | ||
| 666 | FRAME_IMAGE_CACHE (f)->refcount++; | ||
| 667 | |||
| 668 | android_free_frame_resources (f); | 654 | android_free_frame_resources (f); |
| 669 | free_glyphs (f); | 655 | free_glyphs (f); |
| 670 | return Qt; | 656 | return Qt; |
| @@ -944,10 +930,6 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, | |||
| 944 | register_font_driver (&androidfont_driver, f); | 930 | register_font_driver (&androidfont_driver, f); |
| 945 | register_font_driver (&android_sfntfont_driver, f); | 931 | register_font_driver (&android_sfntfont_driver, f); |
| 946 | 932 | ||
| 947 | image_cache_refcount = (FRAME_IMAGE_CACHE (f) | ||
| 948 | ? FRAME_IMAGE_CACHE (f)->refcount | ||
| 949 | : 0); | ||
| 950 | |||
| 951 | gui_default_parameter (f, parms, Qfont_backend, Qnil, | 933 | gui_default_parameter (f, parms, Qfont_backend, Qnil, |
| 952 | "fontBackend", "FontBackend", RES_TYPE_STRING); | 934 | "fontBackend", "FontBackend", RES_TYPE_STRING); |
| 953 | 935 | ||
| @@ -2023,9 +2005,6 @@ android_create_tip_frame (struct android_display_info *dpyinfo, | |||
| 2023 | register_font_driver (&androidfont_driver, f); | 2005 | register_font_driver (&androidfont_driver, f); |
| 2024 | register_font_driver (&android_sfntfont_driver, f); | 2006 | register_font_driver (&android_sfntfont_driver, f); |
| 2025 | 2007 | ||
| 2026 | image_cache_refcount | ||
| 2027 | = FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; | ||
| 2028 | |||
| 2029 | gui_default_parameter (f, parms, Qfont_backend, Qnil, | 2008 | gui_default_parameter (f, parms, Qfont_backend, Qnil, |
| 2030 | "fontBackend", "FontBackend", RES_TYPE_STRING); | 2009 | "fontBackend", "FontBackend", RES_TYPE_STRING); |
| 2031 | 2010 | ||
diff --git a/src/dispextern.h b/src/dispextern.h index 35e1893c83c..85012130689 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -3292,6 +3292,11 @@ struct image_cache | |||
| 3292 | 3292 | ||
| 3293 | /* Reference count (number of frames sharing this cache). */ | 3293 | /* Reference count (number of frames sharing this cache). */ |
| 3294 | ptrdiff_t refcount; | 3294 | ptrdiff_t refcount; |
| 3295 | |||
| 3296 | /* Column width by which images whose QCscale property is Qdefault | ||
| 3297 | will be scaled, which is 10 or FRAME_COLUMN_WIDTH of each frame | ||
| 3298 | assigned this image cache, whichever is greater. */ | ||
| 3299 | int scaling_col_width; | ||
| 3295 | }; | 3300 | }; |
| 3296 | 3301 | ||
| 3297 | /* Size of bucket vector of image caches. Should be prime. */ | 3302 | /* Size of bucket vector of image caches. Should be prime. */ |
| @@ -3708,6 +3713,9 @@ int smaller_face (struct frame *, int, int); | |||
| 3708 | int face_with_height (struct frame *, int, int); | 3713 | int face_with_height (struct frame *, int, int); |
| 3709 | int lookup_derived_face (struct window *, struct frame *, | 3714 | int lookup_derived_face (struct window *, struct frame *, |
| 3710 | Lisp_Object, int, bool); | 3715 | Lisp_Object, int, bool); |
| 3716 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 3717 | extern struct image_cache *share_image_cache (struct frame *f); | ||
| 3718 | #endif /* HAVE_WINDOW_SYSTEM */ | ||
| 3711 | void init_frame_faces (struct frame *); | 3719 | void init_frame_faces (struct frame *); |
| 3712 | void free_frame_faces (struct frame *); | 3720 | void free_frame_faces (struct frame *); |
| 3713 | void recompute_basic_faces (struct frame *); | 3721 | void recompute_basic_faces (struct frame *); |
diff --git a/src/frame.c b/src/frame.c index 25620217680..1bb92e1f9b0 100644 --- a/src/frame.c +++ b/src/frame.c | |||
| @@ -983,6 +983,8 @@ make_frame (bool mini_p) | |||
| 983 | f->tooltip = false; | 983 | f->tooltip = false; |
| 984 | f->was_invisible = false; | 984 | f->was_invisible = false; |
| 985 | f->child_frame_border_width = -1; | 985 | f->child_frame_border_width = -1; |
| 986 | f->face_caches = NULL; | ||
| 987 | f->image_cache = NULL; | ||
| 986 | f->last_tab_bar_item = -1; | 988 | f->last_tab_bar_item = -1; |
| 987 | #ifndef HAVE_EXT_TOOL_BAR | 989 | #ifndef HAVE_EXT_TOOL_BAR |
| 988 | f->last_tool_bar_item = -1; | 990 | f->last_tool_bar_item = -1; |
| @@ -4732,7 +4734,7 @@ void | |||
| 4732 | gui_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval) | 4734 | gui_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval) |
| 4733 | { | 4735 | { |
| 4734 | Lisp_Object font_object; | 4736 | Lisp_Object font_object; |
| 4735 | int fontset = -1; | 4737 | int fontset = -1, iwidth; |
| 4736 | 4738 | ||
| 4737 | /* Set the frame parameter back to the old value because we may | 4739 | /* Set the frame parameter back to the old value because we may |
| 4738 | fail to use ARG as the new parameter value. */ | 4740 | fail to use ARG as the new parameter value. */ |
| @@ -4811,9 +4813,33 @@ gui_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval) | |||
| 4811 | /* Recalculate toolbar height. */ | 4813 | /* Recalculate toolbar height. */ |
| 4812 | f->n_tool_bar_rows = 0; | 4814 | f->n_tool_bar_rows = 0; |
| 4813 | 4815 | ||
| 4814 | /* Clean F's image cache of images whose values derive from the font | 4816 | /* Re-initialize F's image cache. Since `set_new_font_hook' might |
| 4815 | width. */ | 4817 | have changed the frame's column width, by which images are scaled, |
| 4816 | clear_image_cache (f, Qauto); | 4818 | it might likewise need to be assigned a different image cache, or |
| 4819 | have its existing cache adjusted, if by coincidence it is its sole | ||
| 4820 | user. */ | ||
| 4821 | |||
| 4822 | iwidth = max (10, FRAME_COLUMN_WIDTH (f)); | ||
| 4823 | if (FRAME_IMAGE_CACHE (f) | ||
| 4824 | && (iwidth != FRAME_IMAGE_CACHE (f)->scaling_col_width)) | ||
| 4825 | { | ||
| 4826 | eassert (FRAME_IMAGE_CACHE (f)->refcount >= 1); | ||
| 4827 | if (FRAME_IMAGE_CACHE (f)->refcount == 1) | ||
| 4828 | { | ||
| 4829 | /* This frame is the only user of this image cache. */ | ||
| 4830 | FRAME_IMAGE_CACHE (f)->scaling_col_width = iwidth; | ||
| 4831 | /* Clean F's image cache of images whose values are derived | ||
| 4832 | from the font width. */ | ||
| 4833 | clear_image_cache (f, Qauto); | ||
| 4834 | } | ||
| 4835 | else | ||
| 4836 | { | ||
| 4837 | /* Release the current image cache, and reuse or allocate a | ||
| 4838 | new image cache with IWIDTH. */ | ||
| 4839 | FRAME_IMAGE_CACHE (f)->refcount--; | ||
| 4840 | FRAME_IMAGE_CACHE (f) = share_image_cache (f); | ||
| 4841 | } | ||
| 4842 | } | ||
| 4817 | 4843 | ||
| 4818 | /* Ensure we redraw it. */ | 4844 | /* Ensure we redraw it. */ |
| 4819 | clear_current_matrices (f); | 4845 | clear_current_matrices (f); |
diff --git a/src/frame.h b/src/frame.h index 63bcce259af..1d920d1a6bc 100644 --- a/src/frame.h +++ b/src/frame.h | |||
| @@ -288,6 +288,12 @@ struct frame | |||
| 288 | /* Cache of realized faces. */ | 288 | /* Cache of realized faces. */ |
| 289 | struct face_cache *face_cache; | 289 | struct face_cache *face_cache; |
| 290 | 290 | ||
| 291 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 292 | /* Cache of realized images, which may be shared with other | ||
| 293 | frames. */ | ||
| 294 | struct image_cache *image_cache; | ||
| 295 | #endif /* HAVE_WINDOW_SYSTEM */ | ||
| 296 | |||
| 291 | /* Tab-bar item index of the item on which a mouse button was pressed. */ | 297 | /* Tab-bar item index of the item on which a mouse button was pressed. */ |
| 292 | int last_tab_bar_item; | 298 | int last_tab_bar_item; |
| 293 | 299 | ||
| @@ -909,7 +915,7 @@ default_pixels_per_inch_y (void) | |||
| 909 | #define FRAME_KBOARD(f) ((f)->terminal->kboard) | 915 | #define FRAME_KBOARD(f) ((f)->terminal->kboard) |
| 910 | 916 | ||
| 911 | /* Return a pointer to the image cache of frame F. */ | 917 | /* Return a pointer to the image cache of frame F. */ |
| 912 | #define FRAME_IMAGE_CACHE(F) ((F)->terminal->image_cache) | 918 | #define FRAME_IMAGE_CACHE(F) ((F)->image_cache) |
| 913 | 919 | ||
| 914 | #define XFRAME(p) \ | 920 | #define XFRAME(p) \ |
| 915 | (eassert (FRAMEP (p)), XUNTAG (p, Lisp_Vectorlike, struct frame)) | 921 | (eassert (FRAMEP (p)), XUNTAG (p, Lisp_Vectorlike, struct frame)) |
diff --git a/src/haikufns.c b/src/haikufns.c index 870b6f58f02..4a31def4def 100644 --- a/src/haikufns.c +++ b/src/haikufns.c | |||
| @@ -73,9 +73,6 @@ static Lisp_Object tip_last_parms; | |||
| 73 | static void haiku_explicitly_set_name (struct frame *, Lisp_Object, Lisp_Object); | 73 | static void haiku_explicitly_set_name (struct frame *, Lisp_Object, Lisp_Object); |
| 74 | static void haiku_set_title (struct frame *, Lisp_Object, Lisp_Object); | 74 | static void haiku_set_title (struct frame *, Lisp_Object, Lisp_Object); |
| 75 | 75 | ||
| 76 | /* The number of references to an image cache. */ | ||
| 77 | static ptrdiff_t image_cache_refcount; | ||
| 78 | |||
| 79 | static Lisp_Object | 76 | static Lisp_Object |
| 80 | get_geometry_from_preferences (struct haiku_display_info *dpyinfo, | 77 | get_geometry_from_preferences (struct haiku_display_info *dpyinfo, |
| 81 | Lisp_Object parms) | 78 | Lisp_Object parms) |
| @@ -627,29 +624,8 @@ unwind_create_frame (Lisp_Object frame) | |||
| 627 | /* If frame is ``official'', nothing to do. */ | 624 | /* If frame is ``official'', nothing to do. */ |
| 628 | if (NILP (Fmemq (frame, Vframe_list))) | 625 | if (NILP (Fmemq (frame, Vframe_list))) |
| 629 | { | 626 | { |
| 630 | #if defined GLYPH_DEBUG && defined ENABLE_CHECKING | ||
| 631 | struct haiku_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); | ||
| 632 | #endif | ||
| 633 | |||
| 634 | /* If the frame's image cache refcount is still the same as our | ||
| 635 | private shadow variable, it means we are unwinding a frame | ||
| 636 | for which we didn't yet call init_frame_faces, where the | ||
| 637 | refcount is incremented. Therefore, we increment it here, so | ||
| 638 | that free_frame_faces, called in free_frame_resources later, | ||
| 639 | will not mistakenly decrement the counter that was not | ||
| 640 | incremented yet to account for this new frame. */ | ||
| 641 | if (FRAME_IMAGE_CACHE (f) != NULL | ||
| 642 | && FRAME_IMAGE_CACHE (f)->refcount == image_cache_refcount) | ||
| 643 | FRAME_IMAGE_CACHE (f)->refcount++; | ||
| 644 | |||
| 645 | haiku_free_frame_resources (f); | 627 | haiku_free_frame_resources (f); |
| 646 | free_glyphs (f); | 628 | free_glyphs (f); |
| 647 | |||
| 648 | #if defined GLYPH_DEBUG && defined ENABLE_CHECKING | ||
| 649 | /* Check that reference counts are indeed correct. */ | ||
| 650 | if (dpyinfo->terminal->image_cache) | ||
| 651 | eassert (dpyinfo->terminal->image_cache->refcount == image_cache_refcount); | ||
| 652 | #endif | ||
| 653 | } | 629 | } |
| 654 | } | 630 | } |
| 655 | 631 | ||
| @@ -807,9 +783,6 @@ haiku_create_frame (Lisp_Object parms) | |||
| 807 | #endif | 783 | #endif |
| 808 | register_font_driver (&haikufont_driver, f); | 784 | register_font_driver (&haikufont_driver, f); |
| 809 | 785 | ||
| 810 | image_cache_refcount = | ||
| 811 | FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; | ||
| 812 | |||
| 813 | gui_default_parameter (f, parms, Qfont_backend, Qnil, | 786 | gui_default_parameter (f, parms, Qfont_backend, Qnil, |
| 814 | "fontBackend", "FontBackend", RES_TYPE_STRING); | 787 | "fontBackend", "FontBackend", RES_TYPE_STRING); |
| 815 | 788 | ||
| @@ -1098,9 +1071,6 @@ haiku_create_tip_frame (Lisp_Object parms) | |||
| 1098 | #endif | 1071 | #endif |
| 1099 | register_font_driver (&haikufont_driver, f); | 1072 | register_font_driver (&haikufont_driver, f); |
| 1100 | 1073 | ||
| 1101 | image_cache_refcount = | ||
| 1102 | FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; | ||
| 1103 | |||
| 1104 | gui_default_parameter (f, parms, Qfont_backend, Qnil, | 1074 | gui_default_parameter (f, parms, Qfont_backend, Qnil, |
| 1105 | "fontBackend", "FontBackend", RES_TYPE_STRING); | 1075 | "fontBackend", "FontBackend", RES_TYPE_STRING); |
| 1106 | 1076 | ||
diff --git a/src/image.c b/src/image.c index 879531d5264..2945447b962 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -2195,6 +2195,8 @@ make_image_cache (void) | |||
| 2195 | c->used = c->refcount = 0; | 2195 | c->used = c->refcount = 0; |
| 2196 | c->images = xmalloc (c->size * sizeof *c->images); | 2196 | c->images = xmalloc (c->size * sizeof *c->images); |
| 2197 | c->buckets = xzalloc (IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets); | 2197 | c->buckets = xzalloc (IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets); |
| 2198 | /* This value should never be encountered. */ | ||
| 2199 | c->scaling_col_width = -1; | ||
| 2198 | return c; | 2200 | return c; |
| 2199 | } | 2201 | } |
| 2200 | 2202 | ||
| @@ -3620,7 +3622,10 @@ cache_image (struct frame *f, struct image *img) | |||
| 3620 | ptrdiff_t i; | 3622 | ptrdiff_t i; |
| 3621 | 3623 | ||
| 3622 | if (!c) | 3624 | if (!c) |
| 3623 | c = FRAME_IMAGE_CACHE (f) = make_image_cache (); | 3625 | { |
| 3626 | c = FRAME_IMAGE_CACHE (f) = share_image_cache (f); | ||
| 3627 | c->refcount++; | ||
| 3628 | } | ||
| 3624 | 3629 | ||
| 3625 | /* Find a free slot in c->images. */ | 3630 | /* Find a free slot in c->images. */ |
| 3626 | for (i = 0; i < c->used; ++i) | 3631 | for (i = 0; i < c->used; ++i) |
diff --git a/src/nsfns.m b/src/nsfns.m index 24fabbe2eaa..d9c1296056c 100644 --- a/src/nsfns.m +++ b/src/nsfns.m | |||
| @@ -87,8 +87,6 @@ static Lisp_Object tip_last_parms; | |||
| 87 | static Lisp_Object as_script, *as_result; | 87 | static Lisp_Object as_script, *as_result; |
| 88 | static int as_status; | 88 | static int as_status; |
| 89 | 89 | ||
| 90 | static ptrdiff_t image_cache_refcount; | ||
| 91 | |||
| 92 | static struct ns_display_info *ns_display_info_for_name (Lisp_Object); | 90 | static struct ns_display_info *ns_display_info_for_name (Lisp_Object); |
| 93 | 91 | ||
| 94 | /* ========================================================================== | 92 | /* ========================================================================== |
| @@ -1137,29 +1135,8 @@ unwind_create_frame (Lisp_Object frame) | |||
| 1137 | /* If frame is ``official'', nothing to do. */ | 1135 | /* If frame is ``official'', nothing to do. */ |
| 1138 | if (NILP (Fmemq (frame, Vframe_list))) | 1136 | if (NILP (Fmemq (frame, Vframe_list))) |
| 1139 | { | 1137 | { |
| 1140 | #if defined GLYPH_DEBUG && defined ENABLE_CHECKING | ||
| 1141 | struct ns_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); | ||
| 1142 | #endif | ||
| 1143 | |||
| 1144 | /* If the frame's image cache refcount is still the same as our | ||
| 1145 | private shadow variable, it means we are unwinding a frame | ||
| 1146 | for which we didn't yet call init_frame_faces, where the | ||
| 1147 | refcount is incremented. Therefore, we increment it here, so | ||
| 1148 | that free_frame_faces, called in ns_free_frame_resources | ||
| 1149 | below, will not mistakenly decrement the counter that was not | ||
| 1150 | incremented yet to account for this new frame. */ | ||
| 1151 | if (FRAME_IMAGE_CACHE (f) != NULL | ||
| 1152 | && FRAME_IMAGE_CACHE (f)->refcount == image_cache_refcount) | ||
| 1153 | FRAME_IMAGE_CACHE (f)->refcount++; | ||
| 1154 | |||
| 1155 | ns_free_frame_resources (f); | 1138 | ns_free_frame_resources (f); |
| 1156 | free_glyphs (f); | 1139 | free_glyphs (f); |
| 1157 | |||
| 1158 | #if defined GLYPH_DEBUG && defined ENABLE_CHECKING | ||
| 1159 | /* Check that reference counts are indeed correct. */ | ||
| 1160 | eassert (dpyinfo->terminal->image_cache->refcount == image_cache_refcount); | ||
| 1161 | #endif | ||
| 1162 | |||
| 1163 | return Qt; | 1140 | return Qt; |
| 1164 | } | 1141 | } |
| 1165 | 1142 | ||
diff --git a/src/pgtkfns.c b/src/pgtkfns.c index bdc6c5836fa..49467988cae 100644 --- a/src/pgtkfns.c +++ b/src/pgtkfns.c | |||
| @@ -38,8 +38,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 38 | #include "xsettings.h" | 38 | #include "xsettings.h" |
| 39 | #include "atimer.h" | 39 | #include "atimer.h" |
| 40 | 40 | ||
| 41 | static ptrdiff_t image_cache_refcount; | ||
| 42 | |||
| 43 | static int x_decode_color (struct frame *f, Lisp_Object color_name, | 41 | static int x_decode_color (struct frame *f, Lisp_Object color_name, |
| 44 | int mono_color); | 42 | int mono_color); |
| 45 | static struct pgtk_display_info *pgtk_display_info_for_name (Lisp_Object); | 43 | static struct pgtk_display_info *pgtk_display_info_for_name (Lisp_Object); |
| @@ -1019,17 +1017,6 @@ unwind_create_frame (Lisp_Object frame) | |||
| 1019 | /* If frame is ``official'', nothing to do. */ | 1017 | /* If frame is ``official'', nothing to do. */ |
| 1020 | if (NILP (Fmemq (frame, Vframe_list))) | 1018 | if (NILP (Fmemq (frame, Vframe_list))) |
| 1021 | { | 1019 | { |
| 1022 | /* If the frame's image cache refcount is still the same as our | ||
| 1023 | private shadow variable, it means we are unwinding a frame | ||
| 1024 | for which we didn't yet call init_frame_faces, where the | ||
| 1025 | refcount is incremented. Therefore, we increment it here, so | ||
| 1026 | that free_frame_faces, called in x_free_frame_resources | ||
| 1027 | below, will not mistakenly decrement the counter that was not | ||
| 1028 | incremented yet to account for this new frame. */ | ||
| 1029 | if (FRAME_IMAGE_CACHE (f) != NULL | ||
| 1030 | && FRAME_IMAGE_CACHE (f)->refcount == image_cache_refcount) | ||
| 1031 | FRAME_IMAGE_CACHE (f)->refcount++; | ||
| 1032 | |||
| 1033 | pgtk_free_frame_resources (f); | 1020 | pgtk_free_frame_resources (f); |
| 1034 | free_glyphs (f); | 1021 | free_glyphs (f); |
| 1035 | return Qt; | 1022 | return Qt; |
| @@ -1389,9 +1376,6 @@ This function is an internal primitive--use `make-frame' instead. */ ) | |||
| 1389 | register_font_driver (&ftcrhbfont_driver, f); | 1376 | register_font_driver (&ftcrhbfont_driver, f); |
| 1390 | #endif /* HAVE_HARFBUZZ */ | 1377 | #endif /* HAVE_HARFBUZZ */ |
| 1391 | 1378 | ||
| 1392 | image_cache_refcount = | ||
| 1393 | FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; | ||
| 1394 | |||
| 1395 | gui_default_parameter (f, parms, Qfont_backend, Qnil, | 1379 | gui_default_parameter (f, parms, Qfont_backend, Qnil, |
| 1396 | "fontBackend", "FontBackend", RES_TYPE_STRING); | 1380 | "fontBackend", "FontBackend", RES_TYPE_STRING); |
| 1397 | 1381 | ||
| @@ -2746,9 +2730,6 @@ x_create_tip_frame (struct pgtk_display_info *dpyinfo, Lisp_Object parms, struct | |||
| 2746 | register_font_driver (&ftcrhbfont_driver, f); | 2730 | register_font_driver (&ftcrhbfont_driver, f); |
| 2747 | #endif /* HAVE_HARFBUZZ */ | 2731 | #endif /* HAVE_HARFBUZZ */ |
| 2748 | 2732 | ||
| 2749 | image_cache_refcount = | ||
| 2750 | FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; | ||
| 2751 | |||
| 2752 | gui_default_parameter (f, parms, Qfont_backend, Qnil, | 2733 | gui_default_parameter (f, parms, Qfont_backend, Qnil, |
| 2753 | "fontBackend", "FontBackend", RES_TYPE_STRING); | 2734 | "fontBackend", "FontBackend", RES_TYPE_STRING); |
| 2754 | 2735 | ||
diff --git a/src/termhooks.h b/src/termhooks.h index d828c62ce33..d6a9300bac9 100644 --- a/src/termhooks.h +++ b/src/termhooks.h | |||
| @@ -523,11 +523,6 @@ struct terminal | |||
| 523 | /* The terminal's keyboard object. */ | 523 | /* The terminal's keyboard object. */ |
| 524 | struct kboard *kboard; | 524 | struct kboard *kboard; |
| 525 | 525 | ||
| 526 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 527 | /* Cache of images. */ | ||
| 528 | struct image_cache *image_cache; | ||
| 529 | #endif /* HAVE_WINDOW_SYSTEM */ | ||
| 530 | |||
| 531 | /* Device-type dependent data shared amongst all frames on this terminal. */ | 526 | /* Device-type dependent data shared amongst all frames on this terminal. */ |
| 532 | union display_info | 527 | union display_info |
| 533 | { | 528 | { |
diff --git a/src/w32fns.c b/src/w32fns.c index 5b0e4a895d0..b784a9a563d 100644 --- a/src/w32fns.c +++ b/src/w32fns.c | |||
| @@ -270,7 +270,6 @@ unsigned int msh_mousewheel = 0; | |||
| 270 | static unsigned menu_free_timer = 0; | 270 | static unsigned menu_free_timer = 0; |
| 271 | 271 | ||
| 272 | #ifdef GLYPH_DEBUG | 272 | #ifdef GLYPH_DEBUG |
| 273 | static ptrdiff_t image_cache_refcount; | ||
| 274 | static int dpyinfo_refcount; | 273 | static int dpyinfo_refcount; |
| 275 | #endif | 274 | #endif |
| 276 | 275 | ||
| @@ -5918,17 +5917,6 @@ unwind_create_frame (Lisp_Object frame) | |||
| 5918 | { | 5917 | { |
| 5919 | #ifdef GLYPH_DEBUG | 5918 | #ifdef GLYPH_DEBUG |
| 5920 | struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); | 5919 | struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); |
| 5921 | |||
| 5922 | /* If the frame's image cache refcount is still the same as our | ||
| 5923 | private shadow variable, it means we are unwinding a frame | ||
| 5924 | for which we didn't yet call init_frame_faces, where the | ||
| 5925 | refcount is incremented. Therefore, we increment it here, so | ||
| 5926 | that free_frame_faces, called in w32_free_frame_resources | ||
| 5927 | below, will not mistakenly decrement the counter that was not | ||
| 5928 | incremented yet to account for this new frame. */ | ||
| 5929 | if (FRAME_IMAGE_CACHE (f) != NULL | ||
| 5930 | && FRAME_IMAGE_CACHE (f)->refcount == image_cache_refcount) | ||
| 5931 | FRAME_IMAGE_CACHE (f)->refcount++; | ||
| 5932 | #endif | 5920 | #endif |
| 5933 | 5921 | ||
| 5934 | w32_free_frame_resources (f); | 5922 | w32_free_frame_resources (f); |
| @@ -5937,10 +5925,6 @@ unwind_create_frame (Lisp_Object frame) | |||
| 5937 | #ifdef GLYPH_DEBUG | 5925 | #ifdef GLYPH_DEBUG |
| 5938 | /* Check that reference counts are indeed correct. */ | 5926 | /* Check that reference counts are indeed correct. */ |
| 5939 | eassert (dpyinfo->reference_count == dpyinfo_refcount); | 5927 | eassert (dpyinfo->reference_count == dpyinfo_refcount); |
| 5940 | eassert ((dpyinfo->terminal->image_cache == NULL | ||
| 5941 | && image_cache_refcount == 0) | ||
| 5942 | || (dpyinfo->terminal->image_cache != NULL | ||
| 5943 | && dpyinfo->terminal->image_cache->refcount == image_cache_refcount)); | ||
| 5944 | #endif | 5928 | #endif |
| 5945 | return Qt; | 5929 | return Qt; |
| 5946 | } | 5930 | } |
| @@ -6128,8 +6112,6 @@ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, | |||
| 6128 | record_unwind_protect (do_unwind_create_frame, frame); | 6112 | record_unwind_protect (do_unwind_create_frame, frame); |
| 6129 | 6113 | ||
| 6130 | #ifdef GLYPH_DEBUG | 6114 | #ifdef GLYPH_DEBUG |
| 6131 | image_cache_refcount = | ||
| 6132 | FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; | ||
| 6133 | dpyinfo_refcount = dpyinfo->reference_count; | 6115 | dpyinfo_refcount = dpyinfo->reference_count; |
| 6134 | #endif /* GLYPH_DEBUG */ | 6116 | #endif /* GLYPH_DEBUG */ |
| 6135 | 6117 | ||
| @@ -7222,8 +7204,6 @@ w32_create_tip_frame (struct w32_display_info *dpyinfo, Lisp_Object parms) | |||
| 7222 | f->tooltip = true; | 7204 | f->tooltip = true; |
| 7223 | 7205 | ||
| 7224 | #ifdef GLYPH_DEBUG | 7206 | #ifdef GLYPH_DEBUG |
| 7225 | image_cache_refcount = | ||
| 7226 | FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; | ||
| 7227 | dpyinfo_refcount = dpyinfo->reference_count; | 7207 | dpyinfo_refcount = dpyinfo->reference_count; |
| 7228 | #endif /* GLYPH_DEBUG */ | 7208 | #endif /* GLYPH_DEBUG */ |
| 7229 | FRAME_KBOARD (f) = kb; | 7209 | FRAME_KBOARD (f) = kb; |
diff --git a/src/xfaces.c b/src/xfaces.c index e305cc7456f..1e0196a1171 100644 --- a/src/xfaces.c +++ b/src/xfaces.c | |||
| @@ -634,6 +634,37 @@ x_free_gc (struct frame *f, struct android_gc *gc) | |||
| 634 | Frames and faces | 634 | Frames and faces |
| 635 | ***********************************************************************/ | 635 | ***********************************************************************/ |
| 636 | 636 | ||
| 637 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 638 | |||
| 639 | /* Find an existing image cache registered for a frame on F's display | ||
| 640 | and with a `scaling_col_width' of F's FRAME_COLUMN_WIDTH, or, in the | ||
| 641 | absence of an eligible image cache, allocate an image cache with the | ||
| 642 | same width value. */ | ||
| 643 | |||
| 644 | struct image_cache * | ||
| 645 | share_image_cache (struct frame *f) | ||
| 646 | { | ||
| 647 | int width = max (10, FRAME_COLUMN_WIDTH (f)); | ||
| 648 | Lisp_Object tail, frame; | ||
| 649 | struct image_cache *cache; | ||
| 650 | |||
| 651 | FOR_EACH_FRAME (tail, frame) | ||
| 652 | { | ||
| 653 | struct frame *x = XFRAME (frame); | ||
| 654 | |||
| 655 | if (FRAME_TERMINAL (x) == FRAME_TERMINAL (f) | ||
| 656 | && FRAME_IMAGE_CACHE (x) | ||
| 657 | && FRAME_IMAGE_CACHE (x)->scaling_col_width == width) | ||
| 658 | return FRAME_IMAGE_CACHE (x); | ||
| 659 | } | ||
| 660 | |||
| 661 | cache = make_image_cache (); | ||
| 662 | cache->scaling_col_width = width; | ||
| 663 | return cache; | ||
| 664 | } | ||
| 665 | |||
| 666 | #endif /* HAVE_WINDOW_SYSTEM */ | ||
| 667 | |||
| 637 | /* Initialize face cache and basic faces for frame F. */ | 668 | /* Initialize face cache and basic faces for frame F. */ |
| 638 | 669 | ||
| 639 | void | 670 | void |
| @@ -644,14 +675,10 @@ init_frame_faces (struct frame *f) | |||
| 644 | FRAME_FACE_CACHE (f) = make_face_cache (f); | 675 | FRAME_FACE_CACHE (f) = make_face_cache (f); |
| 645 | 676 | ||
| 646 | #ifdef HAVE_WINDOW_SYSTEM | 677 | #ifdef HAVE_WINDOW_SYSTEM |
| 647 | /* Make the image cache. */ | 678 | /* Make or share an image cache. */ |
| 648 | if (FRAME_WINDOW_P (f)) | 679 | if (FRAME_WINDOW_P (f)) |
| 649 | { | 680 | { |
| 650 | /* We initialize the image cache when creating the first frame | 681 | FRAME_IMAGE_CACHE (f) = share_image_cache (f); |
| 651 | on a terminal, and not during terminal creation. This way, | ||
| 652 | `x-open-connection' on a tty won't create an image cache. */ | ||
| 653 | if (FRAME_IMAGE_CACHE (f) == NULL) | ||
| 654 | FRAME_IMAGE_CACHE (f) = make_image_cache (); | ||
| 655 | ++FRAME_IMAGE_CACHE (f)->refcount; | 682 | ++FRAME_IMAGE_CACHE (f)->refcount; |
| 656 | } | 683 | } |
| 657 | #endif /* HAVE_WINDOW_SYSTEM */ | 684 | #endif /* HAVE_WINDOW_SYSTEM */ |
diff --git a/src/xfns.c b/src/xfns.c index 4fdcf07e8fb..5ba4a78ac9d 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -127,7 +127,6 @@ extern LWLIB_ID widget_id_tick; | |||
| 127 | 127 | ||
| 128 | #define MAXREQUEST(dpy) (XMaxRequestSize (dpy)) | 128 | #define MAXREQUEST(dpy) (XMaxRequestSize (dpy)) |
| 129 | 129 | ||
| 130 | static ptrdiff_t image_cache_refcount; | ||
| 131 | #ifdef GLYPH_DEBUG | 130 | #ifdef GLYPH_DEBUG |
| 132 | static int dpyinfo_refcount; | 131 | static int dpyinfo_refcount; |
| 133 | #endif | 132 | #endif |
| @@ -4754,29 +4753,12 @@ unwind_create_frame (Lisp_Object frame) | |||
| 4754 | /* If frame is ``official'', nothing to do. */ | 4753 | /* If frame is ``official'', nothing to do. */ |
| 4755 | if (NILP (Fmemq (frame, Vframe_list))) | 4754 | if (NILP (Fmemq (frame, Vframe_list))) |
| 4756 | { | 4755 | { |
| 4757 | #if defined GLYPH_DEBUG && defined ENABLE_CHECKING | ||
| 4758 | struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); | ||
| 4759 | #endif | ||
| 4760 | |||
| 4761 | /* If the frame's image cache refcount is still the same as our | ||
| 4762 | private shadow variable, it means we are unwinding a frame | ||
| 4763 | for which we didn't yet call init_frame_faces, where the | ||
| 4764 | refcount is incremented. Therefore, we increment it here, so | ||
| 4765 | that free_frame_faces, called in x_free_frame_resources | ||
| 4766 | below, will not mistakenly decrement the counter that was not | ||
| 4767 | incremented yet to account for this new frame. */ | ||
| 4768 | if (FRAME_IMAGE_CACHE (f) != NULL | ||
| 4769 | && FRAME_IMAGE_CACHE (f)->refcount == image_cache_refcount) | ||
| 4770 | FRAME_IMAGE_CACHE (f)->refcount++; | ||
| 4771 | |||
| 4772 | x_free_frame_resources (f); | 4756 | x_free_frame_resources (f); |
| 4773 | free_glyphs (f); | 4757 | free_glyphs (f); |
| 4774 | |||
| 4775 | #if defined GLYPH_DEBUG && defined ENABLE_CHECKING | 4758 | #if defined GLYPH_DEBUG && defined ENABLE_CHECKING |
| 4776 | /* Check that reference counts are indeed correct. */ | 4759 | /* Check that reference counts are indeed correct. */ |
| 4777 | eassert (dpyinfo->reference_count == dpyinfo_refcount); | 4760 | eassert (dpyinfo->reference_count == dpyinfo_refcount); |
| 4778 | eassert (dpyinfo->terminal->image_cache->refcount == image_cache_refcount); | 4761 | #endif /* GLYPH_DEBUG && ENABLE_CHECKING */ |
| 4779 | #endif | ||
| 4780 | return Qt; | 4762 | return Qt; |
| 4781 | } | 4763 | } |
| 4782 | 4764 | ||
| @@ -5112,9 +5094,6 @@ This function is an internal primitive--use `make-frame' instead. */) | |||
| 5112 | #endif /* HAVE_FREETYPE */ | 5094 | #endif /* HAVE_FREETYPE */ |
| 5113 | #endif /* not USE_CAIRO */ | 5095 | #endif /* not USE_CAIRO */ |
| 5114 | register_font_driver (&xfont_driver, f); | 5096 | register_font_driver (&xfont_driver, f); |
| 5115 | |||
| 5116 | image_cache_refcount = | ||
| 5117 | FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; | ||
| 5118 | #ifdef GLYPH_DEBUG | 5097 | #ifdef GLYPH_DEBUG |
| 5119 | dpyinfo_refcount = dpyinfo->reference_count; | 5098 | dpyinfo_refcount = dpyinfo->reference_count; |
| 5120 | #endif /* GLYPH_DEBUG */ | 5099 | #endif /* GLYPH_DEBUG */ |
| @@ -8484,8 +8463,6 @@ x_create_tip_frame (struct x_display_info *dpyinfo, Lisp_Object parms) | |||
| 8484 | #endif /* not USE_CAIRO */ | 8463 | #endif /* not USE_CAIRO */ |
| 8485 | register_font_driver (&xfont_driver, f); | 8464 | register_font_driver (&xfont_driver, f); |
| 8486 | 8465 | ||
| 8487 | image_cache_refcount = | ||
| 8488 | FRAME_IMAGE_CACHE (f) ? FRAME_IMAGE_CACHE (f)->refcount : 0; | ||
| 8489 | #ifdef GLYPH_DEBUG | 8466 | #ifdef GLYPH_DEBUG |
| 8490 | dpyinfo_refcount = dpyinfo->reference_count; | 8467 | dpyinfo_refcount = dpyinfo->reference_count; |
| 8491 | #endif /* GLYPH_DEBUG */ | 8468 | #endif /* GLYPH_DEBUG */ |