[gtk/gtk-3-24: 4/11] frame-clock: Ensure we're always monotonic
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/gtk-3-24: 4/11] frame-clock: Ensure we're always monotonic
- Date: Mon, 15 Jun 2020 10:50:40 +0000 (UTC)
commit 1a598c32d9d19ad3ea23cdb25468bfbfe3b3e08d
Author: Alexander Larsson <alexl redhat com>
Date: Thu May 28 17:44:51 2020 +0200
frame-clock: Ensure we're always monotonic
A call to frame gdk_frame_clock_get_frame_time() outside of the paint
cycle could report an un-error-corrected frame time, and later a
corrected value could be earlier than the previously reported value.
We now always store the latest reported time so we can ensure
monotonicity.
(cherry picked from commit a27fed47e0d20579cd6506e4d2f90f316f7f85a2)
gdk/gdkframeclockidle.c | 31 ++++++++++++++++++++-----------
1 file changed, 20 insertions(+), 11 deletions(-)
---
diff --git a/gdk/gdkframeclockidle.c b/gdk/gdkframeclockidle.c
index 5b145ad6c1..c5dd5ac791 100644
--- a/gdk/gdkframeclockidle.c
+++ b/gdk/gdkframeclockidle.c
@@ -38,10 +38,11 @@
struct _GdkFrameClockIdlePrivate
{
- gint64 frame_time; /* The exact time we last ran the clock cycle, or 0 if never */
- gint64 smoothed_frame_time_base; /* A grid-aligned version of frame_time (grid size == refresh period),
never more than half a grid from frame_time */
- gint64 smoothed_frame_time_period; /* The grid size that smoothed_frame_time_base is aligned to */
- gint64 min_next_frame_time; /* We're not synced to vblank, so wait at least until this before next
cycle to avoid busy looping */
+ gint64 frame_time; /* The exact time we last ran the clock cycle, or 0 if never */
+ gint64 smoothed_frame_time_base; /* A grid-aligned version of frame_time (grid size == refresh
period), never more than half a grid from frame_time */
+ gint64 smoothed_frame_time_period; /* The grid size that smoothed_frame_time_base is aligned to */
+ gint64 smoothed_frame_time_reported; /* Ensures we are always monotonic */
+ gint64 min_next_frame_time; /* We're not synced to vblank, so wait at least until this before
next cycle to avoid busy looping */
gint64 sleep_serial;
#ifdef G_ENABLE_DEBUG
gint64 freeze_time;
@@ -220,9 +221,9 @@ compute_smooth_frame_time (GdkFrameClock *clock,
new_smoothed_time += correction_magnitude;
}
- /* Ensure we're always strictly increasing (avoid division by zero when using time deltas) */
- if (new_smoothed_time <= priv->smoothed_frame_time_base)
- new_smoothed_time = priv->smoothed_frame_time_base + 1;
+ /* Ensure we're always monotonic */
+ if (new_smoothed_time <= priv->smoothed_frame_time_reported)
+ new_smoothed_time = priv->smoothed_frame_time_reported;
return new_smoothed_time;
}
@@ -232,6 +233,7 @@ gdk_frame_clock_idle_get_frame_time (GdkFrameClock *clock)
{
GdkFrameClockIdlePrivate *priv = GDK_FRAME_CLOCK_IDLE (clock)->priv;
gint64 now;
+ gint64 new_smoothed_time;
/* can't change frame time during a paint */
if (priv->phase != GDK_FRAME_CLOCK_PHASE_NONE &&
@@ -243,13 +245,19 @@ gdk_frame_clock_idle_get_frame_time (GdkFrameClock *clock)
/* First time frame, just return something */
if (priv->smoothed_frame_time_base == 0)
- return now;
+ {
+ priv->smoothed_frame_time_reported = now;
+ return now;
+ }
/* Since time is monotonic this is <= what we will pick for the next cycle, but
more likely than not it will be equal if we're doing a constant animation. */
- return compute_smooth_frame_time (clock, now, FALSE,
- priv->smoothed_frame_time_base,
- priv->smoothed_frame_time_period);
+ new_smoothed_time = compute_smooth_frame_time (clock, now, FALSE,
+ priv->smoothed_frame_time_base,
+ priv->smoothed_frame_time_period);
+
+ priv->smoothed_frame_time_reported = new_smoothed_time;
+ return new_smoothed_time;
}
#define RUN_FLUSH_IDLE(priv) \
@@ -424,6 +432,7 @@ gdk_frame_clock_paint_idle (void *data)
priv->smoothed_frame_time_period);
priv->smoothed_frame_time_period = frame_interval;
}
+ priv->smoothed_frame_time_reported = priv->smoothed_frame_time_base;
_gdk_frame_clock_begin_frame (clock);
/* Note "current" is different now so timings != prev_timings */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]