unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Eli Zaretskii <eliz@gnu.org>
To: Daniel Colascione <dancol@dancol.org>, Ken Raeburn <raeburn@raeburn.org>
Cc: emacs-devel@gnu.org
Subject: Re: RFC: flicker-free double-buffered Emacs under X11
Date: Mon, 24 Oct 2016 11:05:29 +0300	[thread overview]
Message-ID: <838tte5fzq.fsf@gnu.org> (raw)
In-Reply-To: <r025h982bxhm.fsf@dancol.org> (message from Daniel Colascione on Sun, 23 Oct 2016 13:51:01 -0700)

> From: Daniel Colascione <dancol@dancol.org>
> Cc: emacs-devel@gnu.org
> Date: Sun, 23 Oct 2016 13:51:01 -0700
> 
> > I meant the test for the lone font backend that needs this kludge, not
> > for the existence of the method.  And also a comment that tells it's a
> > kludge whose need we understand only empirically.  I'd even prefer a
> > direct call to the function when the font backend is the one which
> > needs it, rather than having a method created for the benefit of a
> > single backend, whose necessity we don't really understand.
> 
> So we want to write?
> 
>   for font_backend in frame.font_backends:
>     if instanceof(font_backend, XftBackend):
>       xft_refresh_hack()
> 
> That still strikes me as less clean, especially considering we'll have
> to provide the xft_refresh_hack to general-purpose code.

At the very least let's have a comment there saying that this is a
kludge that's actually done only for that font driver.  (Comments tend
to fall out of sync with the code, so making code speak for itself is
better, but a comment is infinitely better than nothing at all.)

> > I'm not saying the code won't work.  I'm saying it could make its
> > purpose more evident, which is better for long-term maintainability.
> 
> Longer-term, I think we need to move toward greater, not
> lesser, modularity.

I agree, but IME such a move cannot be piecemeal in this case, it must
be done in one go, or in a small number of large steps.  IOW, it's a
significant job on its own.

> >> We need to do a buffer flip at the end of redisplay for each frame on
> >> which update_end was called during redisplay.
> >
> > Even if update_end was called for a frame whose update was "paused",
> > i.e. whose redisplay was interrupted by incoming input?
> 
> Right now, we do a buffer flip unconditionally except in the case that
> we `goto end_of_redisplay`. I think that's a bug actually --- but I have
> to understand more of what this logic is actually doing.
> 
> Why _do_ we have a path that short-circuits the rest of the redisplay
> code? What would happen if we just removed it? It appears to be some
> kind of optimization, and I'm not sure it's actually necessary
> (especially since, according to the comment, we disable it anyway in the
> case of a blinking cursor).

It's an optimization for the case that nothing needs to be
redisplayed.

But I wasn't asking about that, I was asking about this part:

		  pending |= update_frame (f, false, false);

If update_frame returns non-zero, we don't mark all the windows as
having accurate display, which will cause redisplay to be re-entered
again on the first opportunity, and it will then try to redisplay all
of them again.  I was asking whether flipping in this case is TRT.

Without double buffer, what happens in this case is that we could
momentarily flash a partially redrawn window.

> I suppose you could make an argument for not doing a buffer flip if
> redisplay is interrupted by input, but I'm honestly not sure what might
> go wrong there, and my preference would be to act as much like the
> single-buffered case as possible and default, if we're unsure, to
> showing the results of our painting efforts to the user.

OK, we can always wait for bug reports, I guess, and take it from
there.

> > My problems start with the name of the hook, which doesn't hint at all
> > that only double-buffered X11 back-end cares about that.  If the hook
> > was called something like double_buffer_flip_hook, or was compiled
> > only if HAVE_XDBE is defined, this issue would go away.
> 
> So let's call it double_buffer_flip_hook.

Great, let's.

> > IOW, if the code speaks for itself, it makes maintenance of this
> > hyper-convoluted piece of Emacs easier, less time consuming, and less
> > error prone.
> 
> This code is an adventure.

It is.

> >> I'm also worried about maintainability: that's why I don't want to make
> >> redisplay_internal any more of a big ball of mud than it already is.
> >
> > It's too late for that.  It's already an extremely complex and hard to
> > understand piece of code.  Hiding more information from its logic
> > makes the code harder to maintain, not easier.  We are not talking
> > about highly-modular package, where the logic is kept local to each
> > module, and the interfaces between them are kept to the absolute
> > minimum.  xdisp.c _knows_ a lot about how xterm.c and xfns.c work.
> > You cannot disengage them without a complete rewrite.
> 
> Well, it also works with w32term and nsterm, so the coupling can't be
> complete. :-)

That's why w32term and nsterm are largely modeled on xterm (and the
same with xfns), right to the point of literally repeating many code
fragments.

> By the way: aren't most calls to x_catch_errors already buggy? AFAICT,
> they don't generally call x_sync first.  The purpose of this mechanism
> is to run a section of code in such a way that Emacs doesn't die if
> something goes wrong in Xlib, but since Xlib error reporting is
> asynchronous anyway, use of x_catch_errors without a preceding x_sync
> (as I have in my code) can silently swallow X errors that we _do_ want
> to kill Emacs.

That's for some X expert to answer, I really don't know enough about
this stuff.  Ken, can you comment on this?

>   1. [must fix] during frame creation, on one of my computers but not
>   the other, I momentarily see an all-black frame with a small white
>   square, and only a few hundred ms later does the normal frame content
>   get draws

Possibly related to the fact that when Emacs starts, it first defines
a small 10x10 frame, before resizing it to the actual size.  Look for
"10" in make_frame.

>   2. [must fix] on the same system, and not the other, after resuming
>   the system from sleep, Emacs frames momentarily display all white
>   before the usual frame contents get filled in

Could be Emacs waits for an expose event before redrawing the frame,
and meanwhile you show an empty buffer?

>   3. [should fix] on the same system, and not the other, resizing the a
>   frame interactively still produces some flicking, particulary in the
>   modeline, but much less than without the patch entirely.
>   This flickering appears to have something to do with XRender, since if
>   I force everything to use X11 core rendering instead, I don't see any
>   flickering at all.

If the flickering is on the modeline, a breakpoint in
redisplay_mode_lines should tell you why it happens.

Thanks.



  reply	other threads:[~2016-10-24  8:05 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-10-21  1:32 RFC: flicker-free double-buffered Emacs under X11 Daniel Colascione
2016-10-21  2:27 ` Lars Ingebrigtsen
2016-10-21  2:31   ` Daniel Colascione
2016-10-21  3:24 ` Óscar Fuentes
2016-10-21  3:31   ` Clément Pit--Claudel
2016-10-21  3:41     ` Óscar Fuentes
2016-10-21  3:50       ` Clément Pit--Claudel
2016-10-21  8:23     ` Andreas Schwab
2016-10-21  8:25       ` Andreas Schwab
2016-10-21  3:56 ` Clément Pit--Claudel
2016-10-21  8:49 ` Eli Zaretskii
2016-10-21 11:04   ` Daniel Colascione
2016-10-21 17:43     ` Eli Zaretskii
2016-10-21 18:27       ` Daniel Colascione
2016-10-21 19:27         ` Eli Zaretskii
2016-10-23 20:51           ` Daniel Colascione
2016-10-24  8:05             ` Eli Zaretskii [this message]
2016-10-24 18:43               ` Ken Raeburn
2016-10-27 19:06               ` dancol
2016-10-27 19:36                 ` Eli Zaretskii
     [not found]                   ` <db81befd-7a72-58d9-b7a8-107df89bcab3@dancol.org>
2016-10-27 19:56                     ` Daniel Colascione
2016-10-28  6:31                       ` Eli Zaretskii
2016-10-27 22:18                 ` Paul Eggert
2016-10-27 22:46                   ` Clément Pit--Claudel
2016-10-28 13:14                     ` Stefan Monnier
2016-11-01  0:03                       ` Dmitry Gutov
2016-10-27 23:10                   ` Daniel Colascione
2016-10-28  2:07                     ` Paul Eggert
2016-10-28  7:19                       ` Eli Zaretskii
2016-11-06  3:51                         ` Paul Eggert
2016-11-06 15:46                           ` Eli Zaretskii

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=838tte5fzq.fsf@gnu.org \
    --to=eliz@gnu.org \
    --cc=dancol@dancol.org \
    --cc=emacs-devel@gnu.org \
    --cc=raeburn@raeburn.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).