[gtk+/wip/frame-synchronization: 26/33] Add gdk_frame_timings_get/set_slept_before()
- From: Owen Taylor <otaylor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/frame-synchronization: 26/33] Add gdk_frame_timings_get/set_slept_before()
- Date: Tue, 4 Dec 2012 18:00:13 +0000 (UTC)
commit 7a1508f82b42f638b36a0d466e13d778c75f362b
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Wed Nov 14 16:08:08 2012 -0500
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 paint 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
gdk/gdkframetimings.c | 21 +++++++++++++++-
gdk/gdkframetimings.h | 4 +++
gdk/gdkpaintclockidle.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 85 insertions(+), 1 deletions(-)
---
diff --git a/gdk/gdkframetimings.c b/gdk/gdkframetimings.c
index d9354ed..a51912b 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 7fddbd4..53dbffb 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);
diff --git a/gdk/gdkpaintclockidle.c b/gdk/gdkpaintclockidle.c
index e3131f3..987f680 100644
--- a/gdk/gdkpaintclockidle.c
+++ b/gdk/gdkpaintclockidle.c
@@ -39,6 +39,7 @@ struct _GdkPaintClockIdlePrivate
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 (GdkPaintClockIdle, gdk_paint_clock_idle, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINT_CLOCK,
gdk_paint_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_paint_clock_idle_class_init (GdkPaintClockIdleClass *klass)
{
@@ -244,6 +297,9 @@ gdk_paint_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_PAINT_CLOCK_PHASE_BEFORE_PAINT;
/* We always emit ::before-paint and ::after-paint if
@@ -322,6 +378,9 @@ gdk_paint_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_paint_clock_idle_thaw (GdkPaintClock *clock)
* run and do it for us. */
if (priv->paint_idle_id == 0)
priv->phase = GDK_PAINT_CLOCK_PHASE_NONE;
+
+ priv->sleep_serial = get_sleep_serial ();
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]