emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Scrolling commands and skipping redisplay, was: Re: emacs rendering comp


From: Dmitry Gutov
Subject: Scrolling commands and skipping redisplay, was: Re: emacs rendering comparisson between emacs23 and emacs26.3
Date: Thu, 9 Apr 2020 03:32:13 +0300
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.4.1

Hi Eli,

On 07.04.2020 17:26, Eli Zaretskii wrote:

If so, I don't understand how we get the apparent performance improvement from 
using fast-but-imprecise-scrolling.

To explain that, I need to step back and describe how jit-lock
mechanism works, from the display engine POV, and then how the scroll
commands work.  (See also a large commentary in keyboard.c around line
250.) <...>

Thank you, what was a lot of additional detail.

The overall approach seems well-considered, but maybe there are ways to make it more... predictable, so to speak. Or more helpful.

If you lean on C-v, then the scroll command is repeatedly called to
find the next window-start, and repeatedly fontifies the text it goes
through.  If you scroll N screen-fulls, the fontification of the first
N-1 screen-fulls (if they were never displayed before, which happens
when you visit a file and immediately start scrolling) is "wasted
effort" for the purposes of the final window redisplay, because those
N-1 screen-fulls will not be displayed.  Only the fontification of the
last screen-full is "useful", because it saves some, sometimes all, of
the fontification job of the stuff to be eventually displayed when you
stop scrolling.

As you noted, when fontification takes a considerable amount of time, redisplay should be "free", relatively speaking. And if we didn't skip it, it would provide the user with the feedback that something is indeed happening.

Enter fast-but-imprecise-scrolling.  What it does is disable jit-lock
during the part where the scroll command walked the buffer to find the
next window-start position.  Crucially, it also disables putting the
non-nil 'fontified' property on the text traversed by the scroll
command (because that is done by jit-lock).  So when you stop
scrolling, redisplay of the stuff that ends up in the window will have
to fontify all of what is visible in the window.

The obvious downside here is that it's "imprecise". And that it doesn't really know whether redisplay is going to be skipped, even though it could take a pretty good guess (using the input_was_pending variable, for example). If the user has leaned on C-v, they are probably not looking for much precision. But they might want it if they just pressed C-v once.

Of course, if fast-but-imprecise-scrolling makes the job of scroll
commands so much easier that Emacs is capable of keeping up with the
keyboard auto-repeat rate, then every screen-full you scroll through
_will_ be displayed, and therefore will be fontified by the calls to
jit-lock from redisplay itself -- and that will again make scrolling
slower.  So fast-but-imprecise-scrolling is most efficient when it
makes scroll commands faster, but not too fast...

In my testing with an '-Og -g3' build (from emacs-27; master is much faster with the recent tweaks) it allows for redisplay once every several screenfuls or so. So it seems like a good tradeoff, in those particular conditions.

I wonder if we could make it more coordinated. The two problems I see are:

1. Scrolling commands can skip jit-lock when redisplay is going to apply it (loss of precision for no actual perf improvement), or they don't skip it (when fast-but-... is nil) even though redisplay will (precision seems unimportant in most pending-input scenarios). 2. If we accumulate a large enough input queue of C-v keypresses, Emacs won't react to anything (even to C-g, even hit three times) until it processes these events. Even though the user most probably wanted it to stop scrolling just as soon as they stopped leaning on C-v.

I think #2 can have good solutions, but I only have rough suggestions about that.

But let's look at #1. We could fix the discrepancy in two ways: either skip jit-lock in window_scroll if and only if redisplay will likely be skipped (as shown in the attached patch) (a). Or never skip it there, as well as indicate to redisplay that it shouldn't be skipped either (b).

(a) will increase reactivity, as well as make it harder to overwhelm the input queue, which will be perceived by a number of users (who manage to hit these conditions and have slow enough machines) as better responsiveness.

(b) will let the user see what's happening instead, even though the scrolling will become slower. I think this is a plus in its own right, because scrolling is a visual activity; there's little point in doing it if you can't see where you scrolled to. We can probably implement this by setting input_was_pending unconditionally to false inside window_scroll.

Logically, I think I'd prefer (b), especially if a solution for #2 was added as well. Because as soon as #2 is solved, (a)'s benefit isn't so clear anymore.

But either (a) or (b), both look more responsive to me than the current state of affairs.

Attachment: fast_scroll_on_pending_input.diff
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]