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..a5e0e64f2207cb4f4d0bdda128d64107eaae178d |
| --- /dev/null |
| +++ b/cc/animation/animation_player.cc |
| @@ -0,0 +1,295 @@ |
| +// 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_host.h" |
| +#include "cc/animation/animation_registrar.h" |
| +#include "cc/animation/animation_timeline.h" |
| +#include "cc/layers/layer.h" |
| +#include "cc/trees/layer_tree_mutators_client.h" |
| + |
| +namespace cc { |
| + |
| +class AnimationPlayer::ValueObserver : public LayerAnimationValueObserver { |
| + public: |
| + ValueObserver(AnimationPlayer* player, bool is_active) |
| + : player_(player), is_active_(is_active) { |
|
Ian Vollick
2015/05/05 03:52:06
Just to make sure I'm understanding this correctly
loyso (OOO)
2015/05/05 06:51:18
Yes, that's absolutely correct.
|
| + DCHECK(player_); |
| + } |
| + |
| + // LayerAnimationValueObserver implementation. |
| + void OnFilterAnimated(const FilterOperations& filters) override { |
| + player_->SetFilterMutated(is_active_, filters); |
| + } |
| + |
| + void OnOpacityAnimated(float opacity) override { |
| + player_->SetOpacityMutated(is_active_, opacity); |
| + } |
| + |
| + void OnTransformAnimated(const gfx::Transform& transform) override { |
| + player_->SetTransformMutated(is_active_, transform); |
| + } |
| + |
| + void OnScrollOffsetAnimated(const gfx::ScrollOffset& scroll_offset) override { |
| + player_->SetScrollOffsetMutated(is_active_, scroll_offset); |
| + } |
| + |
| + void OnAnimationWaitingForDeletion() override { |
| + // TODO(loyso): implement it. |
|
Ian Vollick
2015/05/05 03:52:06
Why's it ok to put this off?
loyso (OOO)
2015/05/05 06:51:18
It's in separate CL for scroll offset. https://cod
Ian Vollick
2015/05/07 13:58:42
My questions is more about staging. Will the code
loyso (OOO)
2015/05/08 01:04:34
We don't run this code path w/o --enable_composito
Ian Vollick
2015/05/08 14:58:22
K, great.
|
| + } |
| + |
| + bool IsActive() const override { return is_active_; } |
| + |
| + private: |
| + AnimationPlayer* player_; |
| + bool is_active_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ValueObserver); |
| +}; |
| + |
| +scoped_refptr<AnimationPlayer> AnimationPlayer::Create(int id) { |
| + return make_scoped_refptr(new AnimationPlayer(id)); |
| +} |
| + |
| +AnimationPlayer::AnimationPlayer(int id) |
| + : animation_host_(), |
| + animation_timeline_(), |
| + layer_animation_delegate_(), |
| + id_(id), |
| + layer_id_(0) { |
| + DCHECK(id_); |
| +} |
| + |
| +AnimationPlayer::~AnimationPlayer() { |
| + DCHECK(!animation_timeline_); |
| + DCHECK(!layer_animation_controller_); |
| + DCHECK(!layer_id_); |
| +} |
| + |
| +scoped_refptr<AnimationPlayer> AnimationPlayer::CreateImplInstance() const { |
| + scoped_refptr<AnimationPlayer> to_return = AnimationPlayer::Create(id()); |
| + return to_return; |
| +} |
| + |
| +void AnimationPlayer::SetAnimationHost(AnimationHost* animation_host) { |
| + animation_host_ = animation_host; |
| +} |
| + |
| +void AnimationPlayer::SetAnimationTimeline(AnimationTimeline* timeline) { |
| + if (animation_timeline_ == timeline) |
| + return; |
| + |
| + if (layer_id_ && animation_timeline_) |
| + RemoveControllerFromTimeline(); |
|
Ian Vollick
2015/05/05 03:52:06
Can you add a comment explaining why you need to r
loyso (OOO)
2015/05/05 06:51:18
Acknowledged.
loyso (OOO)
2015/06/22 07:48:51
Done.
|
| + |
| + animation_timeline_ = timeline; |
| + |
| + if (layer_id_ && animation_timeline_) |
| + AddControllerToTimeline(); |
| +} |
| + |
| +void AnimationPlayer::set_layer_animation_delegate( |
| + AnimationDelegate* delegate) { |
| + layer_animation_delegate_ = delegate; |
| + if (layer_animation_controller_) |
| + layer_animation_controller_->set_layer_animation_delegate(delegate); |
| +} |
| + |
| +void AnimationPlayer::AttachLayer(int layer_id) { |
| + DCHECK_EQ(layer_id_, 0); |
| + DCHECK_NE(layer_id, 0); |
| + DCHECK(!layer_animation_controller_); |
| + |
| + layer_id_ = layer_id; |
| + |
| + if (animation_timeline_) |
| + AddControllerToTimeline(); |
| +} |
| + |
| +void AnimationPlayer::DetachLayer() { |
| + DCHECK_NE(layer_id_, 0); |
| + |
| + if (animation_timeline_) |
| + RemoveControllerFromTimeline(); |
| + |
| + layer_animation_controller_ = nullptr; |
| + layer_id_ = 0; |
| +} |
| + |
| +void AnimationPlayer::AddControllerToTimeline() { |
| + DCHECK(layer_id_); |
| + DCHECK(animation_host_); |
| + |
| + AnimationRegistrar* registrar = animation_host_->animation_registrar(); |
| + DCHECK(registrar); |
| + |
| + layer_animation_controller_ = |
| + registrar->GetAnimationControllerForId(layer_id_); |
| + layer_animation_controller_->SetAnimationRegistrar(registrar); |
| + |
| + DCHECK(animation_host_->layer_tree_mutators_client()); |
| + if (animation_host_->layer_tree_mutators_client()->IsLayerInActiveTree( |
| + layer_id_)) |
| + CreateActiveValueObserver(); |
| + if (animation_host_->layer_tree_mutators_client()->IsLayerInPendingTree( |
| + layer_id_)) |
| + CreatePendingValueObserver(); |
| + |
| + animation_host_->RegisterPlayerForLayer(layer_id_, this); |
| +} |
| + |
| +void AnimationPlayer::RemoveControllerFromTimeline() { |
| + DCHECK(layer_id_); |
| + DCHECK(animation_host_); |
| + animation_host_->UnregisterPlayerForLayer(layer_id_, this); |
| + |
| + DestroyPendingValueObserver(); |
| + DestroyActiveValueObserver(); |
| + if (layer_animation_controller_) |
| + layer_animation_controller_->SetAnimationRegistrar(nullptr); |
| + layer_animation_controller_ = nullptr; |
| +} |
| + |
| +void AnimationPlayer::LayerRegistered(int layer_id, bool is_active_tree) { |
| + DCHECK_EQ(layer_id_, layer_id); |
| + if (is_active_tree && layer_animation_controller_) { |
| + if (!active_value_observer_) |
| + CreateActiveValueObserver(); |
| + } else { |
| + if (!pending_value_observer_) |
| + CreatePendingValueObserver(); |
| + } |
| +} |
| + |
| +void AnimationPlayer::LayerUnregistered(int layer_id, bool is_active_tree) { |
| + DCHECK_EQ(layer_id_, layer_id); |
| + is_active_tree ? DestroyActiveValueObserver() : DestroyPendingValueObserver(); |
| +} |
| + |
| +void AnimationPlayer::AddAnimation(scoped_ptr<Animation> animation) { |
| + DCHECK(layer_animation_controller_); |
| + layer_animation_controller_->AddAnimation(animation.Pass()); |
| + SetNeedsCommit(); |
| +} |
| + |
| +void AnimationPlayer::PauseAnimation(int animation_id, double time_offset) { |
| + DCHECK(layer_animation_controller_); |
| + layer_animation_controller_->PauseAnimation( |
| + animation_id, base::TimeDelta::FromSecondsD(time_offset)); |
| + SetNeedsCommit(); |
| +} |
| + |
| +void AnimationPlayer::RemoveAnimation(int animation_id) { |
| + if (layer_animation_controller_) { |
| + layer_animation_controller_->RemoveAnimation(animation_id); |
| + SetNeedsCommit(); |
| + } |
| +} |
| + |
| +void AnimationPlayer::PushPropertiesTo(AnimationPlayer* player_impl) { |
| + if (!layer_animation_controller()) { |
| + if (player_impl->layer_animation_controller()) |
| + player_impl->DetachLayer(); |
| + return; |
| + } |
| + |
| + DCHECK_NE(layer_id_, 0); |
| + if (!player_impl->layer_animation_controller()) |
| + player_impl->AttachLayer(layer_id_); |
| + |
| + DCHECK(player_impl->layer_animation_controller()); |
| + layer_animation_controller_->PushAnimationUpdatesTo( |
| + player_impl->layer_animation_controller()); |
| +} |
| + |
| +void AnimationPlayer::SetNeedsCommit() { |
| + DCHECK(animation_host_); |
| + animation_host_->SetNeedsCommit(); |
| +} |
| + |
| +void AnimationPlayer::SetFilterMutated(bool active_tree, |
| + const FilterOperations& filters) { |
| + DCHECK(layer_id_); |
| + if (animation_host()) { |
| + DCHECK(animation_host()->layer_tree_mutators_client()); |
| + animation_host()->layer_tree_mutators_client()->SetLayerFilterMutated( |
| + layer_id_, active_tree, filters); |
| + } |
| +} |
| + |
| +void AnimationPlayer::SetOpacityMutated(bool active_tree, float opacity) { |
| + DCHECK(layer_id_); |
| + if (animation_host()) { |
| + DCHECK(animation_host()->layer_tree_mutators_client()); |
| + animation_host()->layer_tree_mutators_client()->SetLayerOpacityMutated( |
| + layer_id_, active_tree, opacity); |
| + } |
| +} |
| + |
| +void AnimationPlayer::SetTransformMutated(bool active_tree, |
| + const gfx::Transform& transform) { |
| + DCHECK(layer_id_); |
| + if (animation_host()) { |
| + DCHECK(animation_host()->layer_tree_mutators_client()); |
| + animation_host()->layer_tree_mutators_client()->SetLayerTransformMutated( |
|
Ian Vollick
2015/05/05 03:52:06
If I understand correctly, this will cause us to f
loyso (OOO)
2015/05/05 06:51:18
Yes, that's a hash_map look up. We discussed that
Ian Vollick
2015/05/07 13:58:42
I think you're right that we won't have that many
loyso (OOO)
2015/05/08 01:04:34
May I set this as a separate perf and optimization
Ian Vollick
2015/05/08 14:58:22
Since these results could affect the design of thi
loyso (OOO)
2015/06/22 07:48:51
Done. https://codereview.chromium.org/1172583003/
|
| + layer_id_, active_tree, transform); |
| + } |
| +} |
| + |
| +void AnimationPlayer::SetScrollOffsetMutated( |
| + bool active_tree, |
| + const gfx::ScrollOffset& scroll_offset) { |
| + DCHECK(layer_id_); |
| + if (animation_host()) { |
| + DCHECK(animation_host()->layer_tree_mutators_client()); |
| + animation_host()->layer_tree_mutators_client()->SetLayerScrollOffsetMutated( |
| + layer_id_, active_tree, scroll_offset); |
| + } |
| +} |
| + |
| +void AnimationPlayer::CreateActiveValueObserver() { |
| + DCHECK(layer_animation_controller_); |
| + DCHECK(!active_value_observer_); |
| + active_value_observer_ = make_scoped_ptr(new ValueObserver(this, true)); |
| + layer_animation_controller_->AddValueObserver(active_value_observer_.get()); |
| + |
| + layer_animation_controller_->set_value_provider(this); |
| + layer_animation_controller_->set_layer_animation_delegate( |
| + layer_animation_delegate_); |
| +} |
| + |
| +void AnimationPlayer::DestroyActiveValueObserver() { |
| + if (layer_animation_controller_ && active_value_observer_) |
| + layer_animation_controller_->RemoveValueObserver( |
| + active_value_observer_.get()); |
| + active_value_observer_ = nullptr; |
| + |
| + if (layer_animation_controller_) { |
| + layer_animation_controller_->remove_value_provider(this); |
| + layer_animation_controller_->remove_layer_animation_delegate( |
| + layer_animation_delegate_); |
| + } |
| +} |
| + |
| +void AnimationPlayer::CreatePendingValueObserver() { |
| + DCHECK(layer_animation_controller_); |
| + DCHECK(!pending_value_observer_); |
| + pending_value_observer_ = make_scoped_ptr(new ValueObserver(this, false)); |
| + layer_animation_controller_->AddValueObserver(pending_value_observer_.get()); |
| +} |
| + |
| +void AnimationPlayer::DestroyPendingValueObserver() { |
| + if (layer_animation_controller_ && pending_value_observer_) |
| + layer_animation_controller_->RemoveValueObserver( |
| + pending_value_observer_.get()); |
| + pending_value_observer_ = nullptr; |
| +} |
| + |
| +gfx::ScrollOffset AnimationPlayer::ScrollOffsetForAnimation() const { |
| + // TODO(loyso): implement it. |
| + return gfx::ScrollOffset(); |
| +} |
| + |
| +} // namespace cc |