summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel van Vugt <daniel.van.vugt@canonical.com>2018-12-20 18:18:57 +0800
committerGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>2019-06-07 12:08:49 -0300
commite415cc538ae2ab885314aced4381d09221c17970 (patch)
tree43bb35c4aaeb52a97e21a309039709d26ac14fbe
parent67a3715ded0f36fd03193adafb72e079460b7167 (diff)
downloadmutter-e415cc538ae2ab885314aced4381d09221c17970.tar.gz
clutter/master-clock: Remove fallback throttles
The presentation timing logic (via `master_clock_get_swap_wait_time`) now works unconditionally. By "works" we mean that a result of zero from `master_clock_get_swap_wait_time` actually means zero now. Previously zero could mean either a successful result of zero milliseconds or that the backend couldn't get an answer. And a non-zero result is the same as before. This works even if the screen is "idle" and even if the backend doesn't provide presentation timestamps. So now our two fallback throttling mechanisms of relying on `CLUTTER_FEATURE_SWAP_THROTTLE` and decimating to `clutter_get_default_frame_rate` can be deleted. Closes: https://gitlab.gnome.org/GNOME/mutter/issues/406 and https://bugzilla.gnome.org/show_bug.cgi?id=781835 https://gitlab.gnome.org/GNOME/mutter/merge_requests/363
-rw-r--r--clutter/clutter/clutter-master-clock-default.c90
1 files changed, 2 insertions, 88 deletions
diff --git a/clutter/clutter/clutter-master-clock-default.c b/clutter/clutter/clutter-master-clock-default.c
index 6779eb70b..3197a32e3 100644
--- a/clutter/clutter/clutter-master-clock-default.c
+++ b/clutter/clutter/clutter-master-clock-default.c
@@ -64,9 +64,6 @@ struct _ClutterMasterClockDefault
/* the current state of the clock, in usecs */
gint64 cur_tick;
- /* the previous state of the clock, in usecs, used to compute the delta */
- gint64 prev_tick;
-
#ifdef CLUTTER_ENABLE_DEBUG
gint64 frame_budget;
gint64 remaining_budget;
@@ -77,12 +74,6 @@ struct _ClutterMasterClockDefault
*/
GSource *source;
- /* If the master clock is idle that means it has
- * fallen back to idle polling for timeline
- * progressions and it may have been some time since
- * the last real stage update.
- */
- guint idle : 1;
guint ensure_next_iteration : 1;
guint paused : 1;
@@ -275,78 +266,12 @@ master_clock_reschedule_stage_updates (ClutterMasterClockDefault *master_clock,
static gint
master_clock_next_frame_delay (ClutterMasterClockDefault *master_clock)
{
- gint64 now, next;
- gint swap_delay;
-
if (!master_clock_is_running (master_clock))
return -1;
/* If all of the stages are busy waiting for a swap-buffers to complete
* then we wait for one to be ready.. */
- swap_delay = master_clock_get_swap_wait_time (master_clock);
- if (swap_delay != 0)
- return swap_delay;
-
- /* When we have sync-to-vblank, we count on swap-buffer requests (or
- * swap-buffer-complete events if supported in the backend) to throttle our
- * frame rate so no additional delay is needed to start the next frame.
- *
- * If the master-clock has become idle due to no timeline progression causing
- * redraws then we can no longer rely on vblank synchronization because the
- * last real stage update/redraw may have happened a long time ago and so we
- * fallback to polling for timeline progressions every 1/frame_rate seconds.
- *
- * (NB: if there aren't even any timelines running then the master clock will
- * be completely stopped in master_clock_is_running())
- */
- if (clutter_feature_available (CLUTTER_FEATURE_SWAP_THROTTLE) &&
- !master_clock->idle)
- {
- CLUTTER_NOTE (SCHEDULER, "swap throttling available and updated stages");
- return 0;
- }
-
- if (master_clock->prev_tick == 0)
- {
- /* If we weren't previously running, then draw the next frame
- * immediately
- */
- CLUTTER_NOTE (SCHEDULER, "draw the first frame immediately");
- return 0;
- }
-
- /* Otherwise, wait at least 1/frame_rate seconds since we last
- * started a frame
- */
- now = g_source_get_time (master_clock->source);
-
- next = master_clock->prev_tick;
-
- /* If time has gone backwards then there's no way of knowing how
- long we should wait so let's just dispatch immediately */
- if (now <= next)
- {
- CLUTTER_NOTE (SCHEDULER, "Time has gone backwards");
-
- return 0;
- }
-
- next += (1000000L / clutter_get_default_frame_rate ());
-
- if (next <= now)
- {
- CLUTTER_NOTE (SCHEDULER, "Less than %lu microsecs",
- 1000000L / (gulong) clutter_get_default_frame_rate ());
-
- return 0;
- }
- else
- {
- CLUTTER_NOTE (SCHEDULER, "Waiting %" G_GINT64_FORMAT " msecs",
- (next - now) / 1000);
-
- return (next - now) / 1000;
- }
+ return master_clock_get_swap_wait_time (master_clock);
}
static void
@@ -530,7 +455,6 @@ clutter_clock_dispatch (GSource *source,
{
ClutterClockSource *clock_source = (ClutterClockSource *) source;
ClutterMasterClockDefault *master_clock = clock_source->master_clock;
- gboolean stages_updated = FALSE;
GSList *stages;
CLUTTER_NOTE (SCHEDULER, "Master clock [tick]");
@@ -550,8 +474,6 @@ clutter_clock_dispatch (GSource *source,
*/
stages = master_clock_list_ready_stages (master_clock);
- master_clock->idle = FALSE;
-
/* Each frame is split into three separate phases: */
/* 1. process all the events; each stage goes through its events queue
@@ -564,19 +486,12 @@ clutter_clock_dispatch (GSource *source,
master_clock_advance_timelines (master_clock);
/* 3. relayout and redraw the stages */
- stages_updated = master_clock_update_stages (master_clock, stages);
-
- /* The master clock goes idle if no stages were updated and falls back
- * to polling for timeline progressions... */
- if (!stages_updated)
- master_clock->idle = TRUE;
+ master_clock_update_stages (master_clock, stages);
master_clock_reschedule_stage_updates (master_clock, stages);
g_slist_free_full (stages, g_object_unref);
- master_clock->prev_tick = master_clock->cur_tick;
-
_clutter_threads_release_lock ();
return TRUE;
@@ -608,7 +523,6 @@ clutter_master_clock_default_init (ClutterMasterClockDefault *self)
source = clutter_clock_source_new (self);
self->source = source;
- self->idle = FALSE;
self->ensure_next_iteration = FALSE;
self->paused = FALSE;