From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Alan Mackenzie Newsgroups: gmane.emacs.devel Subject: Re: Aborting display. Is this possible? Date: Mon, 20 Oct 2014 18:57:57 +0000 Message-ID: <20141020185757.GD2947@acm.acm> References: <20141019141712.GB3197@acm.acm> <83lhoccdv7.fsf@gnu.org> <20141019154255.GC3197@acm.acm> <83egu4c4om.fsf@gnu.org> <20141020110949.GA2947@acm.acm> <8338aidbcq.fsf@gnu.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1413831548 21887 80.91.229.3 (20 Oct 2014 18:59:08 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 20 Oct 2014 18:59:08 +0000 (UTC) Cc: emacs-devel@gnu.org To: Eli Zaretskii Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Oct 20 20:59:01 2014 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1XgIAW-0004yt-AW for ged-emacs-devel@m.gmane.org; Mon, 20 Oct 2014 20:59:00 +0200 Original-Received: from localhost ([::1]:46392 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XgIAV-0007ge-Rn for ged-emacs-devel@m.gmane.org; Mon, 20 Oct 2014 14:58:59 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:45938) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XgIAO-0007gZ-A9 for emacs-devel@gnu.org; Mon, 20 Oct 2014 14:58:57 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XgIAJ-0006D3-29 for emacs-devel@gnu.org; Mon, 20 Oct 2014 14:58:52 -0400 Original-Received: from colin.muc.de ([193.149.48.1]:22393 helo=mail.muc.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XgIAI-0006Bw-Iu for emacs-devel@gnu.org; Mon, 20 Oct 2014 14:58:46 -0400 Original-Received: (qmail 14132 invoked by uid 3782); 20 Oct 2014 18:58:44 -0000 Original-Received: from acm.muc.de (pD951B873.dip0.t-ipconnect.de [217.81.184.115]) by colin.muc.de (tmda-ofmipd) with ESMTP; Mon, 20 Oct 2014 20:58:43 +0200 Original-Received: (qmail 5028 invoked by uid 1000); 20 Oct 2014 18:57:57 -0000 Content-Disposition: inline In-Reply-To: <8338aidbcq.fsf@gnu.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Delivery-Agent: TMDA/1.1.12 (Macallan) X-Primary-Address: acm@muc.de X-detected-operating-system: by eggs.gnu.org: FreeBSD 8.x X-Received-From: 193.149.48.1 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:175605 Archived-At: Hello, Eli. On Mon, Oct 20, 2014 at 06:12:05PM +0300, Eli Zaretskii wrote: > > Date: Mon, 20 Oct 2014 11:09:49 +0000 > > Cc: emacs-devel@gnu.org > > From: Alan Mackenzie > On a large C Mode buffer (such as xdisp.c), hold down the PageDown key > > for, say, 10 seconds. > > What is seen: The screen freezes. After releasing the key, it takes many > > seconds (~10) before the current buffer position is displayed on the > > screen. Incidentally, I saw this happening today in emacs-lisp-mode, on my terminal with a 3 column follow-mode. > > What I'd like to see: The screen continuously updating with (not > > necessarily contiguous) parts of the buffer, the updating being frequent > > enough to give the illusion of continuous scrolling. On releasing the > > key, the screen "instantly" displaying the new buffer position. > I understand the desire, and I'm not saying it isn't reasonable. So > please don't take what's below as a rebuttal; I'm just trying to > explain how the current Emacs design works against your wishes, and > what could/should be changed for your wishes to maybe become reality. > I will probably say some (or many) things that you already know, so > please bear with me. Thanks for such a clear exposition. > First, Emacs's basic design is that it processes all the available > input before it enters redisplay. As long as there's input in the > input queue, Emacs will not call redisplay. (There are 2 exceptions > to this rule: processing input could indirectly call the 'redisplay' > function; and messages in the echo area produced while processing > input require a kind of "partial" redisplay to show the echo area.) > Why? because processing input allows to avoid showing the user a > screen that is outdated from the user's POV, given that input more > often than not changes what should be displayed. Up to now, I think I've been confusing display with font-locking. Obviously f-l has to happen when d is being done, but not all font-locking is caused by display. > Another part of this puzzle is that redisplay includes fontification > of the visible portion of the buffer. Emacs applies the font-lock > faces (and any other faces) during the 1st stage of its redisplay > cycle, when it computes the so-called "glyph matrices", which are data > structures maintained for each window that describe what the updated > screen should look like. As David points out, it is impossible to > compute the glyph matrices without applying the faces, because faces > change the metrics of each character, and thus affect the layout, > which is what glyph matrices are all about. > The final part of the puzzle is what the scroll-up-command does when > Emacs processes a single PageDown keypress. It computes the new > starting point for the window, which (if we neglect complications) is > simply the beginning of line N screen lines below the original window > start, where N is almost the height of the window. (Note that I wrote > "screen lines", not "physical lines", so this is not entirely trivial > when there are continuation lines and variable-size fonts.) Then it > determines whether this change of the window-start requires to move > point to bring it into the view, and if so, moves point as well. On a PageDown, Emacs needs to do font-locking just to work out how far awy the next page is, like David said. There is a comment in window_scroll_line_based: "Fvertical_motion enters redisplay, which can trigger fontification...". This is the killer: scrolling a screen of xdisp.c is taking, on average, ~0.09s, the bulk of this time being fontification, whereas the key events are coming in every ~0.03s. Some way has to be found to scroll with only every third screen (at most) getting font-locked. If every glyph were assumed to be the same size, the calculation of the window-start position for the current scroll operation would be _much_ faster: display would still have to account for text lines overflowing screen lines, and invisible text, and so on, So, how about the following strategy: when the (new) variable `face-instead-of-fontifying' is bound to a face, AND the input queue is non-empty (or, perhaps, very non-empty), the appropriate subroutine of window-scroll should deem characters without a `face' (or `fontified' ?) property to have face `face-instead-of-fontifying'. This should empty the input queue pretty quickly, enabling a current buffer portion to get displayed frequently enough. > So, after processing a single PageDown key, the window has a new > starting point, and point in that window's buffer has been moved. > If, after processing this single PageDown key, the input queue is > empty (as it is when you lean on the key, because Emacs finishes the > above processing in less time than the auto-repeat interval), Emacs > enters redisplay. Redisplay computes the glyph matrix of the window > given its start point as set by scroll-up-command; as part of this > matrix computation, the display engine applies all the font-lock > properties to the text, and sets the 'fontified' property on that > text. Then, just before it is about to redraw the window given the > new glyph matrix, it checks for input. If there's input available, > and redisplay-dont-pause is nil, the window will not be redrawn, > i.e. this redisplay cycle will be aborted. But in the default situation (redisplay-dont-pause is non-nil), once the calculation of the glyph matrix has begun, the redrawing necessarily takes place. This is good. :-) > Then the same will happen again for the next PageDown key. The result > is a frozen window display, because all the attempts to redisplay are > aborted due to input rate that is high enough to preempt redisplay, > but not high enough to prevent Emacs from entering redisplay after > every (or almost every) PageDown key. To see more frequent updates > that give an illusion of scrolling, we would need a feature that > ignores the input availability, or maybe dynamically changes the > number of input events that could be ignored when redisplay falls > behind. We don't have such a feature. Is this really the case? Is it not that the font-locking caused by scrolling is slow enough, that the input queue is never empty, hence redisplay doesn't get a look in? > Now, what happens when you release the key? The input queue is still > full of unprocessed PageDown keys. As I explained above, Emacs will > drain the entire input queue before it enters redisplay; thus the long > delay you see after releasing the key. And each such PageDown key will necessitate full font-locking for its never-to-be-displayed screen. > You want Emacs to "immediately" display the new buffer position, but > this is impossible without some code that would quickly scan the input > queue, analyze what's there, and "understand" that 100 PageDown > keystrokes can be "optimized" by executing a single scroll-up-command > with a suitable argument. IOW, we would need some input preprocessing > stage that could "optimize" input by replacing a series of commands > with a single command, and do that cheaply. We don't have such a > feature; patches to add it will probably be welcome. :-). If my analysis is right, this wouldn't help. A single mega-scroll would still be font-locking the entire intermediate buffer region. -- Alan Mackenzie (Nuremberg, Germany).