Subject: bug#77039: 31.0.50; Flickering on macOS

From: Eli Zaretskii <[email-masked]>
Date: Sun, 23 Mar 2025 18:39:04 +0200

> Date: Sun, 23 Mar 2025 16:03:17 +0000
> Cc: [email-masked], [email-masked], [email-masked]
> From: "Aaron Jensen" <[email-masked]>
> 
> On Sun, Mar 23, 2025 at 3:37 AM, Eli Zaretskii <[email-masked]> wrote:
> 
>  Cc: [email-masked], [email-masked], [email-masked] Date: Sun, 23 Mar 2025
>  12:13:10 +0200 
>  From: Eli Zaretskii <[email-masked]> 
> 
>  So in summary, I don't see anything abnormal here. If we want to keep the
>  only-current-line-changed optimization in redisplay_internal, someone will have to come up with a
>  smarter test for when line numbers are shown. I think the underlying problem is that when the line
>  number of the current line becomes large enough to require more columns for line-number
>  display, we must redraw the entire window to avoid the problem with shifting or line number
>  described in https://debbugs.gnu.org/cgi/bugreport.cgi?bug=54091#5 . 
> 
>  To clarify: this should not cause any flickering, AFAIU, because the comparison of glyphs in
>  subroutines of update_frame is supposed to find that everything on the glass is already up-to-date and
>  there's no need to draw anything. So flickering, which happens because portions of the window are
>  actually redrawn on the glass, should not happen in this case.
> 
> Right, I don't observe any flickering.

OK, so I think we are good.

> Am I correct that it is only comparing the glyphs on the current
> line?

No, I think in the case we were analyzing it compares the glyphs of
the entire window, or its large parts.

> If
> so, that doesn't seem like a huge problem, even though it is (in most cases?) technically extra work.

For this extra work to be spared, someone has to devise a method of
examining the buffer and the window before actually redrawing it, and
deciding that no update is needed, and do it cheaply enough to yield
net savings.

You should keep in mind the basic problem redisplay needs to solve.
It doesn't react to each and every change in the buffers and other
structures that affect display.  Instead, it is called when Emacs
thinks it's good time to maybe redisplay, and it needs to decide, just
by looking at the buffers as they are at that time, what has changed
since last redisplay and how those changes might affect the windows on
display.  When the first phase of redisplay cannot safely exclude the
need for redrawing a window or some of its parts, it produces the
"desired" glyph matrices for those parts, which describe how those
parts _should_ look, and leaves it to the second phase to decide what,
if anything, should actually be redrawn on the glass, by comparing the
desired matrix with the current matrix (which describes what _is_ on
the glass).  Thus, this second phase, which is where the comparison of
the glyphs happens, is the "last line of defense" against unnecessary
redrawing, which would otherwise cause flickering and is relatively
expensive.

It is in many cases impossible to know whether a particular change in
buffer text will require large portions of a window to be redrawn,
without actually doing the layout work that produces the desired
matrix.  That's because the layout of glyphs is a complex process with
many tricky rules, which all but preclude fast and cheap decisions
like that except in very simple cases.  For example, insertion of a
single character in a middle of bidirectional text can completely
change the way characters are laid out on the glass.  So the simple
cases are detected and handled by "redisplay optimizations" of the
first phase of redisplay, and the rest is left to the second phase,
which prevents unnecessary redraws based on glyph comparison.