[Top][All Lists]

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

Re: Question about display engine

From: Eli Zaretskii
Subject: Re: Question about display engine
Date: Fri, 16 Aug 2019 11:34:38 +0300

> Cc: address@hidden, address@hidden
> From: martin rudalics <address@hidden>
> Date: Fri, 16 Aug 2019 09:29:02 +0200
>  > Exactly.  More accurately, we have 2 problems: (1) how do you know you
>  > hit the stop point while going back; and (2) where do you go to
>  > compute the "next" stop point.  You don't want to know the answers...
> I'm not sure.  If that algorithm is newline agnostic, it will have to
> be changed if an eager (see below) solution is implemented.

Thankfully and mercifully, all the bidi calculations and hidden state
variables are reset at newlines.

>  > It will increase the cache, yes. Whether it will be significant is
>  > another question; I'm not sure.
> In the worst case it would double the size of the cache for
> implementing the background extension alone.  This looks like a
> veritable ordeal to me.  IIUC we do all this to keep the display
> optimizations (where we compare the glyph matrices) simple and
> efficient.  Or is there an additional twist to it?

Well, a face cache is rarely too large, it mostly holds a few dozen
faces.  We also clear it from time to time, so I don't think this
would be a catastrophe.

> One could argue that if, in the current implementation, the display
> element stops right before a newline character and that newline is,
> presumably, a separate display element, the overhead remains
> unchanged.  But AFAICT, font locking does not necessarily pay immense
> attention to newlines (Lisp comments and C strings excluded) so at
> least for displaying programming languages the overhead increase might
> be significant.

Actually, IME the situation where a face crosses a newline is somewhat

>  >> Since extend_face_to_end_of_line already switches to the default face
>  >> when no extension of the region is wanted
>  >
>  > It does? where?
> I thought it did so here
>        /* The last row's blank glyphs should get the default face, to
>        avoid painting the rest of the window with the region face,
>        if the region ends at ZV.  */
>        if (it->glyph_row->ends_at_zv_p)
>       it->face_id = default_face->id;
>        else
>       it->face_id = face->id;
> but apparently that's only a red herring.

This is a corner case, for the screen lines beyond EOB.  It is none of
our business for the purposes of this discussion.

> I currently see two ways to accomplish that: Eagerly, during face
> merging, we would have to search for and possibly create the extend
> face variation whenever the next stop point finding algorithm
> encounters a newline character within the object it examines.

Not my preference.  It will disrupt the neat algorithm of walking the
interval tree, or at least will force us to also search for a newline
(which is very fast, but still a complication).

> This means that any display element that contains a newline
> character also ends before that character and the entire logic of
> finding display elements changes.

What you call "display element" is actually called a "glyph string": a
sequence of glyphs that have the same face.  The division of glyphs
into glyph strings happens as part of preparing glyphs for display,
and will automatically pay attention to changes in the face ID.  So no
logic changes here.  The changes are as I described above: where we
compute the next stop position.  there' we will have to see whether
the stretch of text till the next stop includes a newline.

> A lazy variant would have the display engine itself create the extend
> face by demand whenever it encounters a newline character within the
> current display element.

I'd prefer this method.  Two reasons: (1) it is localized to the code
which may need such a face; and (2) it scales better, because the
display code is frequently invoked on short portions of the text, so
there's no guarantee that it will actually get to producing glyphs
with the "extension" variant of the face, so realizing that face in
advance might well be waste of unneeded effort, because the additional
face will never be used.

> The worst aspect of all this is that there is no simpler solution even
> if we attempted a different implementation of the extend logic.
> Suppose I used just one single, global variable to turn off/on any
> face extensions.  For turning it off, I'd still have to, at the end of
> every line, assure that a separate realized face does implement the
> "off" interpretation while the "on" interpretation is already provided
> by the last face on that line.  Right?

Yes, we will typically need that "on" face for the next screen line.

reply via email to

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