summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdk/gdkframeclockidle.c61
-rw-r--r--gdk/gdkframetimings.c21
-rw-r--r--gdk/gdkframetimings.h4
3 files changed, 85 insertions, 1 deletions
diff --git a/gdk/gdkframeclockidle.c b/gdk/gdkframeclockidle.c
index 37a6733620..f6e2d339b9 100644
--- a/gdk/gdkframeclockidle.c
+++ b/gdk/gdkframeclockidle.c
@@ -39,6 +39,7 @@ struct _GdkFrameClockIdlePrivate
guint64 timer_base;
guint64 frame_time;
guint64 min_next_frame_time;
+ gint64 sleep_serial;
guint flush_idle_id;
guint paint_idle_id;
@@ -60,6 +61,58 @@ G_DEFINE_TYPE_WITH_CODE (GdkFrameClockIdle, gdk_frame_clock_idle, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GDK_TYPE_FRAME_CLOCK,
gdk_frame_clock_idle_interface_init))
+static gint64 sleep_serial;
+static gint64 sleep_source_prepare_time;
+static GSource *sleep_source;
+
+gboolean
+sleep_source_prepare (GSource *source,
+ gint *timeout)
+{
+ sleep_source_prepare_time = g_source_get_time (source);
+ *timeout = -1;
+ return FALSE;
+}
+
+gboolean
+sleep_source_check (GSource *source)
+{
+ if (g_source_get_time (source) != sleep_source_prepare_time)
+ sleep_serial++;
+
+ return FALSE;
+}
+
+gboolean
+sleep_source_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ return TRUE;
+}
+
+static GSourceFuncs sleep_source_funcs = {
+ sleep_source_prepare,
+ sleep_source_check,
+ sleep_source_dispatch,
+ NULL /* finalize */
+};
+
+static gint64
+get_sleep_serial (void)
+{
+ if (sleep_source == NULL)
+ {
+ sleep_source = g_source_new (&sleep_source_funcs, sizeof (GSource));
+
+ g_source_set_priority (sleep_source, G_PRIORITY_HIGH);
+ g_source_attach (sleep_source, NULL);
+ g_source_unref (sleep_source);
+ }
+
+ return sleep_serial;
+}
+
static void
gdk_frame_clock_idle_class_init (GdkFrameClockIdleClass *klass)
{
@@ -244,6 +297,9 @@ gdk_frame_clock_paint_idle (void *data)
timings = gdk_frame_history_get_timings (priv->history, frame_counter);
gdk_frame_timings_set_frame_time (timings, priv->frame_time);
+ gdk_frame_timings_set_slept_before (timings,
+ priv->sleep_serial != get_sleep_serial ());
+
priv->phase = GDK_FRAME_CLOCK_PHASE_BEFORE_PAINT;
/* We always emit ::before-paint and ::after-paint if
@@ -322,6 +378,9 @@ gdk_frame_clock_paint_idle (void *data)
priv->min_next_frame_time = 0;
}
+ if (priv->freeze_count == 0)
+ priv->sleep_serial = get_sleep_serial ();
+
return FALSE;
}
@@ -383,6 +442,8 @@ gdk_frame_clock_idle_thaw (GdkFrameClock *clock)
* run and do it for us. */
if (priv->paint_idle_id == 0)
priv->phase = GDK_FRAME_CLOCK_PHASE_NONE;
+
+ priv->sleep_serial = get_sleep_serial ();
}
}
diff --git a/gdk/gdkframetimings.c b/gdk/gdkframetimings.c
index d9354ede4f..a51912baa6 100644
--- a/gdk/gdkframetimings.c
+++ b/gdk/gdkframetimings.c
@@ -23,13 +23,15 @@ struct _GdkFrameTimings
{
guint ref_count;
- gboolean complete;
gint64 frame_counter;
guint64 cookie;
gint64 frame_time;
gint64 drawn_time;
gint64 presentation_time;
gint64 refresh_interval;
+
+ guint complete : 1;
+ guint slept_before : 1;
};
G_DEFINE_BOXED_TYPE (GdkFrameTimings, gdk_frame_timings,
@@ -111,6 +113,23 @@ gdk_frame_timings_set_complete (GdkFrameTimings *timings,
timings->complete = complete;
}
+gboolean
+gdk_frame_timings_get_slept_before (GdkFrameTimings *timings)
+{
+ g_return_val_if_fail (timings != NULL, FALSE);
+
+ return timings->slept_before;
+}
+
+void
+gdk_frame_timings_set_slept_before (GdkFrameTimings *timings,
+ gboolean slept_before)
+{
+ g_return_if_fail (timings != NULL);
+
+ timings->slept_before = slept_before;
+}
+
gint64
gdk_frame_timings_get_frame_time (GdkFrameTimings *timings)
{
diff --git a/gdk/gdkframetimings.h b/gdk/gdkframetimings.h
index 7fddbd4a6d..53dbffbd06 100644
--- a/gdk/gdkframetimings.h
+++ b/gdk/gdkframetimings.h
@@ -45,6 +45,10 @@ gboolean gdk_frame_timings_get_complete (GdkFrameTimings *timin
void gdk_frame_timings_set_complete (GdkFrameTimings *timings,
gboolean complete);
+gboolean gdk_frame_timings_get_slept_before (GdkFrameTimings *timings);
+void gdk_frame_timings_set_slept_before (GdkFrameTimings *timings,
+ gboolean slept_before);
+
gint64 gdk_frame_timings_get_frame_time (GdkFrameTimings *timings);
void gdk_frame_timings_set_frame_time (GdkFrameTimings *timings,
gint64 frame_time);