summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Hergert <chergert@redhat.com>2016-04-26 03:08:11 -0700
committerMatthias Clasen <mclasen@redhat.com>2016-05-05 15:03:59 -0400
commit3244d7a138a85ac4f7fb809340f4c86b43b303f5 (patch)
treefa49161e417f8cbb856bb1431a6f58d411bdaac3
parent044e4b15a65eb013411ea3cef3e7c2eebf6d5ec6 (diff)
downloadgtk+-3244d7a138a85ac4f7fb809340f4c86b43b303f5.tar.gz
frametimings: reuse previous frame timing in common case
Typically, there won't be any references on old frame timings except for the most recent timing. So instead of discarding these and re-entering gslice twice, just steal the old frame timing and reuse it. https://bugzilla.gnome.org/show_bug.cgi?id=765592
-rw-r--r--gdk/gdkframeclock.c12
-rw-r--r--gdk/gdkframeclockprivate.h4
-rw-r--r--gdk/gdkframetimings.c17
3 files changed, 29 insertions, 4 deletions
diff --git a/gdk/gdkframeclock.c b/gdk/gdkframeclock.c
index f84aee77bb..6f6d1a1d42 100644
--- a/gdk/gdkframeclock.c
+++ b/gdk/gdkframeclock.c
@@ -416,12 +416,18 @@ _gdk_frame_clock_begin_frame (GdkFrameClock *frame_clock)
priv->frame_counter++;
priv->current = (priv->current + 1) % FRAME_HISTORY_MAX_LENGTH;
+ /* Try to steal the previous frame timing instead of discarding
+ * and allocating a new one.
+ */
+ if G_LIKELY (priv->n_timings == FRAME_HISTORY_MAX_LENGTH &&
+ _gdk_frame_timings_steal (priv->timings[priv->current],
+ priv->frame_counter))
+ return;
+
if (priv->n_timings < FRAME_HISTORY_MAX_LENGTH)
priv->n_timings++;
else
- {
- gdk_frame_timings_unref(priv->timings[priv->current]);
- }
+ gdk_frame_timings_unref(priv->timings[priv->current]);
priv->timings[priv->current] = _gdk_frame_timings_new (priv->frame_counter);
}
diff --git a/gdk/gdkframeclockprivate.h b/gdk/gdkframeclockprivate.h
index cda5aff37b..17e06dfcf7 100644
--- a/gdk/gdkframeclockprivate.h
+++ b/gdk/gdkframeclockprivate.h
@@ -111,7 +111,9 @@ void _gdk_frame_clock_begin_frame (GdkFrameClock *clock);
void _gdk_frame_clock_debug_print_timings (GdkFrameClock *clock,
GdkFrameTimings *timings);
-GdkFrameTimings *_gdk_frame_timings_new (gint64 frame_counter);
+GdkFrameTimings *_gdk_frame_timings_new (gint64 frame_counter);
+gboolean _gdk_frame_timings_steal (GdkFrameTimings *timings,
+ gint64 frame_counter);
void _gdk_frame_clock_emit_flush_events (GdkFrameClock *frame_clock);
void _gdk_frame_clock_emit_before_paint (GdkFrameClock *frame_clock);
diff --git a/gdk/gdkframetimings.c b/gdk/gdkframetimings.c
index 0245d469d2..7b8a3dd88c 100644
--- a/gdk/gdkframetimings.c
+++ b/gdk/gdkframetimings.c
@@ -17,6 +17,8 @@
#include "config.h"
+#include <string.h>
+
#include "gdkframeclockprivate.h"
/**
@@ -48,6 +50,21 @@ _gdk_frame_timings_new (gint64 frame_counter)
return timings;
}
+gboolean
+_gdk_frame_timings_steal (GdkFrameTimings *timings,
+ gint64 frame_counter)
+{
+ if (timings->ref_count == 1)
+ {
+ memset (timings, 0, sizeof *timings);
+ timings->ref_count = 1;
+ timings->frame_counter = frame_counter;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
/**
* gdk_frame_timings_ref:
* @timings: a #GdkFrameTimings