summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2015-09-18 16:52:24 +0300
committerEli Zaretskii <eliz@gnu.org>2015-09-18 16:52:24 +0300
commiteb68d48ff7d1bd2328812a1519280b777dd63dba (patch)
treeb6dadc2298a78e7ef35de0a46c79013963f778ec
parentfb875ee6ff20034944df04b83a147493db7ddeb3 (diff)
downloademacs-eb68d48ff7d1bd2328812a1519280b777dd63dba.tar.gz
First take on minimizing face-related X calls
Introduce a frame-specific face_change flag, and set only it when a face change involves a single frame. Prevent redisplay from skipping a window when its frame's face_change flag is set. Ditto for redisplay optimization 1. Don't free all faces when the frame's screen-gamma parameter is set. Don't clear face caches (on all frames!) when tty colors are registered at startup, when the selected frame is a GUI frame.
-rw-r--r--lisp/term/tty-colors.el8
-rw-r--r--src/frame.c5
-rw-r--r--src/frame.h3
-rw-r--r--src/xdisp.c16
-rw-r--r--src/xfaces.c40
5 files changed, 50 insertions, 22 deletions
diff --git a/lisp/term/tty-colors.el b/lisp/term/tty-colors.el
index 98108ce6356..3bc1aa0ee48 100644
--- a/lisp/term/tty-colors.el
+++ b/lisp/term/tty-colors.el
@@ -810,9 +810,11 @@ Value is the modified color alist for FRAME."
(while colors
(tty-color-define (car color) (cadr color) (cddr color))
(setq colors (cdr colors) color (car colors)))
- ;; Modifying color mappings means realized faces don't
- ;; use the right colors, so clear them.
- (clear-face-cache)))
+ ;; Modifying color mappings means realized faces don't use the
+ ;; right colors, so clear them, if we modified colors on a TTY
+ ;; frame.
+ (or (display-graphic-p)
+ (clear-face-cache))))
(defun tty-color-canonicalize (color)
"Return COLOR in canonical form.
diff --git a/src/frame.c b/src/frame.c
index 0e95749a055..a4ebffc443a 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -3517,7 +3517,7 @@ x_set_line_spacing (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu
void
x_set_screen_gamma (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
{
- Lisp_Object bgcolor;
+ Lisp_Object bgcolor, frame;
if (NILP (new_value))
f->gamma = 0;
@@ -3539,7 +3539,8 @@ x_set_screen_gamma (struct frame *f, Lisp_Object new_value, Lisp_Object old_valu
(f, bgcolor, Qnil);
}
- Fclear_face_cache (Qnil);
+ clear_face_cache (true);
+ windows_or_buffers_changed = 70;
}
diff --git a/src/frame.h b/src/frame.h
index 546bede213d..af0dadb3d99 100644
--- a/src/frame.h
+++ b/src/frame.h
@@ -335,6 +335,9 @@ struct frame
/* Set to true after this frame was made by `make-frame'. */
bool_bf after_make_frame : 1;
+ /* Non-zero if this frame's faces need to be recomputed. */
+ bool_bf face_change : 1;
+
/* Bitfield area ends here. */
/* Number of lines (rounded up) of tool bar. REMOVE THIS */
diff --git a/src/xdisp.c b/src/xdisp.c
index 3eff61f3716..9845a9a1dbb 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -2661,10 +2661,18 @@ init_iterator (struct it *it, struct window *w,
free realized faces now because they depend on face definitions
that might have changed. Don't free faces while there might be
desired matrices pending which reference these faces. */
- if (face_change && !inhibit_free_realized_faces)
+ if (!inhibit_free_realized_faces)
{
- face_change = false;
- free_all_realized_faces (Qnil);
+ if (face_change)
+ {
+ face_change = false;
+ free_all_realized_faces (Qnil);
+ }
+ else if (XFRAME (w->frame)->face_change)
+ {
+ XFRAME (w->frame)->face_change = 0;
+ free_all_realized_faces (w->frame);
+ }
}
/* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
@@ -13531,6 +13539,7 @@ redisplay_internal (void)
&& FRAME_VISIBLE_P (XFRAME (w->frame))
&& !FRAME_OBSCURED_P (XFRAME (w->frame))
&& !XFRAME (w->frame)->cursor_type_changed
+ && !XFRAME (w->frame)->face_change
/* Make sure recorded data applies to current buffer, etc. */
&& this_line_buffer == current_buffer
&& match_p
@@ -15877,6 +15886,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
&& REDISPLAY_SOME_P ()
&& !w->redisplay
&& !w->update_mode_line
+ && !f->face_change
&& !f->redisplay
&& !buffer->text->redisplay
&& BUF_PT (buffer) == w->last_point)
diff --git a/src/xfaces.c b/src/xfaces.c
index 94f3c4d67c2..40713f167ff 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -687,7 +687,6 @@ clear_face_cache (bool clear_fonts_p)
#endif /* HAVE_WINDOW_SYSTEM */
}
-
DEFUN ("clear-face-cache", Fclear_face_cache, Sclear_face_cache, 0, 1, 0,
doc: /* Clear face caches on all frames.
Optional THOROUGHLY non-nil means try to free unused fonts, too. */)
@@ -2528,7 +2527,10 @@ Value is a vector of face attributes. */)
free realized faces. */
if (NILP (Fget (face, Qface_no_inherit)))
{
- face_change = true;
+ if (f)
+ f->face_change = 1;
+ else
+ face_change = true;
windows_or_buffers_changed = 54;
}
@@ -2576,6 +2578,7 @@ The value is TO. */)
(Lisp_Object from, Lisp_Object to, Lisp_Object frame, Lisp_Object new_frame)
{
Lisp_Object lface, copy;
+ struct frame *f;
CHECK_SYMBOL (from);
CHECK_SYMBOL (to);
@@ -2586,6 +2589,7 @@ The value is TO. */)
strings etc. because 20.2 didn't do it either. */
lface = lface_from_face_name (NULL, from, true);
copy = Finternal_make_lisp_face (to, Qnil);
+ f = NULL;
}
else
{
@@ -2596,6 +2600,7 @@ The value is TO. */)
CHECK_LIVE_FRAME (new_frame);
lface = lface_from_face_name (XFRAME (frame), from, true);
copy = Finternal_make_lisp_face (to, new_frame);
+ f = XFRAME (new_frame);
}
vcopy (copy, 0, XVECTOR (lface)->contents, LFACE_VECTOR_SIZE);
@@ -2607,7 +2612,10 @@ The value is TO. */)
free realized faces. */
if (NILP (Fget (to, Qface_no_inherit)))
{
- face_change = true;
+ if (f)
+ f->face_change = 1;
+ else
+ face_change = true;
windows_or_buffers_changed = 55;
}
@@ -2630,6 +2638,7 @@ FRAME 0 means change the face on all frames, and change the default
/* Set one of enum font_property_index (> 0) if ATTR is one of
font-related attributes other than QCfont and QCfontset. */
enum font_property_index prop_index = 0;
+ struct frame *f;
CHECK_SYMBOL (face);
CHECK_SYMBOL (attr);
@@ -2650,6 +2659,7 @@ FRAME 0 means change the face on all frames, and change the default
/* Set lface to the Lisp attribute vector of FACE. */
if (EQ (frame, Qt))
{
+ f = NULL;
lface = lface_from_face_name (NULL, face, true);
/* When updating face-new-frame-defaults, we put :ignore-defface
@@ -2665,9 +2675,10 @@ FRAME 0 means change the face on all frames, and change the default
{
if (NILP (frame))
frame = selected_frame;
+ f = XFRAME (frame);
CHECK_LIVE_FRAME (frame);
- lface = lface_from_face_name (XFRAME (frame), face, false);
+ lface = lface_from_face_name (f, face, false);
/* If a frame-local face doesn't exist yet, create one. */
if (NILP (lface))
@@ -2989,11 +3000,11 @@ FRAME 0 means change the face on all frames, and change the default
else if (EQ (attr, QCfont))
{
#ifdef HAVE_WINDOW_SYSTEM
- if (EQ (frame, Qt) || FRAME_WINDOW_P (XFRAME (frame)))
+ if (EQ (frame, Qt) || FRAME_WINDOW_P (f))
{
if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value))
{
- struct frame *f;
+ struct frame *f1;
old_value = LFACE_FONT (lface);
if (! FONTP (value))
@@ -3013,28 +3024,29 @@ FRAME 0 means change the face on all frames, and change the default
signal_error ("Invalid font or font-spec", value);
}
if (EQ (frame, Qt))
- f = XFRAME (selected_frame);
+ f1 = XFRAME (selected_frame);
else
- f = XFRAME (frame);
+ f1 = XFRAME (frame);
/* FIXME:
If frame is t, and selected frame is a tty frame, the font
can't be realized. An improvement would be to loop over frames
for a non-tty frame and use that. See discussion in Bug#18573.
For a daemon, frame may be an initial frame (Bug#18869). */
- if (FRAME_WINDOW_P (f))
+ if (FRAME_WINDOW_P (f1))
{
if (! FONT_OBJECT_P (value))
{
Lisp_Object *attrs = XVECTOR (lface)->contents;
Lisp_Object font_object;
- font_object = font_load_for_lface (f, attrs, value);
+ font_object = font_load_for_lface (f1, attrs, value);
if (NILP (font_object))
signal_error ("Font not available", value);
value = font_object;
}
- set_lface_from_font (f, lface, value, true);
+ set_lface_from_font (f1, lface, value, true);
+ f1->face_change = 1;
}
}
else
@@ -3045,7 +3057,7 @@ FRAME 0 means change the face on all frames, and change the default
else if (EQ (attr, QCfontset))
{
#ifdef HAVE_WINDOW_SYSTEM
- if (EQ (frame, Qt) || FRAME_WINDOW_P (XFRAME (frame)))
+ if (EQ (frame, Qt) || FRAME_WINDOW_P (f))
{
Lisp_Object tmp;
@@ -3107,7 +3119,7 @@ FRAME 0 means change the face on all frames, and change the default
&& NILP (Fget (face, Qface_no_inherit))
&& NILP (Fequal (old_value, value)))
{
- face_change = true;
+ f->face_change = true;
windows_or_buffers_changed = 56;
}
@@ -3280,7 +3292,7 @@ update_face_from_frame_parameter (struct frame *f, Lisp_Object param,
if (!NILP (face)
&& NILP (Fget (face, Qface_no_inherit)))
{
- face_change = true;
+ f->face_change = true;
windows_or_buffers_changed = 57;
}
}