[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 80bfd6dc5b: Make frame synchronization more robust
From: |
Po Lu |
Subject: |
master 80bfd6dc5b: Make frame synchronization more robust |
Date: |
Sun, 27 Nov 2022 06:21:15 -0500 (EST) |
branch: master
commit 80bfd6dc5bc3738db595a4972893b149b1224800
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
Make frame synchronization more robust
* src/xterm.c (x_sync_wait_for_frame_drawn_event)
(x_sync_handle_frame_drawn): Only cancel frame synchronization
if hanging twice or more in a row.
* src/xterm.h (struct x_output, FRAME_X_DRAW_JUST_HUNG): New
flag.
---
src/xterm.c | 46 +++++++++++++++++++++++++++++++++++++++-------
src/xterm.h | 6 ++++++
2 files changed, 45 insertions(+), 7 deletions(-)
diff --git a/src/xterm.c b/src/xterm.c
index ec605f5e91..7eaf59d54b 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -6919,13 +6919,27 @@ x_sync_wait_for_frame_drawn_event (struct frame *f)
x_sync_is_frame_drawn_event, (XPointer) f,
make_timespec (1, 0)))
{
- /* TODO: display this warning in the echo area. */
- fprintf (stderr, "Warning: compositing manager spent more than 1 second "
- "drawing a frame. Frame synchronization has been disabled\n");
- FRAME_X_OUTPUT (f)->use_vsync_p = false;
+ /* The first time a draw hangs, treat it as a random fluctuation
+ on the part of the compositor. If the next draw continues to
+ hang, disable frame synchronization. */
+ if (FRAME_X_DRAW_JUST_HUNG (f))
+ {
+ fprintf (stderr, "Warning: compositing manager spent more than 1 "
+ "second drawing a frame. Frame synchronization has "
+ "been disabled\n");
+ FRAME_X_OUTPUT (f)->use_vsync_p = false;
- /* Also change the frame parameter to reflect the new state. */
- store_frame_param (f, Quse_frame_synchronization, Qnil);
+ /* Also change the frame parameter to reflect the new
+ state. */
+ store_frame_param (f, Quse_frame_synchronization, Qnil);
+ }
+ else
+ {
+ fprintf (stderr, "Warning: compositing manager spent more than 1 "
+ "second drawing a frame. Frame synchronization will be "
+ "disabled if this happens again\n");
+ FRAME_X_DRAW_JUST_HUNG (f) = true;
+ }
}
else
x_sync_note_frame_times (FRAME_DISPLAY_INFO (f), f, &event);
@@ -7128,8 +7142,26 @@ static void
x_sync_handle_frame_drawn (struct x_display_info *dpyinfo,
XEvent *message, struct frame *f)
{
+ XSyncValue value, counter;
+
if (FRAME_OUTER_WINDOW (f) == message->xclient.window)
- FRAME_X_WAITING_FOR_DRAW (f) = false;
+ {
+ counter = FRAME_X_COUNTER_VALUE (f);
+
+ /* Check that the counter in the message is the same as the
+ counter in the frame. */
+ XSyncIntsToValue (&value,
+ message->xclient.data.l[0] & 0xffffffff,
+ message->xclient.data.l[1] & 0xffffffff);
+
+ if (XSyncValueEqual (value, counter))
+ FRAME_X_WAITING_FOR_DRAW (f) = false;
+
+ /* As long as a _NET_WM_FRAME_DRAWN message arrives, we know
+ that the compositor is still sending events, so avoid timing
+ out. */
+ FRAME_X_DRAW_JUST_HUNG (f) = false;
+ }
x_sync_note_frame_times (dpyinfo, f, message);
}
diff --git a/src/xterm.h b/src/xterm.h
index c36920081d..ee429e9c68 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -1179,6 +1179,10 @@ struct x_output
frame. */
bool_bf waiting_for_frame_p : 1;
+ /* Whether or not Emacs just skipped waiting for a frame due to a
+ timeout. */
+ bool_bf draw_just_hung_p : 1;
+
#if !defined USE_GTK && defined HAVE_CLOCK_GETTIME
/* Whether or not Emacs should wait for the compositing manager to
draw frames before starting a new frame. */
@@ -1392,6 +1396,8 @@ extern void x_mark_frame_dirty (struct frame *f);
FRAME_X_OUTPUT (f)->extended_frame_counter
#define FRAME_X_WAITING_FOR_DRAW(f) \
FRAME_X_OUTPUT (f)->waiting_for_frame_p
+#define FRAME_X_DRAW_JUST_HUNG(f) \
+ FRAME_X_OUTPUT (f)->draw_just_hung_p
#define FRAME_X_COUNTER_VALUE(f) \
FRAME_X_OUTPUT (f)->current_extended_counter_value
#endif
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- master 80bfd6dc5b: Make frame synchronization more robust,
Po Lu <=