diff --git a/clutter/clutter-master-clock.c b/clutter/clutter-master-clock.c
index 1d67924..8e96075 100644
--- a/clutter/clutter-master-clock.c
+++ b/clutter/clutter-master-clock.c
@@ -74,6 +74,7 @@ struct _ClutterMasterClock
    */
   guint idle : 1;
   guint ensure_next_iteration : 1;
+  guint post_tick : 1;
 };
 
 struct _ClutterMasterClockClass
@@ -158,6 +159,26 @@ master_clock_is_running (ClutterMasterClock *master_clock)
   return FALSE;
 }
 
+static gint64
+clutter_master_clock_get_cur_tick (ClutterMasterClock *master_clock)
+{
+  gint64 cur_tick;
+
+  /* Get the time to use for this frame */
+#if GLIB_CHECK_VERSION (2, 27, 3)
+  cur_tick = g_source_get_time (master_clock->source);
+#else
+  {
+    GTimeVal source_time;
+    g_source_get_current_time (master_clock->source, &source_time);
+    cur_tick = source_time.tv_sec * 1000000L
+             + source_time.tv_usec;
+  }
+#endif
+
+  return cur_tick;
+}
+
 /*
  * master_clock_next_frame_delay:
  * @master_clock: a #ClutterMasterClock
@@ -206,16 +227,7 @@ master_clock_next_frame_delay (ClutterMasterClock *master_clock)
   /* Otherwise, wait at least 1/frame_rate seconds since we last
    * started a frame
    */
-#if GLIB_CHECK_VERSION (2, 27, 3)
-  now = g_source_get_time (master_clock->source);
-#else
-  {
-    GTimeVal source_time;
-    g_source_get_current_time (master_clock->source, &source_time);
-    now = source_time.tv_sec * 1000000L + source_time.tv_usec;
-  }
-#endif
-
+  now = clutter_master_clock_get_cur_tick (master_clock);
   next = master_clock->prev_tick;
 
   /* If time has gone backwards then there's no way of knowing how
@@ -328,16 +340,7 @@ clutter_clock_dispatch (GSource     *source,
   clutter_threads_enter ();
 
   /* Get the time to use for this frame */
-#if GLIB_CHECK_VERSION (2, 27, 3)
-  master_clock->cur_tick = g_source_get_time (source);
-#else
-  {
-    GTimeVal source_time;
-    g_source_get_current_time (source, &source_time);
-    master_clock->cur_tick = source_time.tv_sec * 1000000L
-                           + source_time.tv_usec;
-  }
-#endif
+  master_clock->cur_tick = clutter_master_clock_get_cur_tick (master_clock);
 
   /* We need to protect ourselves against stages being destroyed during
    * event handling
@@ -362,6 +365,7 @@ clutter_clock_dispatch (GSource     *source,
 
   CLUTTER_TIMER_STOP (_clutter_uprof_context, master_event_process);
 
+  master_clock->post_tick = FALSE;
   _clutter_master_clock_advance (master_clock);
 
   _clutter_run_repaint_functions ();
@@ -389,6 +393,9 @@ clutter_clock_dispatch (GSource     *source,
   if (!stages_updated)
     master_clock->idle = TRUE;
 
+  master_clock->post_tick = TRUE;
+  _clutter_master_clock_advance (master_clock);
+
   g_slist_foreach (stages, (GFunc) g_object_unref, NULL);
   g_slist_free (stages);
 
@@ -524,6 +531,7 @@ _clutter_master_clock_start_running (ClutterMasterClock *master_clock)
 void
 _clutter_master_clock_advance (ClutterMasterClock *master_clock)
 {
+  gint64 tick;
   GSList *timelines, *l;
 
   CLUTTER_STATIC_TIMER (master_timeline_advance,
@@ -559,8 +567,18 @@ _clutter_master_clock_advance (ClutterMasterClock *master_clock)
   timelines = g_slist_copy (master_clock->timelines);
   g_slist_foreach (timelines, (GFunc) g_object_ref, NULL);
 
-  for (l = timelines; l != NULL; l = l->next)
-    _clutter_timeline_do_tick (l->data, master_clock->cur_tick / 1000);
+  if (master_clock->post_tick)
+    {
+      tick = clutter_master_clock_get_cur_tick (master_clock) / 1000;
+      for (l = timelines; l != NULL; l = l->next)
+        _clutter_timeline_do_post_tick (l->data, tick);
+    }
+  else
+    {
+      tick = master_clock->cur_tick / 1000;
+      for (l = timelines; l != NULL; l = l->next)
+        _clutter_timeline_do_tick (l->data, tick);
+    }
 
   g_slist_foreach (timelines, (GFunc) g_object_unref, NULL);
   g_slist_free (timelines);
diff --git a/clutter/clutter-timeline.c b/clutter/clutter-timeline.c
index a2db02f..8559e77 100644
--- a/clutter/clutter-timeline.c
+++ b/clutter/clutter-timeline.c
@@ -1265,8 +1265,9 @@ _clutter_timeline_do_tick (ClutterTimeline *timeline,
     {
       priv->last_frame_time = tick_time;
       priv->msecs_delta = 0;
-      priv->waiting_first_tick = FALSE;
       clutter_timeline_do_frame (timeline);
+
+      /* The waiting_first_tick flag is reset in do_post_tick */
     }
   else
     {
@@ -1295,6 +1296,31 @@ _clutter_timeline_do_tick (ClutterTimeline *timeline,
     }
 }
 
+void
+_clutter_timeline_do_post_tick (ClutterTimeline *timeline,
+                                gint64           tick_time)
+{
+  ClutterTimelinePrivate *priv;
+
+  g_return_if_fail (CLUTTER_IS_TIMELINE (timeline));
+
+  priv = timeline->priv;
+
+  if (!priv->is_playing)
+    return;
+
+  /* If we've just processed the first frame, update the tick as if this was
+   * the time of the first frame. Although this introduces a time discrepancy
+   * for the second frame, it means that we don't so often drop frames at the
+   * beginning of animations.
+   */
+  if (priv->waiting_first_tick)
+    {
+      priv->waiting_first_tick = FALSE;
+      priv->last_frame_time = tick_time;
+    }
+}
+
 static inline void
 clutter_timeline_add_marker_internal (ClutterTimeline *timeline,
                                       const gchar     *marker_name,
diff --git a/clutter/clutter-timeline.h b/clutter/clutter-timeline.h
index 95f2bfa..3f18952 100644
--- a/clutter/clutter-timeline.h
+++ b/clutter/clutter-timeline.h
@@ -159,6 +159,8 @@ void             clutter_timeline_advance_to_marker     (ClutterTimeline *timeli
 /*< private >*/
 void             _clutter_timeline_do_tick              (ClutterTimeline *timeline,
                                                          gint64           tick_time);
+void             _clutter_timeline_do_post_tick         (ClutterTimeline *timeline,
+                                                         gint64           tick_time);
 
 G_END_DECLS
 

