From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Eli Zaretskii Newsgroups: gmane.emacs.devel Subject: Re: Scrolling commands and skipping redisplay, was: Re: emacs rendering comparisson between emacs23 and emacs26.3 Date: Fri, 24 Apr 2020 12:51:21 +0300 Message-ID: <83lfmlb49y.fsf@gnu.org> References: <20200403174757.GA8266@ACM> <542b48ba-4dfa-820f-ba50-4b147ab6d8e2@yandex.ru> <0a5f70aa-4985-8f8d-81d6-6ac4a60a94f9@yandex.ru> <838sj8sphk.fsf@gnu.org> <834ktwsmfw.fsf@gnu.org> <83imibqsmm.fsf@gnu.org> <478c2aab-a5fc-61c2-02e2-2d9846b95273@yandex.ru> <83v9m9nltx.fsf@gnu.org> <83tv1rn8fx.fsf@gnu.org> <4f8bb277-b376-97bf-8539-799688d8e66d@yandex.ru> <83eesvmj15.fsf@gnu.org> <6eec7f68-770e-b3b1-4627-6222f3ef7216@yandex.ru> <83ftd9kwlu.fsf@gnu.org> <1de9d24f-eeb7-7d0a-3768-4baba4365066@yandex.ru> <83zhbcdmyi.fsf@gnu.org> <61f565cd-4fee-d48c-a9ef-b78419b3d058@yandex.ru> <83wo6ed4kb.fsf@gnu.org> <464b5639-7790-fdbc-b519-22a6b0e8c016@yandex.ru> <83o8rqaucp.fsf@gnu.org> <83lfmqgpb9.fsf@gnu.org> <83mu75ey3k.fsf@gnu.org> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="130569"; mail-complaints-to="usenet@ciao.gmane.io" Cc: acm@muc.de, rrandresf@gmail.com, emacs-devel@gnu.org, rms@gnu.org, rudalics@gmx.at To: Dmitry Gutov Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Fri Apr 24 11:52:27 2020 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jRv0U-000XqF-T7 for ged-emacs-devel@m.gmane-mx.org; Fri, 24 Apr 2020 11:52:26 +0200 Original-Received: from localhost ([::1]:57836 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jRv0T-0000Ac-Ri for ged-emacs-devel@m.gmane-mx.org; Fri, 24 Apr 2020 05:52:25 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:33408) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jRuzs-0007sB-Ps for emacs-devel@gnu.org; Fri, 24 Apr 2020 05:51:49 -0400 Original-Received: from fencepost.gnu.org ([2001:470:142:3::e]:42628) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jRuzq-0004n8-60; Fri, 24 Apr 2020 05:51:46 -0400 Original-Received: from [176.228.60.248] (port=2955 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1jRuzf-0007iF-VU; Fri, 24 Apr 2020 05:51:37 -0400 In-Reply-To: (message from Dmitry Gutov on Fri, 24 Apr 2020 04:23:57 +0300) X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 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-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:247679 Archived-At: > Cc: acm@muc.de, rudalics@gmx.at, rrandresf@gmail.com, rms@gnu.org, > emacs-devel@gnu.org > From: Dmitry Gutov > Date: Fri, 24 Apr 2020 04:23:57 +0300 > > > I suggest to use a common terminology, otherwise we will just confuse > > each other. Let's agree to call "redisplay" only what happens when > > Emacs calls one of the two functions: redisplay_internal and > > echo_area_display. OK? Redisplay calls many functions, including > > fontification-functions, but those functions themselves are not to be > > called "redisplay", because they don't display anything. > > Do scrolling commands and/or code that calls posn-at-point do anything > else common with redisplay other than fontification functions? "Common" is too general a word to give an intelligent and helpful answer to your question. I have no other way except explaining a lot of how relevant parts of the display engine work (below), or else we will be forever trapped in misunderstandings. (I do suggest to read the commentary and the code in xdisp.c, to facilitate better communications. It takes time and non-trivial effort to write these descriptions.) > For instance, converting the buffer text into some other structure that > rendering the window will be based on. I think you called it a "glyphs > table" or something like that. You mean the glyph matrices. There are two matrices for each window on display: the "current" matrix and the "desired" matrix. The current matrix describes what's currently on the glass. The desired matrix is created during each redisplay cycle and describes what _should_ be on the glass; it is generally sparse, i.e. holds only parts of the window's screen lines, because the display engine decided only those parts need to be updated for this cycle. The desired matrix is used to update what's on the glass, and then its "glyph rows" (each row corresponds to a screen line) are copied into the current matrix (thus making the current matrix up-to-date), and then the desired matrix is discarded. Glyph rows in the desired matrix are produced by the functions display_line (which handles buffer text and any display/overlay strings put on buffer text via text properties and overlays), and display_string (which handles Lisp or C strings unrelated to any buffer, like what we do with mode/header/tab-line, menu-bar on TTY and non-toolkit GUI frames, etc.) These two functions use the "iterator" object ('struct it', see dispextern.h) to iterate the object, whether a buffer or a string, one character position at a time, and produce the glyph structures which are elements of glyph rows. The iteration includes a lot of logic, but basically is built on 3 low-level subroutines: set_iterator_to_next (which moves the iterator to the next "display element"), get_next_display_element (which figures out what kind of display element -- a character, a character composition, an image, a stretch of white space, an xwidget -- is that element, and fills the relevant fields of the iterator object with the data for that element), and PRODUCE_GLYPHS, which is a macro that invokes a produce_glyphs method of the window's frame, and fills up the glyph structure of the next element of the glyph row. The produce_glyphs method also updates the running row metrics fields within the iterator object, ones that keep track of the current pixel position, the height, ascent, and descent of the row, etc. JIT fontification happens inside get_next_display_element, when it detects that it came upon buffer text that doesn't have a non-nil 'fontified' property. Scrolling commands, posn-at-point, and others that need layout information of any kind, use the functions that simulate the display. Those functions do NOT produce any glyph rows. They use the move_it_in_display_line function, which invokes the same 3 subroutines as display_line and display_string, and with a similar surrounding logic, but their only purpose is to move the iterator object in the same way as redisplay would, keeping the metrics, but without producing any glyphs. I hope you can now figure out the answer to your question about the "common" parts. > If *that* work (together with fontification) is usually what takes the > most time during redisplay This remains to be shown. Someoneā„¢ should profile redisplay in relevant use cases and present the profiles, then we could decide whether this is or isn't the case. Personally, I think it's roughly 40%-60% or 30%-70%, with the actual redisplay being the larger part. But humans are notoriously bad in guessing this stuff, so I won't be surprised if mine turns out to be wrong. > there could be some simple cache added on to of it, which would make > skipping redisplay unnecessary in cases when the command would > pre-fill such cache. I have my doubts that it will turn out to be simple. Besides my humble experience of hacking the display code, I have a much more significant evidence: that such a cache was not implemented when the current display engine was developed for Emacs 21. Gerd Moellmann is an extremely capable and talented programmer, and most of the work he did on the display engine during Emacs 21 development was precisely to make it fast enough. All the redisplay optimizations we have now were designed and implemented for that purpose, because without them redisplay was unbearably slow on the machines we had at that time. At some point Gerd wrote that he implemented these optimizations one by one, until he got satisfactory redisplay speed. If there was a simple way of caching more data to speed this up, I have no doubt we'd have that already. Of course, no one is perfect, so it could be that some opportunities were missed. Ideas and patches are welcome, together with timings and profiles to show their utility.