diff options
| author | Ken Raeburn | 2015-10-03 00:15:54 -0400 |
|---|---|---|
| committer | Ken Raeburn | 2015-10-08 01:19:49 -0400 |
| commit | b8eea1d7b1485a147f112127c0ca58cb1a0a8ebb (patch) | |
| tree | 215730e1b1fc26ea26a37f4b454c6da138be4c28 /src/xterm.c | |
| parent | 0360b7f2c4f0358106e229de4dfe91a67445a50c (diff) | |
| download | emacs-b8eea1d7b1485a147f112127c0ca58cb1a0a8ebb.tar.gz emacs-b8eea1d7b1485a147f112127c0ca58cb1a0a8ebb.zip | |
Cache XParseColor results in the X display info structure.
With repeated lookups of foreground and background colors for multiple
faces per frame, we issue a lot of redundant color name lookups to the
X server, waiting every time for the response. On a remote network
with, say, 30ms round-trip time, this can add nearly a full second to
creation of a new frame.
* src/gtkutil.c (xg_check_special_colors): Call x_parse_color.
* src/image.c (get_spec_bg_or_alpha_as_argb):
(xpm_init_color_cache, xpm_lookup_color):
* src/xfns.c (x_defined_color):
* src/xterm.c (x_parse_color): New function; caches color names not
starting with "#" in the display-info structure.
(x_delete_display): Delete the cache content.
* src/xterm.h (struct color_name_cache_entry): New type.
(x_parse_color): Declare.
(struct x_display_info): Add a new field for the cache.
Diffstat (limited to 'src/xterm.c')
| -rw-r--r-- | src/xterm.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/src/xterm.c b/src/xterm.c index dd54552510c..6065f964063 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -2223,6 +2223,52 @@ x_query_color (struct frame *f, XColor *color) | |||
| 2223 | } | 2223 | } |
| 2224 | 2224 | ||
| 2225 | 2225 | ||
| 2226 | /* On frame F, translate the color name to RGB values. Use cached | ||
| 2227 | information, if possible. | ||
| 2228 | |||
| 2229 | Note that there is currently no way to clean old entries out of the | ||
| 2230 | cache. However, it is limited to names in the server's database, | ||
| 2231 | and names we've actually looked up; list-colors-display is probably | ||
| 2232 | the most color-intensive case we're likely to hit. */ | ||
| 2233 | |||
| 2234 | Status x_parse_color (struct frame *f, const char *color_name, | ||
| 2235 | XColor *color) | ||
| 2236 | { | ||
| 2237 | Display *dpy = FRAME_X_DISPLAY (f); | ||
| 2238 | Colormap cmap = FRAME_X_COLORMAP (f); | ||
| 2239 | Status status; | ||
| 2240 | struct color_name_cache_entry *cache_entry; | ||
| 2241 | |||
| 2242 | if (color_name[0] == '#') | ||
| 2243 | { | ||
| 2244 | /* The hex form is parsed directly by XParseColor without | ||
| 2245 | talking to the X server. No need for caching. */ | ||
| 2246 | return XParseColor (dpy, cmap, color_name, color); | ||
| 2247 | } | ||
| 2248 | |||
| 2249 | for (cache_entry = FRAME_DISPLAY_INFO (f)->color_names; cache_entry; | ||
| 2250 | cache_entry = cache_entry->next) | ||
| 2251 | { | ||
| 2252 | if (!xstrcasecmp(cache_entry->name, color_name)) | ||
| 2253 | { | ||
| 2254 | *color = cache_entry->rgb; | ||
| 2255 | return 1; | ||
| 2256 | } | ||
| 2257 | } | ||
| 2258 | |||
| 2259 | if (XParseColor (dpy, cmap, color_name, color) == 0) | ||
| 2260 | /* No caching of negative results, currently. */ | ||
| 2261 | return 0; | ||
| 2262 | |||
| 2263 | cache_entry = xzalloc (sizeof *cache_entry); | ||
| 2264 | cache_entry->rgb = *color; | ||
| 2265 | cache_entry->name = xstrdup (color_name); | ||
| 2266 | cache_entry->next = FRAME_DISPLAY_INFO (f)->color_names; | ||
| 2267 | FRAME_DISPLAY_INFO (f)->color_names = cache_entry; | ||
| 2268 | return 1; | ||
| 2269 | } | ||
| 2270 | |||
| 2271 | |||
| 2226 | /* Allocate the color COLOR->pixel on DISPLAY, colormap CMAP. If an | 2272 | /* Allocate the color COLOR->pixel on DISPLAY, colormap CMAP. If an |
| 2227 | exact match can't be allocated, try the nearest color available. | 2273 | exact match can't be allocated, try the nearest color available. |
| 2228 | Value is true if successful. Set *COLOR to the color | 2274 | Value is true if successful. Set *COLOR to the color |
| @@ -12119,6 +12165,7 @@ static void | |||
| 12119 | x_delete_display (struct x_display_info *dpyinfo) | 12165 | x_delete_display (struct x_display_info *dpyinfo) |
| 12120 | { | 12166 | { |
| 12121 | struct terminal *t; | 12167 | struct terminal *t; |
| 12168 | struct color_name_cache_entry *color_entry, *next_color_entry; | ||
| 12122 | 12169 | ||
| 12123 | /* Close all frames and delete the generic struct terminal for this | 12170 | /* Close all frames and delete the generic struct terminal for this |
| 12124 | X display. */ | 12171 | X display. */ |
| @@ -12148,6 +12195,15 @@ x_delete_display (struct x_display_info *dpyinfo) | |||
| 12148 | tail->next = tail->next->next; | 12195 | tail->next = tail->next->next; |
| 12149 | } | 12196 | } |
| 12150 | 12197 | ||
| 12198 | for (color_entry = dpyinfo->color_names; | ||
| 12199 | color_entry; | ||
| 12200 | color_entry = next_color_entry) | ||
| 12201 | { | ||
| 12202 | next_color_entry = color_entry->next; | ||
| 12203 | xfree (color_entry->name); | ||
| 12204 | xfree (color_entry); | ||
| 12205 | } | ||
| 12206 | |||
| 12151 | xfree (dpyinfo->x_id_name); | 12207 | xfree (dpyinfo->x_id_name); |
| 12152 | xfree (dpyinfo->x_dnd_atoms); | 12208 | xfree (dpyinfo->x_dnd_atoms); |
| 12153 | xfree (dpyinfo->color_cells); | 12209 | xfree (dpyinfo->color_cells); |