diff options
author | Owen W. Taylor <otaylor@fishsoup.net> | 2012-11-14 16:08:08 -0500 |
---|---|---|
committer | Owen W. Taylor <otaylor@fishsoup.net> | 2013-02-14 17:19:50 -0500 |
commit | 58b5811d03ded179b285727407b6a6be3d4d0734 (patch) | |
tree | 57bb0e1f18a863a6abb1958b871a33b4b784510d /gdk/gdkframeclockidle.c | |
parent | dc6dedab4dfdff5d067ba9f8c88d6a48cf0af143 (diff) | |
download | gtk+-58b5811d03ded179b285727407b6a6be3d4d0734.tar.gz |
Add gdk_frame_timings_get/set_slept_before()
Add functions that tell us whether the main loop slept before we drew
a frame. Blocking with the frame clock frozen doesn't count as sleeping.
We'll use this to advertise to the compositor whether we
are drawing as fast as possible (and it should do the same) or timing
frames carefully (and it should do the same.)
https://bugzilla.gnome.org/show_bug.cgi?id=685460
Diffstat (limited to 'gdk/gdkframeclockidle.c')
-rw-r--r-- | gdk/gdkframeclockidle.c | 61 |
1 files changed, 61 insertions, 0 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 (); } } |