diff options
-rw-r--r-- | gdk/gdkframeclockidle.c | 61 | ||||
-rw-r--r-- | gdk/gdkframetimings.c | 21 | ||||
-rw-r--r-- | gdk/gdkframetimings.h | 4 |
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); |