aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2024-06-20 17:03:36 +0800
committerPo Lu2024-06-20 17:03:36 +0800
commitcebca072c33937b84995a62c35c16441d23bb86d (patch)
treee1bf28f6453a63a4d0eafa4757e4f65230e2338f /src
parent374f4235d5e78def23d92b05f3d0257c1f609725 (diff)
downloademacs-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.c13
-rw-r--r--src/androidfns.c21
-rw-r--r--src/dispextern.h8
-rw-r--r--src/frame.c34
-rw-r--r--src/frame.h8
-rw-r--r--src/haikufns.c30
-rw-r--r--src/image.c7
-rw-r--r--src/nsfns.m23
-rw-r--r--src/pgtkfns.c19
-rw-r--r--src/termhooks.h5
-rw-r--r--src/w32fns.c20
-rw-r--r--src/xfaces.c39
-rw-r--r--src/xfns.c25
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
7060static void 7067static 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. */
36static 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. */
39static Lisp_Object tip_frame; 36static 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);
3708int face_with_height (struct frame *, int, int); 3713int face_with_height (struct frame *, int, int);
3709int lookup_derived_face (struct window *, struct frame *, 3714int lookup_derived_face (struct window *, struct frame *,
3710 Lisp_Object, int, bool); 3715 Lisp_Object, int, bool);
3716#ifdef HAVE_WINDOW_SYSTEM
3717extern struct image_cache *share_image_cache (struct frame *f);
3718#endif /* HAVE_WINDOW_SYSTEM */
3711void init_frame_faces (struct frame *); 3719void init_frame_faces (struct frame *);
3712void free_frame_faces (struct frame *); 3720void free_frame_faces (struct frame *);
3713void recompute_basic_faces (struct frame *); 3721void 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
4732gui_set_font (struct frame *f, Lisp_Object arg, Lisp_Object oldval) 4734gui_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;
73static void haiku_explicitly_set_name (struct frame *, Lisp_Object, Lisp_Object); 73static void haiku_explicitly_set_name (struct frame *, Lisp_Object, Lisp_Object);
74static void haiku_set_title (struct frame *, Lisp_Object, Lisp_Object); 74static void haiku_set_title (struct frame *, Lisp_Object, Lisp_Object);
75 75
76/* The number of references to an image cache. */
77static ptrdiff_t image_cache_refcount;
78
79static Lisp_Object 76static Lisp_Object
80get_geometry_from_preferences (struct haiku_display_info *dpyinfo, 77get_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;
87static Lisp_Object as_script, *as_result; 87static Lisp_Object as_script, *as_result;
88static int as_status; 88static int as_status;
89 89
90static ptrdiff_t image_cache_refcount;
91
92static struct ns_display_info *ns_display_info_for_name (Lisp_Object); 90static 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
41static ptrdiff_t image_cache_refcount;
42
43static int x_decode_color (struct frame *f, Lisp_Object color_name, 41static int x_decode_color (struct frame *f, Lisp_Object color_name,
44 int mono_color); 42 int mono_color);
45static struct pgtk_display_info *pgtk_display_info_for_name (Lisp_Object); 43static 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;
270static unsigned menu_free_timer = 0; 270static unsigned menu_free_timer = 0;
271 271
272#ifdef GLYPH_DEBUG 272#ifdef GLYPH_DEBUG
273static ptrdiff_t image_cache_refcount;
274static int dpyinfo_refcount; 273static 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
644struct image_cache *
645share_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
639void 670void
@@ -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
130static ptrdiff_t image_cache_refcount;
131#ifdef GLYPH_DEBUG 130#ifdef GLYPH_DEBUG
132static int dpyinfo_refcount; 131static 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 */