fepitre / rpms / gtk3

Forked from rpms/gtk3 4 years ago
Clone

Blame SOURCES/0001-GdkDisplayX11-Properly-translate-server-timestamps-f.patch

25dd04
From 2ef204e6071b985d5b8e5d1c25ca0b0abf5f9d31 Mon Sep 17 00:00:00 2001
25dd04
From: "Owen W. Taylor" <otaylor@fishsoup.net>
25dd04
Date: Wed, 15 Jul 2015 12:38:38 -0400
25dd04
Subject: [PATCH 1/2] GdkDisplayX11: Properly translate server timestamps from
25dd04
 _NET_WM_FRAME_* messages
25dd04
25dd04
When using frame times from _NET_WM_FRAME_DRAWN and _NET_WM_FRAME_TIMINGS, we
25dd04
were treating them as local monotonic times, but they are actually extended-precision
25dd04
versions of the server time, and need to be translated to monotonic times in the
25dd04
case where the X server and client aren't running on the same system.
25dd04
25dd04
This fixes rendering stalls when using X over a remote ssh connection.
25dd04
https://bugzilla.gnome.org/show_bug.cgi?id=741800
25dd04
---
25dd04
 gdk/x11/gdkdisplay-x11.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
25dd04
 gdk/x11/gdkdisplay-x11.h |  6 ++++++
25dd04
 2 files changed, 48 insertions(+), 1 deletion(-)
25dd04
25dd04
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
25dd04
index 4fe7524..2fe2cd4 100644
25dd04
--- a/gdk/x11/gdkdisplay-x11.c
25dd04
+++ b/gdk/x11/gdkdisplay-x11.c
25dd04
@@ -1096,6 +1096,47 @@ find_frame_timings (GdkFrameClock *clock,
25dd04
   return NULL;
25dd04
 }
25dd04
 
25dd04
+/* _NET_WM_FRAME_DRAWN and _NET_WM_FRAME_TIMINGS messages represent time
25dd04
+ * as a "high resolution server time" - this is the server time interpolated
25dd04
+ * to microsecond resolution. The advantage of this time representation
25dd04
+ * is that if  X server is running on the same computer as a client, and
25dd04
+ * the Xserver uses 'clock_gettime(CLOCK_MONOTONIC, ...)' for the server
25dd04
+ * time, the client can detect this, and all such clients will share a
25dd04
+ * a time representation with high accuracy. If there is not a common
25dd04
+ * time source, then the time synchronization will be less accurate.
25dd04
+ */
25dd04
+gint64
25dd04
+server_time_to_monotonic_time (GdkX11Display *display_x11,
25dd04
+                               gint64         server_time)
25dd04
+{
25dd04
+  if (display_x11->server_time_query_time == 0 ||
25dd04
+      (!display_x11->server_time_is_monotonic_time &&
25dd04
+       server_time > display_x11->server_time_query_time + 10*1000*1000)) /* 10 seconds */
25dd04
+    {
25dd04
+      gint64 current_server_time = gdk_x11_get_server_time (display_x11->leader_gdk_window);
25dd04
+      gint64 current_server_time_usec = (gint64)current_server_time * 1000;
25dd04
+      gint64 current_monotonic_time = g_get_monotonic_time ();
25dd04
+      display_x11->server_time_query_time = current_monotonic_time;
25dd04
+
25dd04
+      /* If the server time is within a second of the monotonic time,
25dd04
+       * we assume that they are identical. This seems like a big margin,
25dd04
+       * but we want to be as robust as possible even if the system
25dd04
+       * is under load and our processing of the server response is
25dd04
+       * delayed.
25dd04
+       */
25dd04
+      if (current_server_time_usec > current_monotonic_time - 1000*1000 &&
25dd04
+          current_server_time_usec < current_monotonic_time + 1000*1000)
25dd04
+        display_x11->server_time_is_monotonic_time = TRUE;
25dd04
+
25dd04
+      display_x11->server_time_offset = current_server_time_usec - current_monotonic_time;
25dd04
+    }
25dd04
+
25dd04
+  if (display_x11->server_time_is_monotonic_time)
25dd04
+    return server_time;
25dd04
+  else
25dd04
+    return server_time - display_x11->server_time_offset;
25dd04
+}
25dd04
+
25dd04
 GdkFilterReturn
25dd04
 _gdk_wm_protocols_filter (GdkXEvent *xev,
25dd04
 			  GdkEvent  *event,
25dd04
@@ -1128,7 +1169,7 @@ _gdk_wm_protocols_filter (GdkXEvent *xev,
25dd04
           guint32 d3 = xevent->xclient.data.l[3];
25dd04
 
25dd04
           guint64 serial = ((guint64)d1 << 32) | d0;
25dd04
-          gint64 frame_drawn_time = ((guint64)d3 << 32) | d2;
25dd04
+          gint64 frame_drawn_time = server_time_to_monotonic_time (GDK_X11_DISPLAY (display), ((guint64)d3 << 32) | d2);
25dd04
           gint64 refresh_interval, presentation_time;
25dd04
 
25dd04
           GdkFrameClock *clock = gdk_window_get_frame_clock (win);
25dd04
diff --git a/gdk/x11/gdkdisplay-x11.h b/gdk/x11/gdkdisplay-x11.h
25dd04
index 69ba890..d9305dd 100644
25dd04
--- a/gdk/x11/gdkdisplay-x11.h
25dd04
+++ b/gdk/x11/gdkdisplay-x11.h
25dd04
@@ -124,6 +124,12 @@ struct _GdkX11Display
25dd04
   GSList *error_traps;
25dd04
 
25dd04
   gint wm_moveresize_button;
25dd04
+
25dd04
+  /* Translation between X server time and system-local monotonic time */
25dd04
+  gint64 server_time_query_time;
25dd04
+  gint64 server_time_offset;
25dd04
+
25dd04
+  guint server_time_is_monotonic_time : 1;
25dd04
 };
25dd04
 
25dd04
 struct _GdkX11DisplayClass
25dd04
-- 
25dd04
2.4.5
25dd04