From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Eli Zaretskii Newsgroups: gmane.emacs.devel Subject: Re: RFC: flicker-free double-buffered Emacs under X11 Date: Mon, 24 Oct 2016 11:05:29 +0300 Message-ID: <838tte5fzq.fsf@gnu.org> References: <9e8ad090-a6a0-c807-95ae-7ec7c3f391cb@dancol.org> <83k2d2rssf.fsf@gnu.org> <831sz9sime.fsf@gnu.org> <83y41hqz94.fsf@gnu.org> Reply-To: Eli Zaretskii NNTP-Posting-Host: blaine.gmane.org X-Trace: blaine.gmane.org 1477296399 22300 195.159.176.226 (24 Oct 2016 08:06:39 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Mon, 24 Oct 2016 08:06:39 +0000 (UTC) Cc: emacs-devel@gnu.org To: Daniel Colascione , Ken Raeburn Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Oct 24 10:06:34 2016 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1byaGp-0002HY-12 for ged-emacs-devel@m.gmane.org; Mon, 24 Oct 2016 10:06:11 +0200 Original-Received: from localhost ([::1]:45202 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1byaGr-0000rd-DN for ged-emacs-devel@m.gmane.org; Mon, 24 Oct 2016 04:06:13 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:52064) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1byaGH-0000rN-37 for emacs-devel@gnu.org; Mon, 24 Oct 2016 04:05:38 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1byaGC-0007BJ-Tt for emacs-devel@gnu.org; Mon, 24 Oct 2016 04:05:36 -0400 Original-Received: from fencepost.gnu.org ([2001:4830:134:3::e]:44843) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1byaGC-0007BF-L0; Mon, 24 Oct 2016 04:05:32 -0400 Original-Received: from 84.94.185.246.cable.012.net.il ([84.94.185.246]:1399 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_128_CBC_SHA1:128) (Exim 4.82) (envelope-from ) id 1byaGB-00068e-SO; Mon, 24 Oct 2016 04:05:32 -0400 In-reply-to: (message from Daniel Colascione on Sun, 23 Oct 2016 13:51:01 -0700) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2001:4830:134:3::e X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:208662 Archived-At: > From: Daniel Colascione > 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.