15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer_animator.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/animation/animation_id_provider.h"
111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "cc/output/begin_frame_args.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/compositor.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer_animation_delegate.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer_animation_observer.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer_animation_sequence.h"
1746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/compositor/layer_animator_collection.h"
181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ui/gfx/frame_time.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SAFE_INVOKE_VOID(function, running_anim, ...) \
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (running_anim.is_sequence_alive()) \
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      function(running_anim.sequence(), ##__VA_ARGS__)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SAFE_INVOKE_BOOL(function, running_anim) \
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ((running_anim.is_sequence_alive()) \
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ? function(running_anim.sequence()) \
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : false)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SAFE_INVOKE_PTR(function, running_anim) \
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ((running_anim.is_sequence_alive()) \
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ? function(running_anim.sequence()) \
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        : NULL)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kDefaultTransitionDurationMs = 120;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LayerAnimator public --------------------------------------------------------
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LayerAnimator::LayerAnimator(base::TimeDelta transition_duration)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : delegate_(NULL),
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      preemption_strategy_(IMMEDIATELY_SET_NEW_TARGET),
45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      is_transition_duration_locked_(false),
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      transition_duration_(transition_duration),
47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      tween_type_(gfx::Tween::LINEAR),
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_started_(false),
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      disable_timer_for_test_(false),
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      adding_animations_(false) {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LayerAnimator::~LayerAnimator() {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < running_animations_.size(); ++i) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (running_animations_[i].is_sequence_alive())
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      running_animations_[i].sequence()->OnAnimatorDestroyed();
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClearAnimationsInternal();
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_ = NULL;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LayerAnimator* LayerAnimator::CreateDefaultAnimator() {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new LayerAnimator(base::TimeDelta::FromMilliseconds(0));
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LayerAnimator* LayerAnimator::CreateImplicitAnimator() {
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return new LayerAnimator(
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::TimeDelta::FromMilliseconds(kDefaultTransitionDurationMs));
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This macro provides the implementation for the setter and getter (well,
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// the getter of the target value) for an animated property. For example,
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// it is used for the implementations of SetTransform and GetTargetTransform.
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// It is worth noting that SetFoo avoids invoking the usual animation machinery
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// if the transition duration is zero -- in this case we just set the property
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// on the layer animation delegate immediately.
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define ANIMATED_PROPERTY(type, property, name, member_type, member)  \
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LayerAnimator::Set##name(type value) {                           \
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeDelta duration = GetTransitionDuration();                 \
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (duration == base::TimeDelta() && delegate() &&                  \
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (preemption_strategy_ != ENQUEUE_NEW_ANIMATION)) {              \
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    StopAnimatingProperty(LayerAnimationElement::property);           \
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delegate()->Set##name##FromAnimation(value);                      \
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;                                                           \
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }                                                                   \
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<LayerAnimationElement> element(                          \
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LayerAnimationElement::Create##name##Element(value, duration)); \
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  element->set_tween_type(tween_type_);                               \
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StartAnimation(new LayerAnimationSequence(element.release()));      \
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}                                                                     \
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                                      \
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)member_type LayerAnimator::GetTarget##name() const {                  \
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerAnimationElement::TargetValue target(delegate());              \
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetTargetValue(&target);                                            \
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return target.member;                                               \
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ANIMATED_PROPERTY(
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Transform&, TRANSFORM, Transform, gfx::Transform, transform);
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ANIMATED_PROPERTY(const gfx::Rect&, BOUNDS, Bounds, gfx::Rect, bounds);
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ANIMATED_PROPERTY(float, OPACITY, Opacity, float, opacity);
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ANIMATED_PROPERTY(bool, VISIBILITY, Visibility, bool, visibility);
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ANIMATED_PROPERTY(float, BRIGHTNESS, Brightness, float, brightness);
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ANIMATED_PROPERTY(float, GRAYSCALE, Grayscale, float, grayscale);
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ANIMATED_PROPERTY(SkColor, COLOR, Color, SkColor, color);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::TimeDelta LayerAnimator::GetTransitionDuration() const {
110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return transition_duration_;
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::SetDelegate(LayerAnimationDelegate* delegate) {
11446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (delegate_ && is_started_) {
11546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
11646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (collection)
11746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      collection->StopAnimator(this);
11846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delegate_ = delegate;
12046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (delegate_ && is_started_) {
12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (collection)
12346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      collection->StartAnimator(this);
12446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::StartAnimation(LayerAnimationSequence* animation) {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<LayerAnimator> retain(this);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnScheduled(animation);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!StartSequenceImmediately(animation)) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Attempt to preempt a running animation.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (preemption_strategy_) {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case IMMEDIATELY_SET_NEW_TARGET:
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ImmediatelySetNewTarget(animation);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case IMMEDIATELY_ANIMATE_TO_NEW_TARGET:
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ImmediatelyAnimateToNewTarget(animation);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case ENQUEUE_NEW_ANIMATION:
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        EnqueueNewAnimation(animation);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case REPLACE_QUEUED_ANIMATIONS:
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ReplaceQueuedAnimations(animation);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case BLEND_WITH_CURRENT_ANIMATION: {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // TODO(vollick) Add support for blended sequences and use them here.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NOTIMPLEMENTED();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FinishAnyAnimationWithZeroDuration();
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateAnimationState();
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::ScheduleAnimation(LayerAnimationSequence* animation) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<LayerAnimator> retain(this);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OnScheduled(animation);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_animating()) {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    animation_queue_.push_back(make_linked_ptr(animation));
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ProcessQueue();
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    StartSequenceImmediately(animation);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateAnimationState();
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LayerAnimator::StartTogether(
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<LayerAnimationSequence*>& animations) {
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<LayerAnimator> retain(this);
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (preemption_strategy_ == IMMEDIATELY_SET_NEW_TARGET) {
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<LayerAnimationSequence*>::const_iterator iter;
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (iter = animations.begin(); iter != animations.end(); ++iter) {
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      StartAnimation(*iter);
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  adding_animations_ = true;
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!is_animating()) {
18146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
18246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (collection && collection->HasActiveAnimators())
18346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      last_step_time_ = collection->last_tick_time();
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
1851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      last_step_time_ = gfx::FrameTime::Now();
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Collect all the affected properties.
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LayerAnimationElement::AnimatableProperties animated_properties =
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      LayerAnimationElement::UNKNOWN;
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<LayerAnimationSequence*>::const_iterator iter;
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (iter = animations.begin(); iter != animations.end(); ++iter)
1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    animated_properties |= (*iter)->properties();
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Starting a zero duration pause that affects all the animated properties
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // will prevent any of the sequences from animating until there are no
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // running animations that affect any of these properties, as well as
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // handle preemption strategy.
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StartAnimation(new LayerAnimationSequence(
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LayerAnimationElement::CreatePauseElement(animated_properties,
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                base::TimeDelta())));
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool wait_for_group_start = false;
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (iter = animations.begin(); iter != animations.end(); ++iter)
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    wait_for_group_start |= (*iter)->IsFirstElementThreaded();
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int group_id = cc::AnimationIdProvider::NextGroupId();
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // These animations (provided they don't animate any common properties) will
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // now animate together if trivially scheduled.
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (iter = animations.begin(); iter != animations.end(); ++iter) {
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*iter)->set_animation_group_id(group_id);
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*iter)->set_waiting_for_group_start(wait_for_group_start);
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ScheduleAnimation(*iter);
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  adding_animations_ = false;
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateAnimationState();
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::ScheduleTogether(
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::vector<LayerAnimationSequence*>& animations) {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<LayerAnimator> retain(this);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Collect all the affected properties.
2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  LayerAnimationElement::AnimatableProperties animated_properties =
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      LayerAnimationElement::UNKNOWN;
2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<LayerAnimationSequence*>::const_iterator iter;
2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (iter = animations.begin(); iter != animations.end(); ++iter)
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    animated_properties |= (*iter)->properties();
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Scheduling a zero duration pause that affects all the animated properties
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will prevent any of the sequences from animating until there are no
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // running animations that affect any of these properties.
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAnimation(new LayerAnimationSequence(
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LayerAnimationElement::CreatePauseElement(animated_properties,
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                base::TimeDelta())));
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool wait_for_group_start = false;
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (iter = animations.begin(); iter != animations.end(); ++iter)
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    wait_for_group_start |= (*iter)->IsFirstElementThreaded();
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int group_id = cc::AnimationIdProvider::NextGroupId();
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These animations (provided they don't animate any common properties) will
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // now animate together if trivially scheduled.
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (iter = animations.begin(); iter != animations.end(); ++iter) {
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*iter)->set_animation_group_id(group_id);
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    (*iter)->set_waiting_for_group_start(wait_for_group_start);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScheduleAnimation(*iter);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateAnimationState();
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::SchedulePauseForProperties(
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::TimeDelta duration,
2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LayerAnimationElement::AnimatableProperties properties_to_pause) {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScheduleAnimation(new ui::LayerAnimationSequence(
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        ui::LayerAnimationElement::CreatePauseElement(
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            properties_to_pause, duration)));
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool LayerAnimator::IsAnimatingProperty(
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LayerAnimationElement::AnimatableProperty property) const {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (AnimationQueue::const_iterator queue_iter = animation_queue_.begin();
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       queue_iter != animation_queue_.end(); ++queue_iter) {
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if ((*queue_iter)->properties() & property)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::StopAnimatingProperty(
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LayerAnimationElement::AnimatableProperty property) {
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<LayerAnimator> retain(this);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (true) {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // GetRunningAnimation purges deleted animations before searching, so we are
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // guaranteed to find a live animation if any is returned at all.
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunningAnimation* running = GetRunningAnimation(property);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!running)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // As was mentioned above, this sequence must be alive.
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(running->is_sequence_alive());
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FinishAnimation(running->sequence(), false);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::AddObserver(LayerAnimationObserver* observer) {
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!observers_.HasObserver(observer))
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observers_.AddObserver(observer);
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::RemoveObserver(LayerAnimationObserver* observer) {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observers_.RemoveObserver(observer);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove the observer from all sequences as well.
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       queue_iter != animation_queue_.end(); ++queue_iter) {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*queue_iter)->RemoveObserver(observer);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LayerAnimator::OnThreadedAnimationStarted(
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const cc::AnimationEvent& event) {
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LayerAnimationElement::AnimatableProperty property =
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerAnimationElement::ToAnimatableProperty(event.target_property);
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunningAnimation* running = GetRunningAnimation(property);
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!running)
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(running->is_sequence_alive());
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (running->sequence()->animation_group_id() != event.group_id)
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  running->sequence()->OnThreadedAnimationStarted(event);
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!running->sequence()->waiting_for_group_start())
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  base::TimeTicks start_time = event.monotonic_time;
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  running->sequence()->set_waiting_for_group_start(false);
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The call to GetRunningAnimation made above already purged deleted
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // animations, so we are guaranteed that all the animations we iterate
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // over now are alive.
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (RunningAnimations::iterator iter = running_animations_.begin();
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != running_animations_.end(); ++iter) {
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Ensure that each sequence is only Started once, regardless of the
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // number of sequences in the group that have threaded first elements.
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (((*iter).sequence()->animation_group_id() == event.group_id) &&
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        !(*iter).sequence()->IsFirstElementThreaded() &&
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        (*iter).sequence()->waiting_for_group_start()) {
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (*iter).sequence()->set_start_time(start_time);
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (*iter).sequence()->set_waiting_for_group_start(false);
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (*iter).sequence()->Start(delegate());
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
34446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void LayerAnimator::AddToCollection(LayerAnimatorCollection* collection) {
34546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (is_animating() && !is_started_) {
34646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    collection->StartAnimator(this);
34746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    is_started_ = true;
34846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
34946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
35046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
35146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void LayerAnimator::RemoveFromCollection(LayerAnimatorCollection* collection) {
35246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (is_animating() && is_started_) {
35346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    collection->StopAnimator(this);
35446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    is_started_ = false;
35546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
35646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
35746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LayerAnimator protected -----------------------------------------------------
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::ProgressAnimation(LayerAnimationSequence* sequence,
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      base::TimeTicks now) {
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!delegate() || sequence->waiting_for_group_start())
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sequence->Progress(now, delegate());
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::ProgressAnimationToEnd(LayerAnimationSequence* sequence) {
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!delegate())
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  sequence->ProgressToEnd(delegate());
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool LayerAnimator::HasAnimation(LayerAnimationSequence* sequence) const {
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (AnimationQueue::const_iterator queue_iter = animation_queue_.begin();
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       queue_iter != animation_queue_.end(); ++queue_iter) {
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((*queue_iter).get() == sequence)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LayerAnimator private -------------------------------------------------------
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::Step(base::TimeTicks now) {
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TRACE_EVENT0("ui", "LayerAnimator::Step");
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<LayerAnimator> retain(this);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  last_step_time_ = now;
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PurgeDeletedAnimations();
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We need to make a copy of the running animations because progressing them
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and finishing them may indirectly affect the collection of running
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // animations.
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunningAnimations running_animations_copy = running_animations_;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < running_animations_copy.size(); ++i) {
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (running_animations_copy[i].sequence()->IsFinished(now)) {
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SAFE_INVOKE_VOID(FinishAnimation, running_animations_copy[i], false);
4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SAFE_INVOKE_VOID(ProgressAnimation, running_animations_copy[i], now);
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LayerAnimator::StopAnimatingInternal(bool abort) {
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<LayerAnimator> retain(this);
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while (is_animating()) {
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // We're going to attempt to finish the first running animation. Let's
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // ensure that it's valid.
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PurgeDeletedAnimations();
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // If we've purged all running animations, attempt to start one up.
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (running_animations_.empty())
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ProcessQueue();
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DCHECK(!running_animations_.empty());
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Still no luck, let's just bail and clear all animations.
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (running_animations_.empty()) {
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ClearAnimationsInternal();
4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SAFE_INVOKE_VOID(FinishAnimation, running_animations_[0], abort);
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::UpdateAnimationState() {
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (disable_timer_for_test_)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool should_start = is_animating();
43846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
43946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (collection) {
44046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (should_start && !is_started_)
44146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      collection->StartAnimator(this);
44246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    else if (!should_start && is_started_)
44346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      collection->StopAnimator(this);
44446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    is_started_ = should_start;
44546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  } else {
44646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    is_started_ = false;
44746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  }
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LayerAnimationSequence* LayerAnimator::RemoveAnimation(
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LayerAnimationSequence* sequence) {
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  linked_ptr<LayerAnimationSequence> to_return;
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_running = false;
4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First remove from running animations
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (RunningAnimations::iterator iter = running_animations_.begin();
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != running_animations_.end(); ++iter) {
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((*iter).sequence() == sequence) {
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      running_animations_.erase(iter);
4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_running = true;
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Then remove from the queue
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       queue_iter != animation_queue_.end(); ++queue_iter) {
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((*queue_iter) == sequence) {
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      to_return = *queue_iter;
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      animation_queue_.erase(queue_iter);
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!to_return.get() ||
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !to_return->waiting_for_group_start() ||
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !to_return->IsFirstElementThreaded())
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return to_return.release();
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The removed sequence may have been responsible for making other sequences
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // wait for a group start. If no other sequences in the group have a
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // threaded first element, the group no longer needs the additional wait.
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_wait_still_needed = false;
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int group_id = to_return->animation_group_id();
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       queue_iter != animation_queue_.end(); ++queue_iter) {
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (((*queue_iter)->animation_group_id() == group_id) &&
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        (*queue_iter)->IsFirstElementThreaded()) {
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      is_wait_still_needed = true;
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (is_wait_still_needed)
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return to_return.release();
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       queue_iter != animation_queue_.end(); ++queue_iter) {
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if ((*queue_iter)->animation_group_id() == group_id &&
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        (*queue_iter)->waiting_for_group_start()) {
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (*queue_iter)->set_waiting_for_group_start(false);
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (is_running) {
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        (*queue_iter)->set_start_time(last_step_time_);
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        (*queue_iter)->Start(delegate());
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return to_return.release();
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void LayerAnimator::FinishAnimation(
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LayerAnimationSequence* sequence, bool abort) {
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<LayerAnimator> retain(this);
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<LayerAnimationSequence> removed(RemoveAnimation(sequence));
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (abort)
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sequence->Abort(delegate());
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  else
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ProgressAnimationToEnd(sequence);
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProcessQueue();
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateAnimationState();
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::FinishAnyAnimationWithZeroDuration() {
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<LayerAnimator> retain(this);
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Special case: if we've started a 0 duration animation, just finish it now
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and get rid of it. We need to make a copy because Progress may indirectly
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // cause new animations to start running.
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunningAnimations running_animations_copy = running_animations_;
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < running_animations_copy.size(); ++i) {
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (running_animations_copy[i].sequence()->IsFinished(
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          running_animations_copy[i].sequence()->start_time())) {
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SAFE_INVOKE_VOID(ProgressAnimationToEnd, running_animations_copy[i]);
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_ptr<LayerAnimationSequence> removed(
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          SAFE_INVOKE_PTR(RemoveAnimation, running_animations_copy[i]));
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProcessQueue();
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateAnimationState();
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::ClearAnimations() {
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<LayerAnimator> retain(this);
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClearAnimationsInternal();
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LayerAnimator::RunningAnimation* LayerAnimator::GetRunningAnimation(
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LayerAnimationElement::AnimatableProperty property) {
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PurgeDeletedAnimations();
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (RunningAnimations::iterator iter = running_animations_.begin();
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != running_animations_.end(); ++iter) {
5555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if ((*iter).sequence()->properties() & property)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return &(*iter);
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::AddToQueueIfNotPresent(LayerAnimationSequence* animation) {
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If we don't have the animation in the queue yet, add it.
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool found_sequence = false;
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       queue_iter != animation_queue_.end(); ++queue_iter) {
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((*queue_iter) == animation) {
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      found_sequence = true;
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!found_sequence)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    animation_queue_.push_front(make_linked_ptr(animation));
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::RemoveAllAnimationsWithACommonProperty(
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LayerAnimationSequence* sequence, bool abort) {
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For all the running animations, if they animate the same property,
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // progress them to the end and remove them. Note, Aborting or Progressing
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // animations may affect the collection of running animations, so we need to
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // operate on a copy.
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunningAnimations running_animations_copy = running_animations_;
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < running_animations_copy.size(); ++i) {
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (running_animations_copy[i].sequence()->HasConflictingProperty(
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            sequence->properties())) {
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_ptr<LayerAnimationSequence> removed(
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          SAFE_INVOKE_PTR(RemoveAnimation, running_animations_copy[i]));
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (abort)
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        running_animations_copy[i].sequence()->Abort(delegate());
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SAFE_INVOKE_VOID(ProgressAnimationToEnd, running_animations_copy[i]);
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Same for the queued animations that haven't been started. Again, we'll
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // need to operate on a copy.
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<base::WeakPtr<LayerAnimationSequence> > sequences;
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       queue_iter != animation_queue_.end(); ++queue_iter)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sequences.push_back((*queue_iter)->AsWeakPtr());
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < sequences.size(); ++i) {
606868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!sequences[i].get() || !HasAnimation(sequences[i].get()))
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (sequences[i]->HasConflictingProperty(sequence->properties())) {
610868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      scoped_ptr<LayerAnimationSequence> removed(
611868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          RemoveAnimation(sequences[i].get()));
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (abort)
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        sequences[i]->Abort(delegate());
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else
615868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        ProgressAnimationToEnd(sequences[i].get());
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::ImmediatelySetNewTarget(LayerAnimationSequence* sequence) {
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Need to detect if our sequence gets destroyed.
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sequence->AsWeakPtr();
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool abort = false;
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RemoveAllAnimationsWithACommonProperty(sequence, abort);
627868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!weak_sequence_ptr.get())
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LayerAnimationSequence* removed = RemoveAnimation(sequence);
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(removed == NULL || removed == sequence);
632868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!weak_sequence_ptr.get())
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ProgressAnimationToEnd(sequence);
636868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!weak_sequence_ptr.get())
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete sequence;
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::ImmediatelyAnimateToNewTarget(
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LayerAnimationSequence* sequence) {
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Need to detect if our sequence gets destroyed.
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sequence->AsWeakPtr();
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool abort = true;
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RemoveAllAnimationsWithACommonProperty(sequence, abort);
650868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!weak_sequence_ptr.get())
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddToQueueIfNotPresent(sequence);
654868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!weak_sequence_ptr.get())
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StartSequenceImmediately(sequence);
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::EnqueueNewAnimation(LayerAnimationSequence* sequence) {
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It is assumed that if there was no conflicting animation, we would
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not have been called. No need to check for a collision; just
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // add to the queue.
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  animation_queue_.push_back(make_linked_ptr(sequence));
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProcessQueue();
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::ReplaceQueuedAnimations(LayerAnimationSequence* sequence) {
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Need to detect if our sequence gets destroyed.
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtr<LayerAnimationSequence> weak_sequence_ptr =
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sequence->AsWeakPtr();
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Remove all animations that aren't running. Note: at each iteration i is
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // incremented or an element is removed from the queue, so
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // animation_queue_.size() - i is always decreasing and we are always making
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // progress towards the loop terminating.
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < animation_queue_.size();) {
678868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!weak_sequence_ptr.get())
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PurgeDeletedAnimations();
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_running = false;
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (RunningAnimations::const_iterator iter = running_animations_.begin();
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         iter != running_animations_.end(); ++iter) {
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if ((*iter).sequence() == animation_queue_[i].get()) {
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        is_running = true;
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!is_running)
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delete RemoveAnimation(animation_queue_[i].get());
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++i;
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  animation_queue_.push_back(make_linked_ptr(sequence));
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProcessQueue();
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::ProcessQueue() {
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool started_sequence = false;
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do {
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    started_sequence = false;
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Build a list of all currently animated properties.
7065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    LayerAnimationElement::AnimatableProperties animated =
7075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        LayerAnimationElement::UNKNOWN;
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (RunningAnimations::const_iterator iter = running_animations_.begin();
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         iter != running_animations_.end(); ++iter) {
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!(*iter).is_sequence_alive())
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
7125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      animated |= (*iter).sequence()->properties();
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Try to find an animation that doesn't conflict with an animated
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // property or a property that will be animated before it. Note: starting
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the animation may indirectly cause more animations to be started, so we
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // need to operate on a copy.
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<base::WeakPtr<LayerAnimationSequence> > sequences;
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (AnimationQueue::iterator queue_iter = animation_queue_.begin();
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         queue_iter != animation_queue_.end(); ++queue_iter)
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sequences.push_back((*queue_iter)->AsWeakPtr());
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < sequences.size(); ++i) {
726868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (!sequences[i].get() || !HasAnimation(sequences[i].get()))
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!sequences[i]->HasConflictingProperty(animated)) {
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        StartSequenceImmediately(sequences[i].get());
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        started_sequence = true;
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Animation couldn't be started. Add its properties to the collection so
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // that we don't start a conflicting animation. For example, if our queue
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // has the elements { {T,B}, {B} } (that is, an element that animates both
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // the transform and the bounds followed by an element that animates the
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // bounds), and we're currently animating the transform, we can't start
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // the first element because it animates the transform, too. We cannot
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // start the second element, either, because the first element animates
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // bounds too, and needs to go first.
7435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      animated |= sequences[i]->properties();
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If we started a sequence, try again. We may be able to start several.
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while (started_sequence);
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool LayerAnimator::StartSequenceImmediately(LayerAnimationSequence* sequence) {
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PurgeDeletedAnimations();
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that no one is animating one of the sequence's properties already.
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (RunningAnimations::const_iterator iter = running_animations_.begin();
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != running_animations_.end(); ++iter) {
7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if ((*iter).sequence()->HasConflictingProperty(sequence->properties()))
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All clear, actually start the sequence. Note: base::TimeTicks::Now has
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a resolution that can be as bad as 15ms. If this causes glitches in the
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // animations, this can be switched to HighResNow() (animation uses Now()
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // internally).
76446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  // All LayerAnimators share the same LayerAnimatorCollection. Use the
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // last_tick_time() from there to ensure animations started during the same
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // event complete at the same time.
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeTicks start_time;
76846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  LayerAnimatorCollection* collection = GetLayerAnimatorCollection();
7692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (is_animating() || adding_animations_)
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    start_time = last_step_time_;
77146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  else if (collection && collection->HasActiveAnimators())
77246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    start_time = collection->last_tick_time();
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
7741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    start_time = gfx::FrameTime::Now();
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!sequence->animation_group_id())
7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sequence->set_animation_group_id(cc::AnimationIdProvider::NextGroupId());
7782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!sequence->waiting_for_group_start() ||
7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      sequence->IsFirstElementThreaded()) {
7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sequence->set_start_time(start_time);
7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sequence->Start(delegate());
7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  running_animations_.push_back(
7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      RunningAnimation(sequence->AsWeakPtr()));
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Need to keep a reference to the animation.
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddToQueueIfNotPresent(sequence);
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that animations get stepped at their start time.
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Step(start_time);
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::GetTargetValue(
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LayerAnimationElement::TargetValue* target) const {
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (AnimationQueue::const_iterator iter = animation_queue_.begin();
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       iter != animation_queue_.end(); ++iter) {
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (*iter)->GetTargetValue(target);
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::OnScheduled(LayerAnimationSequence* sequence) {
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (observers_.might_have_observers()) {
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ObserverListBase<LayerAnimationObserver>::Iterator it(observers_);
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LayerAnimationObserver* obs;
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while ((obs = it.GetNext()) != NULL) {
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sequence->AddObserver(obs);
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sequence->OnScheduled();
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
814a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void LayerAnimator::SetTransitionDuration(base::TimeDelta duration) {
815a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (is_transition_duration_locked_)
816a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
817a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  transition_duration_ = duration;
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::ClearAnimationsInternal() {
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PurgeDeletedAnimations();
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Abort should never affect the set of running animations, but just in case
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // clients are badly behaved, we will use a copy of the running animations.
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RunningAnimations running_animations_copy = running_animations_;
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < running_animations_copy.size(); ++i) {
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!SAFE_INVOKE_BOOL(HasAnimation, running_animations_copy[i]))
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<LayerAnimationSequence> removed(
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        RemoveAnimation(running_animations_copy[i].sequence()));
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (removed.get())
8332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      removed->Abort(delegate());
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This *should* have cleared the list of running animations.
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(running_animations_.empty());
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  running_animations_.clear();
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  animation_queue_.clear();
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateAnimationState();
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LayerAnimator::PurgeDeletedAnimations() {
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < running_animations_.size();) {
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!running_animations_[i].is_sequence_alive())
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      running_animations_.erase(running_animations_.begin() + i);
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      i++;
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)LayerAnimatorCollection* LayerAnimator::GetLayerAnimatorCollection() {
85246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return delegate_ ? delegate_->GetLayerAnimatorCollection() : NULL;
85346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}
85446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LayerAnimator::RunningAnimation::RunningAnimation(
8562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::WeakPtr<LayerAnimationSequence>& sequence)
8572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : sequence_(sequence) {
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LayerAnimator::RunningAnimation::~RunningAnimation() { }
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ui
863