]> Pileus Git - ~andy/gtk/blobdiff - gdk/gdkframeclock.c
Add gdk_frame_timings_get_predicted_presentation_time()
[~andy/gtk] / gdk / gdkframeclock.c
index 569ab6b52effd3786eda813a5a32f600dd95e383..fd41d945331af052c7d189679684f9727affae55 100644 (file)
@@ -91,11 +91,13 @@ G_DEFINE_INTERFACE (GdkFrameClock, gdk_frame_clock, G_TYPE_OBJECT)
 
 enum {
   FRAME_REQUESTED,
+  FLUSH_EVENTS,
   BEFORE_PAINT,
   UPDATE,
   LAYOUT,
   PAINT,
   AFTER_PAINT,
+  RESUME_EVENTS,
   LAST_SIGNAL
 };
 
@@ -120,6 +122,21 @@ gdk_frame_clock_default_init (GdkFrameClockInterface *iface)
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
 
+  /**
+   * GdkFrameClock::flush-events:
+   * @clock: the frame clock emitting the signal
+   *
+   * FIXME.
+   */
+  signals[FLUSH_EVENTS] =
+    g_signal_new (g_intern_static_string ("flush-events"),
+                  GDK_TYPE_FRAME_CLOCK,
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__VOID,
+                  G_TYPE_NONE, 0);
+
   /**
    * GdkFrameClock::before-paint:
    * @clock: the frame clock emitting the signal
@@ -202,6 +219,21 @@ gdk_frame_clock_default_init (GdkFrameClockInterface *iface)
                   NULL, NULL,
                   g_cclosure_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
+
+  /**
+   * GdkFrameClock::resume-events:
+   * @clock: the frame clock emitting the signal
+   *
+   * FIXME.
+   */
+  signals[RESUME_EVENTS] =
+    g_signal_new (g_intern_static_string ("resume-events"),
+                  GDK_TYPE_FRAME_CLOCK,
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__VOID,
+                  G_TYPE_NONE, 0);
 }
 
 /**
@@ -272,6 +304,23 @@ gdk_frame_clock_thaw (GdkFrameClock *clock)
   GDK_FRAME_CLOCK_GET_IFACE (clock)->thaw (clock);
 }
 
+/**
+ * gdk_frame_clock_get_history:
+ * @clock: the clock
+ *
+ * Gets the #GdkFrameHistory for the frame clock.
+ *
+ * Since: 3.8
+ * Return value: (transfer none): the frame history object
+ */
+GdkFrameHistory *
+gdk_frame_clock_get_history (GdkFrameClock *clock)
+{
+  g_return_val_if_fail (GDK_IS_FRAME_CLOCK (clock), NULL);
+
+  return GDK_FRAME_CLOCK_GET_IFACE (clock)->get_history (clock);
+}
+
 /**
  * gdk_frame_clock_get_requested:
  * @clock: the clock
@@ -329,3 +378,76 @@ gdk_frame_clock_frame_requested (GdkFrameClock *clock)
   g_signal_emit (G_OBJECT (clock),
                  signals[FRAME_REQUESTED], 0);
 }
+
+GdkFrameTimings *
+gdk_frame_clock_get_current_frame_timings (GdkFrameClock *clock)
+{
+  GdkFrameHistory *history;
+  gint64 frame_counter;
+
+  g_return_val_if_fail (GDK_IS_FRAME_CLOCK (clock), 0);
+
+  history = gdk_frame_clock_get_history (clock);
+  frame_counter = gdk_frame_history_get_frame_counter (history);
+  return gdk_frame_history_get_timings (history, frame_counter);
+}
+
+
+#define DEFAULT_REFRESH_INTERVAL 16667 /* 16.7ms (1/60th second) */
+#define MAX_HISTORY_AGE 150000         /* 150ms */
+
+void
+gdk_frame_clock_get_refresh_info (GdkFrameClock *clock,
+                                  gint64         base_time,
+                                  gint64        *refresh_interval_return,
+                                  gint64        *presentation_time_return)
+{
+  GdkFrameHistory *history;
+  gint64 frame_counter;
+
+  g_return_if_fail (GDK_IS_FRAME_CLOCK (clock));
+
+  history = gdk_frame_clock_get_history (clock);
+  frame_counter = gdk_frame_history_get_frame_counter (history);
+
+  if (presentation_time_return)
+    *presentation_time_return = 0;
+  if (refresh_interval_return)
+    *refresh_interval_return = DEFAULT_REFRESH_INTERVAL;
+
+  while (TRUE)
+    {
+      GdkFrameTimings *timings = gdk_frame_history_get_timings (history, frame_counter);
+      gint64 presentation_time;
+      gint64 refresh_interval;
+
+      if (timings == NULL)
+        return;
+
+      refresh_interval = gdk_frame_timings_get_refresh_interval (timings);
+      presentation_time = gdk_frame_timings_get_presentation_time (timings);
+
+      if (presentation_time != 0)
+        {
+          if (presentation_time > base_time - MAX_HISTORY_AGE &&
+              presentation_time_return)
+            {
+              if (refresh_interval == 0)
+                refresh_interval = DEFAULT_REFRESH_INTERVAL;
+
+              if (refresh_interval_return)
+                *refresh_interval_return = refresh_interval;
+
+              while (presentation_time < base_time)
+                presentation_time += refresh_interval;
+
+              if (presentation_time_return)
+                *presentation_time_return = presentation_time;
+            }
+
+          return;
+        }
+
+      frame_counter--;
+    }
+}