|
From: | Jan D. |
Subject: | Re: Display performance degradation |
Date: | Thu, 17 Dec 2009 08:39:50 +0100 |
User-agent: | Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.5) Gecko/20091204 Thunderbird/3.0 |
On 2009-12-17 03:49, YAMAMOTO Mitsuharu wrote:
I can observe significant display performance degradation on Emacs 23.1.90 compared with 23.1, especially when scrolling TUTORIAL.ja on a frame that uses the xft font backend. I also observe the increase of the total number of xftfont_draw calls, and a string in a single font and color, which was originally displayed by one call, is now unnecessarily divided into smaller units. As an experiment, I tried restoring the following change, and then the performance became comparable to 23.1.
The basic question is why is this called so much? It is a fundamental flaw in Emacs that makes it hard to add new stuff without degrading performance. The core problem is that Emacs internally doesn't track what is changed. So it re-evaluates faces, fonts, menus, toolbars and so on, all the time before redisplay, and 99.99% of those times, nothing has changed. So to speed things up, we have various caches to check if things are the same as before. But these caches cause problems elsewhere. For example, if a new font is added or if /etc/font.conf is changed, Emacs must be restarted because caches prevents Emacs from noticing the change.
In particular, this cache prevents Emacs from picking up changes in hintstyle or dpi or other font-related redering parameters.
Emacs should to things all the way to get rid of this problem. Now, when a menu for exampls is changed in lisp, the actual widgets on the screen are not changed until later. So there is no connection between the change and the update on the screen. So Emacs re-evaluates menus a lot of times just to be sure, in case something changed at the lisp level. Instead the lisp change should lead to a screen change at once. That way we know that the menu is up to date and we don't have to re-evaluate it. The same is true for faces, which I assume causes this problem.
I don't know if this particular problem can be worked around, probably there is a way with different caching and/or status flags, but it will be just another band-aid. The real problem is harder to fix.
Jan D.
2009-11-17 Jan Djärv<address@hidden> * font.c (font_open_entity): Do not use cache, it does not pick up new fontconfig settings like hinting. *** 2975,2985 **** --- 2987,3001 ---- else if (CONSP (Vface_font_rescale_alist)) scaled_pixel_size = pixel_size * font_rescale_ratio (entity); + #if 0 + /* This doesn't work if you have changed hinting or any other parameter. + We need to make a new object in every case to be sure. */ for (objlist = AREF (entity, FONT_OBJLIST_INDEX); CONSP (objlist); objlist = XCDR (objlist)) if (! NILP (AREF (XCAR (objlist), FONT_TYPE_INDEX)) && XFONT_OBJECT (XCAR (objlist))->pixel_size == pixel_size) return XCAR (objlist); + #endif val = AREF (entity, FONT_TYPE_INDEX); for (driver_list = f->font_driver_list; The added comment implies that the simple removal of #if 0 causes another problem for some cases, but I think creating a new font object for each call is too much for the usual cases. Perhaps this part needs some improvement. YAMAMOTO Mitsuharu address@hidden
[Prev in Thread] | Current Thread | [Next in Thread] |