4 * An OpenGL based 'interactive canvas' library.
6 * Authored By: Emmanuele Bassi <ebassi@linux.intel.com>
8 * Copyright (C) 2009 Intel Corporation.
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
25 * SECTION:clutter-master-clock
26 * @short_description: The master clock for all animations
28 * The #ClutterMasterClock class is responsible for advancing all
29 * #ClutterTimelines when a stage is being redrawn. The master clock
30 * makes sure that the scenegraph is always integrally updated before
38 #include "clutter-master-clock.h"
39 #include "clutter-debug.h"
40 #include "clutter-private.h"
41 #include "clutter-profile.h"
42 #include "clutter-stage-manager-private.h"
43 #include "clutter-stage-private.h"
45 #define CLUTTER_MASTER_CLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_MASTER_CLOCK, ClutterMasterClockClass))
46 #define CLUTTER_IS_MASTER_CLOCK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_MASTER_CLOCK))
47 #define CLUTTER_MASTER_CLASS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_MASTER_CLOCK, ClutterMasterClockClass))
49 #ifdef CLUTTER_ENABLE_DEBUG
50 #define clutter_warn_if_over_budget(master_clock,start_time,section) G_STMT_START { \
51 gint64 __delta = g_get_monotonic_time () - start_time; \
52 gint64 __budget = master_clock->remaining_budget; \
53 if (__budget > 0 && __delta >= __budget) { \
54 _clutter_diagnostic_message ("%s took %" G_GINT64_FORMAT " microseconds " \
55 "over a budget of %" G_GINT64_FORMAT " microseconds", \
56 section, __delta, __budget); \
59 #define clutter_warn_if_over_budget(master_clock,start_time,section)
62 typedef struct _ClutterClockSource ClutterClockSource;
63 typedef struct _ClutterMasterClockClass ClutterMasterClockClass;
65 struct _ClutterMasterClock
67 GObject parent_instance;
69 /* the list of timelines handled by the clock */
72 /* the current state of the clock, in usecs */
75 /* the previous state of the clock, in usecs, used to compute the delta */
78 #ifdef CLUTTER_ENABLE_DEBUG
80 gint64 remaining_budget;
83 /* an idle source, used by the Master Clock to queue
84 * a redraw on the stage and drive the animations
88 /* If the master clock is idle that means it has
89 * fallen back to idle polling for timeline
90 * progressions and it may have been some time since
91 * the last real stage update.
94 guint ensure_next_iteration : 1;
97 struct _ClutterMasterClockClass
99 GObjectClass parent_class;
102 struct _ClutterClockSource
106 ClutterMasterClock *master_clock;
109 static gboolean clutter_clock_prepare (GSource *source,
111 static gboolean clutter_clock_check (GSource *source);
112 static gboolean clutter_clock_dispatch (GSource *source,
113 GSourceFunc callback,
116 static GSourceFuncs clock_funcs = {
117 clutter_clock_prepare,
119 clutter_clock_dispatch,
123 #define clutter_master_clock_get_type _clutter_master_clock_get_type
125 G_DEFINE_TYPE (ClutterMasterClock, clutter_master_clock, G_TYPE_OBJECT);
128 * master_clock_is_running:
129 * @master_clock: a #ClutterMasterClock
131 * Checks if we should currently be advancing timelines or redrawing
134 * Return value: %TRUE if the #ClutterMasterClock has at least
135 * one running timeline
138 master_clock_is_running (ClutterMasterClock *master_clock)
140 ClutterStageManager *stage_manager = clutter_stage_manager_get_default ();
141 const GSList *stages, *l;
142 gboolean stage_free = FALSE;
144 stages = clutter_stage_manager_peek_stages (stage_manager);
146 /* If all of the stages are busy waiting for a swap-buffers to complete
147 * then we stop the master clock... */
148 for (l = stages; l != NULL; l = l->next)
150 if (_clutter_stage_get_pending_swaps (l->data) == 0)
160 if (master_clock->timelines)
163 for (l = stages; l; l = l->next)
165 if (_clutter_stage_has_queued_events (l->data) ||
166 _clutter_stage_needs_update (l->data))
170 if (master_clock->ensure_next_iteration)
172 master_clock->ensure_next_iteration = FALSE;
180 * master_clock_next_frame_delay:
181 * @master_clock: a #ClutterMasterClock
183 * Computes the number of delay before we need to draw the next frame.
185 * Return value: -1 if there is no next frame pending, otherwise the
186 * number of millseconds before the we need to draw the next frame
189 master_clock_next_frame_delay (ClutterMasterClock *master_clock)
193 if (!master_clock_is_running (master_clock))
196 /* When we have sync-to-vblank, we count on swap-buffer requests (or
197 * swap-buffer-complete events if supported in the backend) to throttle our
198 * frame rate so no additional delay is needed to start the next frame.
200 * If the master-clock has become idle due to no timeline progression causing
201 * redraws then we can no longer rely on vblank synchronization because the
202 * last real stage update/redraw may have happened a long time ago and so we
203 * fallback to polling for timeline progressions every 1/frame_rate seconds.
205 * (NB: if there aren't even any timelines running then the master clock will
206 * be completely stopped in master_clock_is_running())
208 if (clutter_feature_available (CLUTTER_FEATURE_SYNC_TO_VBLANK) &&
211 CLUTTER_NOTE (SCHEDULER, "vblank available and updated stages");
215 if (master_clock->prev_tick == 0)
217 /* If we weren't previously running, then draw the next frame
220 CLUTTER_NOTE (SCHEDULER, "draw the first frame immediately");
224 /* Otherwise, wait at least 1/frame_rate seconds since we last
227 now = g_source_get_time (master_clock->source);
229 next = master_clock->prev_tick;
231 /* If time has gone backwards then there's no way of knowing how
232 long we should wait so let's just dispatch immediately */
235 CLUTTER_NOTE (SCHEDULER, "Time has gone backwards");
240 next += (1000000L / clutter_get_default_frame_rate ());
244 CLUTTER_NOTE (SCHEDULER, "Less than %lu microsecs",
245 1000000L / (gulong) clutter_get_default_frame_rate ());
251 CLUTTER_NOTE (SCHEDULER, "Waiting %" G_GINT64_FORMAT " msecs",
252 (next - now) / 1000);
254 return (next - now) / 1000;
259 master_clock_process_events (ClutterMasterClock *master_clock,
263 #ifdef CLUTTER_ENABLE_DEBUG
264 gint64 start = g_get_monotonic_time ();
267 CLUTTER_STATIC_TIMER (master_event_process,
270 "The time spent processing events on all stages",
273 CLUTTER_TIMER_START (_clutter_uprof_context, master_event_process);
275 /* Process queued events */
276 for (l = stages; l != NULL; l = l->next)
278 /* NB: If a stage is busy waiting for a swap-buffers completion then
279 * we don't process its events so we can maximize the benefits of
280 * motion compression, and avoid multiple picks per frame.
282 if (_clutter_stage_get_pending_swaps (l->data) == 0)
283 _clutter_stage_process_queued_events (l->data);
286 CLUTTER_TIMER_STOP (_clutter_uprof_context, master_event_process);
288 #ifdef CLUTTER_ENABLE_DEBUG
289 if (_clutter_diagnostic_enabled ())
290 clutter_warn_if_over_budget (master_clock, start, "Event processing");
292 master_clock->remaining_budget -= (g_get_monotonic_time () - start);
297 * master_clock_advance_timelines:
298 * @master_clock: a #ClutterMasterClock
300 * Advances all the timelines held by the master clock. This function
301 * should be called before calling _clutter_stage_do_update() to
302 * make sure that all the timelines are advanced and the scene is updated.
305 master_clock_advance_timelines (ClutterMasterClock *master_clock)
307 GSList *timelines, *l;
308 #ifdef CLUTTER_ENABLE_DEBUG
309 gint64 start = g_get_monotonic_time ();
312 CLUTTER_STATIC_TIMER (master_timeline_advance,
314 "Timelines Advancement",
315 "The time spent advancing all timelines",
318 /* we protect ourselves from timelines being removed during
319 * the advancement by other timelines by copying the list of
320 * timelines, taking a reference on them, iterating over the
321 * copied list and then releasing the reference.
323 * we cannot simply take a reference on the timelines and still
324 * use the list held by the master clock because the do_tick()
325 * might result in the creation of a new timeline, which gets
326 * added at the end of the list with no reference increase and
327 * thus gets disposed at the end of the iteration.
329 * this implies that a newly added timeline will not be advanced
330 * by this clock iteration, which is perfectly fine since we're
331 * in its first cycle.
333 * we also cannot steal the master clock timelines list because
334 * a timeline might be removed as the direct result of do_tick()
335 * and remove_timeline() would not find the timeline, failing
336 * and leaving a dangling pointer behind.
338 timelines = g_slist_copy (master_clock->timelines);
339 g_slist_foreach (timelines, (GFunc) g_object_ref, NULL);
341 CLUTTER_TIMER_START (_clutter_uprof_context, master_timeline_advance);
343 for (l = timelines; l != NULL; l = l->next)
344 _clutter_timeline_do_tick (l->data, master_clock->cur_tick / 1000);
346 CLUTTER_TIMER_STOP (_clutter_uprof_context, master_timeline_advance);
348 g_slist_foreach (timelines, (GFunc) g_object_unref, NULL);
349 g_slist_free (timelines);
351 #ifdef CLUTTER_ENABLE_DEBUG
352 if (_clutter_diagnostic_enabled ())
353 clutter_warn_if_over_budget (master_clock, start, "Animations");
355 master_clock->remaining_budget -= (g_get_monotonic_time () - start);
360 master_clock_update_stages (ClutterMasterClock *master_clock,
363 gboolean stages_updated = FALSE;
365 #ifdef CLUTTER_ENABLE_DEBUG
366 gint64 start = g_get_monotonic_time ();
369 _clutter_run_repaint_functions (CLUTTER_REPAINT_FLAGS_PRE_PAINT);
371 /* Update any stage that needs redraw/relayout after the clock
374 for (l = stages; l != NULL; l = l->next)
376 /* If a stage has a swap-buffers pending we don't want to draw to it
377 * in case the driver may block the CPU while it waits for the next
378 * backbuffer to become available.
380 * TODO: We should be able to identify if we are running triple or N
381 * buffered and in these cases we can still draw if there is 1 swap
382 * pending so we can hopefully always be ready to swap for the next
383 * vblank and really match the vsync frequency.
385 if (_clutter_stage_get_pending_swaps (l->data) == 0)
386 stages_updated |= _clutter_stage_do_update (l->data);
389 _clutter_run_repaint_functions (CLUTTER_REPAINT_FLAGS_POST_PAINT);
391 #ifdef CLUTTER_ENABLE_DEBUG
392 if (_clutter_diagnostic_enabled ())
393 clutter_warn_if_over_budget (master_clock, start, "Updating the stage");
395 master_clock->remaining_budget -= (g_get_monotonic_time () - start);
398 return stages_updated;
402 * clutter_clock_source_new:
403 * @master_clock: a #ClutterMasterClock for the source
405 * The #ClutterClockSource is an idle GSource that will queue a redraw
406 * if @master_clock has at least a running #ClutterTimeline. The redraw
407 * will cause @master_clock to advance all timelines, thus advancing all
408 * animations as well.
410 * Return value: the newly created #GSource
413 clutter_clock_source_new (ClutterMasterClock *master_clock)
415 GSource *source = g_source_new (&clock_funcs, sizeof (ClutterClockSource));
416 ClutterClockSource *clock_source = (ClutterClockSource *) source;
418 g_source_set_name (source, "Clutter master clock");
419 clock_source->master_clock = master_clock;
425 clutter_clock_prepare (GSource *source,
428 ClutterClockSource *clock_source = (ClutterClockSource *) source;
429 ClutterMasterClock *master_clock = clock_source->master_clock;
432 clutter_threads_enter ();
434 if (G_UNLIKELY (clutter_paint_debug_flags &
435 CLUTTER_DEBUG_CONTINUOUS_REDRAW))
437 ClutterStageManager *stage_manager = clutter_stage_manager_get_default ();
438 const GSList *stages, *l;
440 stages = clutter_stage_manager_peek_stages (stage_manager);
442 /* Queue a full redraw on all of the stages */
443 for (l = stages; l != NULL; l = l->next)
444 clutter_actor_queue_redraw (l->data);
447 delay = master_clock_next_frame_delay (master_clock);
448 clutter_threads_leave ();
456 clutter_clock_check (GSource *source)
458 ClutterClockSource *clock_source = (ClutterClockSource *) source;
459 ClutterMasterClock *master_clock = clock_source->master_clock;
462 clutter_threads_enter ();
463 delay = master_clock_next_frame_delay (master_clock);
464 clutter_threads_leave ();
470 clutter_clock_dispatch (GSource *source,
471 GSourceFunc callback,
474 ClutterClockSource *clock_source = (ClutterClockSource *) source;
475 ClutterMasterClock *master_clock = clock_source->master_clock;
476 ClutterStageManager *stage_manager = clutter_stage_manager_get_default ();
477 gboolean stages_updated = FALSE;
480 CLUTTER_STATIC_TIMER (master_dispatch_timer,
483 "Master clock dispatch",
486 CLUTTER_TIMER_START (_clutter_uprof_context, master_dispatch_timer);
488 CLUTTER_NOTE (SCHEDULER, "Master clock [tick]");
490 clutter_threads_enter ();
492 /* Get the time to use for this frame */
493 master_clock->cur_tick = g_source_get_time (source);
495 #ifdef CLUTTER_ENABLE_DEBUG
496 master_clock->remaining_budget = master_clock->frame_budget;
499 /* We need to protect ourselves against stages being destroyed during
502 stages = clutter_stage_manager_list_stages (stage_manager);
503 g_slist_foreach (stages, (GFunc) g_object_ref, NULL);
505 master_clock->idle = FALSE;
507 /* Each frame is split into three separate phases: */
509 /* 1. process all the events; each stage goes through its events queue
510 * and processes each event according to its type, then emits the
511 * various signals that are associated with the event
513 master_clock_process_events (master_clock, stages);
515 /* 2. advance the timelines */
516 master_clock_advance_timelines (master_clock);
518 /* 3. relayout and redraw the stages */
519 stages_updated = master_clock_update_stages (master_clock, stages);
521 /* The master clock goes idle if no stages were updated and falls back
522 * to polling for timeline progressions... */
524 master_clock->idle = TRUE;
526 g_slist_foreach (stages, (GFunc) g_object_unref, NULL);
527 g_slist_free (stages);
529 master_clock->prev_tick = master_clock->cur_tick;
531 clutter_threads_leave ();
533 CLUTTER_TIMER_STOP (_clutter_uprof_context, master_dispatch_timer);
539 clutter_master_clock_finalize (GObject *gobject)
541 ClutterMasterClock *master_clock = CLUTTER_MASTER_CLOCK (gobject);
543 g_slist_free (master_clock->timelines);
545 G_OBJECT_CLASS (clutter_master_clock_parent_class)->finalize (gobject);
549 clutter_master_clock_class_init (ClutterMasterClockClass *klass)
551 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
553 gobject_class->finalize = clutter_master_clock_finalize;
557 clutter_master_clock_init (ClutterMasterClock *self)
561 source = clutter_clock_source_new (self);
562 self->source = source;
565 self->ensure_next_iteration = FALSE;
567 #ifdef CLUTTER_ENABLE_DEBUG
568 self->frame_budget = G_USEC_PER_SEC / 60;
571 g_source_set_priority (source, CLUTTER_PRIORITY_REDRAW);
572 g_source_set_can_recurse (source, FALSE);
573 g_source_attach (source, NULL);
577 * _clutter_master_clock_get_default:
579 * Retrieves the default master clock. If this function has never
580 * been called before, the default master clock is created.
582 * Return value: the default master clock. The returned object is
583 * owned by Clutter and should not be modified or freed
586 _clutter_master_clock_get_default (void)
588 ClutterMainContext *context = _clutter_context_get_default ();
590 if (G_UNLIKELY (context->master_clock == NULL))
591 context->master_clock = g_object_new (CLUTTER_TYPE_MASTER_CLOCK, NULL);
593 return context->master_clock;
597 * _clutter_master_clock_add_timeline:
598 * @master_clock: a #ClutterMasterClock
599 * @timeline: a #ClutterTimeline
601 * Adds @timeline to the list of playing timelines held by the master
605 _clutter_master_clock_add_timeline (ClutterMasterClock *master_clock,
606 ClutterTimeline *timeline)
610 if (g_slist_find (master_clock->timelines, timeline))
613 is_first = master_clock->timelines == NULL;
615 master_clock->timelines = g_slist_prepend (master_clock->timelines,
619 _clutter_master_clock_start_running (master_clock);
623 * _clutter_master_clock_remove_timeline:
624 * @master_clock: a #ClutterMasterClock
625 * @timeline: a #ClutterTimeline
627 * Removes @timeline from the list of playing timelines held by the
631 _clutter_master_clock_remove_timeline (ClutterMasterClock *master_clock,
632 ClutterTimeline *timeline)
634 master_clock->timelines = g_slist_remove (master_clock->timelines,
639 * _clutter_master_clock_start_running:
640 * @master_clock: a #ClutterMasterClock
642 * Called when we have events or redraws to process; if the clock
643 * is stopped, does the processing necessary to wake it up again.
646 _clutter_master_clock_start_running (ClutterMasterClock *master_clock)
648 /* If called from a different thread, we need to wake up the
649 * main loop to start running the timelines
651 g_main_context_wakeup (NULL);
655 * _clutter_master_clock_ensure_next_iteration:
656 * @master_clock: a #ClutterMasterClock
658 * Ensures that the master clock will run at least one iteration
661 _clutter_master_clock_ensure_next_iteration (ClutterMasterClock *master_clock)
663 g_return_if_fail (CLUTTER_IS_MASTER_CLOCK (master_clock));
665 master_clock->ensure_next_iteration = TRUE;