Chromium Code Reviews| Index: cc/animation/animation_player.cc |
| diff --git a/cc/animation/animation_player.cc b/cc/animation/animation_player.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..603ffa97e939d10368c37a6d7808cce02ececd20 |
| --- /dev/null |
| +++ b/cc/animation/animation_player.cc |
| @@ -0,0 +1,185 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "cc/animation/animation_player.h" |
| + |
| +#include "cc/animation/animation_delegate.h" |
| +#include "cc/animation/animation_host.h" |
| +#include "cc/animation/animation_timeline.h" |
| +#include "cc/animation/element_animations.h" |
| +#include "cc/animation/layer_animation_controller.h" |
| + |
| +namespace cc { |
| + |
| +scoped_refptr<AnimationPlayer> AnimationPlayer::Create(int id) { |
| + return make_scoped_refptr(new AnimationPlayer(id)); |
| +} |
| + |
| +AnimationPlayer::AnimationPlayer(int id) |
| + : animation_host_(), |
| + animation_timeline_(), |
| + element_animations_(), |
| + layer_animation_delegate_(), |
| + id_(id), |
| + layer_id_(0) { |
| + DCHECK(id_); |
| +} |
| + |
| +AnimationPlayer::~AnimationPlayer() { |
| + DCHECK(!animation_timeline_); |
| + DCHECK(!element_animations_); |
| + DCHECK(!layer_id_); |
| +} |
| + |
| +scoped_refptr<AnimationPlayer> AnimationPlayer::CreateImplInstance() const { |
| + scoped_refptr<AnimationPlayer> player = AnimationPlayer::Create(id()); |
| + return player; |
| +} |
| + |
| +void AnimationPlayer::SetAnimationHost(AnimationHost* animation_host) { |
| + animation_host_ = animation_host; |
| +} |
| + |
| +void AnimationPlayer::SetAnimationTimeline(AnimationTimeline* timeline) { |
| + if (animation_timeline_ == timeline) |
| + return; |
| + |
| + // We need to unregister player to manage ElementAnimations and observers |
| + // properly. |
| + if (layer_id_ && element_animations_) |
| + UnregisterPlayer(); |
| + |
| + animation_timeline_ = timeline; |
| + |
| + // Register player only if layer AND host attached. |
| + if (layer_id_ && animation_host_) |
| + RegisterPlayer(); |
| +} |
| + |
| +void AnimationPlayer::AttachLayer(int layer_id) { |
| + DCHECK_EQ(layer_id_, 0); |
| + DCHECK(layer_id); |
| + |
| + layer_id_ = layer_id; |
| + |
| + // Register player only if layer AND host attached. |
| + if (animation_host_) |
| + RegisterPlayer(); |
| +} |
| + |
| +void AnimationPlayer::DetachLayer() { |
| + DCHECK(layer_id_); |
| + |
| + if (animation_host_) |
| + UnregisterPlayer(); |
| + |
| + layer_id_ = 0; |
| +} |
| + |
| +void AnimationPlayer::RegisterPlayer() { |
| + DCHECK(layer_id_); |
| + DCHECK(animation_host_); |
| + DCHECK(!element_animations_); |
| + |
| + // Create LAC or re-use existing. |
| + animation_host_->RegisterPlayerForLayer(layer_id_, this); |
| + // Get local reference to shared LAC. |
| + BindElementAnimations(); |
| +} |
| + |
| +void AnimationPlayer::UnregisterPlayer() { |
| + DCHECK(layer_id_); |
| + DCHECK(animation_host_); |
| + DCHECK(element_animations_); |
| + |
| + UnbindElementAnimations(); |
| + // Destroy LAC or release it if it's still needed. |
| + animation_host_->UnregisterPlayerForLayer(layer_id_, this); |
| +} |
| + |
| +void AnimationPlayer::BindElementAnimations() { |
| + DCHECK(!element_animations_); |
| + element_animations_ = |
| + animation_host_->GetElementAnimationsForLayerId(layer_id_); |
| + DCHECK(element_animations_); |
| + |
| + // Pass all accumulated animations to LAC. |
| + for (auto it = animations_.begin(); it != animations_.end(); ++it) |
| + element_animations_->layer_animation_controller()->AddAnimation( |
| + animations_.take(it)); |
| + if (!animations_.empty()) |
|
Ian Vollick
2015/07/01 03:03:29
When will this be the case?
loyso (OOO)
2015/07/01 06:59:05
|take| doesn't erase elements. It makes the elemen
|
| + SetNeedsCommit(); |
| + animations_.clear(); |
| +} |
| + |
| +void AnimationPlayer::UnbindElementAnimations() { |
| + element_animations_ = nullptr; |
| + DCHECK(animations_.empty()); |
| +} |
| + |
| +void AnimationPlayer::AddAnimation(scoped_ptr<Animation> animation) { |
| + if (element_animations_) { |
| + element_animations_->layer_animation_controller()->AddAnimation( |
| + animation.Pass()); |
| + SetNeedsCommit(); |
| + } else { |
| + animations_.push_back(animation.Pass()); |
| + } |
| +} |
| + |
| +void AnimationPlayer::PauseAnimation(int animation_id, double time_offset) { |
| + DCHECK(element_animations_); |
| + element_animations_->layer_animation_controller()->PauseAnimation( |
| + animation_id, base::TimeDelta::FromSecondsD(time_offset)); |
| + SetNeedsCommit(); |
| +} |
| + |
| +void AnimationPlayer::RemoveAnimation(int animation_id) { |
| + if (element_animations_) { |
| + element_animations_->layer_animation_controller()->RemoveAnimation( |
| + animation_id); |
| + SetNeedsCommit(); |
| + } else { |
| + auto animations_to_remove = animations_.remove_if([animation_id]( |
| + Animation* animation) { return animation->id() == animation_id; }); |
| + animations_.erase(animations_to_remove, animations_.end()); |
| + } |
| +} |
| + |
| +void AnimationPlayer::PushPropertiesTo(AnimationPlayer* player_impl) { |
| + if (!element_animations_) { |
| + if (player_impl->element_animations()) |
| + player_impl->DetachLayer(); |
| + return; |
| + } |
| + |
| + DCHECK(layer_id_); |
| + if (!player_impl->element_animations()) |
| + player_impl->AttachLayer(layer_id_); |
| +} |
| + |
| +void AnimationPlayer::NotifyAnimationStarted( |
| + base::TimeTicks monotonic_time, |
| + Animation::TargetProperty target_property, |
| + int group) { |
| + if (layer_animation_delegate_) |
| + layer_animation_delegate_->NotifyAnimationStarted(monotonic_time, |
| + target_property, group); |
| +} |
| + |
| +void AnimationPlayer::NotifyAnimationFinished( |
| + base::TimeTicks monotonic_time, |
| + Animation::TargetProperty target_property, |
| + int group) { |
| + if (layer_animation_delegate_) |
| + layer_animation_delegate_->NotifyAnimationFinished(monotonic_time, |
| + target_property, group); |
| +} |
| + |
| +void AnimationPlayer::SetNeedsCommit() { |
| + DCHECK(animation_host_); |
| + animation_host_->SetNeedsCommit(); |
| +} |
| + |
| +} // namespace cc |