[mutter/gnome-3-36] clutter/master-clock-default: Sync timelines to hardware vsync
- From: Robert Mader <rmader src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/gnome-3-36] clutter/master-clock-default: Sync timelines to hardware vsync
- Date: Fri, 3 Apr 2020 11:34:05 +0000 (UTC)
commit 6f094bd399f4197e7036d8306337b4b0ee72ca65
Author: Daniel van Vugt <daniel van vugt canonical com>
Date: Tue Aug 13 18:03:26 2019 +0800
clutter/master-clock-default: Sync timelines to hardware vsync
Previously clutter timelines advanced according to `g_source_get_time`.
But that meant the spatial stepping of animations was visibly sensitive to
any irregularities in the main loop. It also represented a time older [1]
than the intended presentation time of each frame.
Now we instead use `master_clock_get_next_presentation_time`. This ensures
we get the smoothness of hardware vsync as well as being closer to the
actual presentation time.
This means, for example, backends like Xorg that move the hardware cursor
independently of repaints will have their animations more closely matching
the hardware cursor position. So the cursor appears to stick more closely
when dragging windows or on the lock screen etc.
[1] "older" = (refresh_interval - sync_delay) = ~14ms for 60Hz
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/25
https://gitlab.gnome.org/GNOME/mutter/merge_requests/724
clutter/clutter/clutter-master-clock-default.c | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
---
diff --git a/clutter/clutter/clutter-master-clock-default.c b/clutter/clutter/clutter-master-clock-default.c
index 8d50ab8f3..ac55f1b42 100644
--- a/clutter/clutter/clutter-master-clock-default.c
+++ b/clutter/clutter/clutter-master-clock-default.c
@@ -190,6 +190,26 @@ master_clock_get_swap_wait_time (ClutterMasterClockDefault *master_clock)
}
}
+static int64_t
+master_clock_get_next_presentation_time (ClutterMasterClockDefault *master_clock)
+{
+ ClutterStageManager *stage_manager = clutter_stage_manager_get_default ();
+ const GSList *stages, *l;
+ int64_t earliest = -1;
+
+ stages = clutter_stage_manager_peek_stages (stage_manager);
+
+ for (l = stages; l != NULL; l = l->next)
+ {
+ gint64 t = _clutter_stage_get_next_presentation_time (l->data);
+
+ if (earliest == -1 || (t != -1 && t < earliest))
+ earliest = t;
+ }
+
+ return earliest;
+}
+
static void
master_clock_schedule_stage_updates (ClutterMasterClockDefault *master_clock)
{
@@ -466,7 +486,11 @@ clutter_clock_dispatch (GSource *source,
COGL_TRACE_BEGIN (ClutterMasterClockTick, "Master Clock (tick)");
/* Get the time to use for this frame */
- master_clock->cur_tick = g_source_get_time (source);
+ master_clock->cur_tick = master_clock_get_next_presentation_time (master_clock);
+
+ /* On the first frame the backend might not have an answer */
+ if (master_clock->cur_tick <= 0)
+ master_clock->cur_tick = g_source_get_time (source);
#ifdef CLUTTER_ENABLE_DEBUG
master_clock->remaining_budget = master_clock->frame_budget;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]