[Top][All Lists]

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

Re: Redisplay problems?

From: Eli Zaretskii
Subject: Re: Redisplay problems?
Date: Thu, 20 Mar 2014 20:12:56 +0200

> From: Stefan <address@hidden>
> Date: Thu, 20 Mar 2014 08:45:59 -0400
> Cc: Christian Lynbech <address@hidden>, James Cloos <address@hidden>,
>       Kan-Ru Chen (陳侃如) <address@hidden>,
>       address@hidden
> And of course, the frame's "garbaged" bit may not always be needed: if
> the frame was simply iconified+deiconified without any other change,
> there's no need to recompute matrices nor redraw anything, since it's
> pretty much the same as obscuring the frame with another and then
> exposing it again.

But exposing does require a kind of "redrawing", see below.

> I'm not 100% clear either, but my current understanding is that
> "garbaged" means that the frame needs to be fully redrawn in the
> following sense:
> Normal redisplay takes place by first computing new matrices, then
> comparing the old matrices to the new matrices to discover what needs to
> be changed on screen, then redrawing the parts that have changed.

Your description is slightly inaccurate, and on top of that, you use
several keywords in confusingly overloaded senses, which makes this
discussion harder to understand.

So allow me first to set the stage by making the description more

Redisplay includes 2 phases.  In the first phase, Emacs computes, for
every window, the desired glyph matrix, which describes what should be
on the display.  This stage includes some redisplay optimizations,
which can decide that certain portions of the display couldn't
possibly have changed, in which case the corresponding parts ("glyph
rows") of the desired matrix are marked "disabled".

In the second phase of redisplay, Emacs compares the desired matrix
with the "current matrix" (which was the desired matrix during the
previous redisplay cycle).  This stage also includes optimizations,
but of a different kind.  For each screen line, which corresponds to a
glyph row, Emacs redraws only the parts of that glyph row that are
different from the corresponding row of the current matrix, and it
also reuses what's on display as much as possible, even if they don't
match exactly.

Crucially, if the current matrix' glyph row is "disabled", the
corresponding screen line is redrawn in its entirety.  (If the desired
matrix' glyph row is "disabled", it is simply copied to the current
matrix without redrawing the line.)

When Emacs decides that some part of a glyph row needs to be redrawn,
it calls a function named draw_glyphs, which actually delivers the
glyphs to the glass by calling the display-specific back-end (xterm.c
etc.), after arranging the row's glyphs in "glyph strings", which make
the job easier for the back end.

> So "garbaged" means that we should not try to only redraw the parts that
> have changed.

When redisplay finds that a frame is "garbaged", it marks all of its
glyph matrix rows "disabled".  This will force their complete
redrawing, as described above.

> Note that the drawing that takes place in response to Expose events is
> not a "redraw": "redraw" is when a change inside Emacs causes a need to
> change the display, whereas expose events are due to changes outside
> of Emacs.

An expose event calls expose_frame, which walks the frame's window
tree, and redraws the part of each window that belongs to the exposed
rectangle.  This doesn't compute the glyph matrices at all, but just
calls draw_glyphs directly to redraw the portions of the glyph rows
that were exposed.  IOW, the existing current glyph matrix is used
without recomputing it.

> Part of the reason it's still fuzzy is that xdisp.c seems to recompute
> the matrices when it finds a "garbaged" frame, so it seems that it
> doesn't just cause it to "redraw".  I have the impression that this is
> a mistake in that it's more work than needed, and also in that some code
> relies on that behavior (i.e. it sets the bit to cause a complete
> redisplay+redraw).

I don't think I understand what you meant to say here.  But if you
were talking about what to do about a frame that was deiconified, I
think you need to call expose_frame, and arrange for the exposed
rectangle to cover the entire frame.  That should do what you want, no
more, no less.

reply via email to

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