1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/animation/element_animations.h"
7 #include "cc/animation/animation_host.h"
8 #include "cc/animation/animation_player.h"
9 #include "cc/animation/animation_registrar.h"
10 #include "cc/animation/layer_animation_value_observer.h"
11 #include "cc/trees/mutator_host_client.h"
15 class ElementAnimations::ValueObserver
: public LayerAnimationValueObserver
{
17 ValueObserver(ElementAnimations
* element_animation
, LayerTreeType tree_type
)
18 : element_animations_(element_animation
), tree_type_(tree_type
) {
19 DCHECK(element_animations_
);
22 // LayerAnimationValueObserver implementation.
23 void OnFilterAnimated(const FilterOperations
& filters
) override
{
24 element_animations_
->SetFilterMutated(tree_type_
, filters
);
27 void OnOpacityAnimated(float opacity
) override
{
28 element_animations_
->SetOpacityMutated(tree_type_
, opacity
);
31 void OnTransformAnimated(const gfx::Transform
& transform
) override
{
32 element_animations_
->SetTransformMutated(tree_type_
, transform
);
35 void OnScrollOffsetAnimated(const gfx::ScrollOffset
& scroll_offset
) override
{
36 element_animations_
->SetScrollOffsetMutated(tree_type_
, scroll_offset
);
39 void OnAnimationWaitingForDeletion() override
{
40 // TODO(loyso): See Layer::OnAnimationWaitingForDeletion. But we always do
41 // PushProperties for AnimationTimelines for now.
44 void OnTransformIsPotentiallyAnimatingChanged(bool is_animating
) override
{
45 element_animations_
->SetTransformIsPotentiallyAnimatingChanged(
46 tree_type_
, is_animating
);
49 bool IsActive() const override
{ return tree_type_
== LayerTreeType::ACTIVE
; }
52 ElementAnimations
* element_animations_
;
53 const LayerTreeType tree_type_
;
55 DISALLOW_COPY_AND_ASSIGN(ValueObserver
);
58 scoped_ptr
<ElementAnimations
> ElementAnimations::Create(AnimationHost
* host
) {
59 return make_scoped_ptr(new ElementAnimations(host
));
62 ElementAnimations::ElementAnimations(AnimationHost
* host
)
63 : players_list_(make_scoped_ptr(new PlayersList())), animation_host_(host
) {
64 DCHECK(animation_host_
);
67 ElementAnimations::~ElementAnimations() {
68 DCHECK(!layer_animation_controller_
);
71 void ElementAnimations::CreateLayerAnimationController(int layer_id
) {
73 DCHECK(!layer_animation_controller_
);
74 DCHECK(animation_host_
);
76 AnimationRegistrar
* registrar
= animation_host_
->animation_registrar();
79 layer_animation_controller_
=
80 registrar
->GetAnimationControllerForId(layer_id
);
81 layer_animation_controller_
->SetAnimationRegistrar(registrar
);
82 layer_animation_controller_
->set_layer_animation_delegate(this);
83 layer_animation_controller_
->set_value_provider(this);
85 DCHECK(animation_host_
->mutator_host_client());
86 if (animation_host_
->mutator_host_client()->IsLayerInTree(
87 layer_id
, LayerTreeType::ACTIVE
))
88 CreateActiveValueObserver();
89 if (animation_host_
->mutator_host_client()->IsLayerInTree(
90 layer_id
, LayerTreeType::PENDING
))
91 CreatePendingValueObserver();
94 void ElementAnimations::DestroyLayerAnimationController() {
95 DCHECK(animation_host_
);
97 DestroyPendingValueObserver();
98 DestroyActiveValueObserver();
100 if (layer_animation_controller_
) {
101 layer_animation_controller_
->remove_value_provider(this);
102 layer_animation_controller_
->remove_layer_animation_delegate(this);
103 layer_animation_controller_
->SetAnimationRegistrar(nullptr);
104 layer_animation_controller_
= nullptr;
108 void ElementAnimations::LayerRegistered(int layer_id
, LayerTreeType tree_type
) {
109 DCHECK(layer_animation_controller_
);
110 DCHECK_EQ(layer_animation_controller_
->id(), layer_id
);
112 if (tree_type
== LayerTreeType::ACTIVE
) {
113 if (!active_value_observer_
)
114 CreateActiveValueObserver();
116 if (!pending_value_observer_
)
117 CreatePendingValueObserver();
121 void ElementAnimations::LayerUnregistered(int layer_id
,
122 LayerTreeType tree_type
) {
123 DCHECK_EQ(this->layer_id(), layer_id
);
124 tree_type
== LayerTreeType::ACTIVE
? DestroyActiveValueObserver()
125 : DestroyPendingValueObserver();
128 void ElementAnimations::AddPlayer(AnimationPlayer
* player
) {
129 players_list_
->Append(player
);
132 void ElementAnimations::RemovePlayer(AnimationPlayer
* player
) {
133 for (PlayersListNode
* node
= players_list_
->head();
134 node
!= players_list_
->end(); node
= node
->next()) {
135 if (node
->value() == player
) {
136 node
->RemoveFromList();
142 bool ElementAnimations::IsEmpty() const {
143 return players_list_
->empty();
146 void ElementAnimations::PushPropertiesTo(
147 ElementAnimations
* element_animations_impl
) {
148 DCHECK(layer_animation_controller_
);
149 DCHECK(element_animations_impl
->layer_animation_controller());
151 layer_animation_controller_
->PushAnimationUpdatesTo(
152 element_animations_impl
->layer_animation_controller());
155 void ElementAnimations::SetFilterMutated(LayerTreeType tree_type
,
156 const FilterOperations
& filters
) {
158 DCHECK(animation_host());
159 DCHECK(animation_host()->mutator_host_client());
160 animation_host()->mutator_host_client()->SetLayerFilterMutated(
161 layer_id(), tree_type
, filters
);
164 void ElementAnimations::SetOpacityMutated(LayerTreeType tree_type
,
167 DCHECK(animation_host());
168 DCHECK(animation_host()->mutator_host_client());
169 animation_host()->mutator_host_client()->SetLayerOpacityMutated(
170 layer_id(), tree_type
, opacity
);
173 void ElementAnimations::SetTransformMutated(LayerTreeType tree_type
,
174 const gfx::Transform
& transform
) {
176 DCHECK(animation_host());
177 DCHECK(animation_host()->mutator_host_client());
178 animation_host()->mutator_host_client()->SetLayerTransformMutated(
179 layer_id(), tree_type
, transform
);
182 void ElementAnimations::SetScrollOffsetMutated(
183 LayerTreeType tree_type
,
184 const gfx::ScrollOffset
& scroll_offset
) {
186 DCHECK(animation_host());
187 DCHECK(animation_host()->mutator_host_client());
188 animation_host()->mutator_host_client()->SetLayerScrollOffsetMutated(
189 layer_id(), tree_type
, scroll_offset
);
192 void ElementAnimations::SetTransformIsPotentiallyAnimatingChanged(
193 LayerTreeType tree_type
,
196 DCHECK(animation_host());
197 DCHECK(animation_host()->mutator_host_client());
199 ->mutator_host_client()
200 ->LayerTransformIsPotentiallyAnimatingChanged(layer_id(), tree_type
,
204 void ElementAnimations::CreateActiveValueObserver() {
205 DCHECK(layer_animation_controller_
);
206 DCHECK(!active_value_observer_
);
207 active_value_observer_
=
208 make_scoped_ptr(new ValueObserver(this, LayerTreeType::ACTIVE
));
209 layer_animation_controller_
->AddValueObserver(active_value_observer_
.get());
212 void ElementAnimations::DestroyActiveValueObserver() {
213 if (layer_animation_controller_
&& active_value_observer_
)
214 layer_animation_controller_
->RemoveValueObserver(
215 active_value_observer_
.get());
216 active_value_observer_
= nullptr;
219 void ElementAnimations::CreatePendingValueObserver() {
220 DCHECK(layer_animation_controller_
);
221 DCHECK(!pending_value_observer_
);
222 pending_value_observer_
=
223 make_scoped_ptr(new ValueObserver(this, LayerTreeType::PENDING
));
224 layer_animation_controller_
->AddValueObserver(pending_value_observer_
.get());
227 void ElementAnimations::DestroyPendingValueObserver() {
228 if (layer_animation_controller_
&& pending_value_observer_
)
229 layer_animation_controller_
->RemoveValueObserver(
230 pending_value_observer_
.get());
231 pending_value_observer_
= nullptr;
234 void ElementAnimations::NotifyAnimationStarted(
235 base::TimeTicks monotonic_time
,
236 Animation::TargetProperty target_property
,
238 for (PlayersListNode
* node
= players_list_
->head();
239 node
!= players_list_
->end(); node
= node
->next()) {
240 AnimationPlayer
* player
= node
->value();
241 player
->NotifyAnimationStarted(monotonic_time
, target_property
, group
);
245 void ElementAnimations::NotifyAnimationFinished(
246 base::TimeTicks monotonic_time
,
247 Animation::TargetProperty target_property
,
249 for (PlayersListNode
* node
= players_list_
->head();
250 node
!= players_list_
->end(); node
= node
->next()) {
251 AnimationPlayer
* player
= node
->value();
252 player
->NotifyAnimationFinished(monotonic_time
, target_property
, group
);
256 gfx::ScrollOffset
ElementAnimations::ScrollOffsetForAnimation() const {
257 DCHECK(layer_animation_controller_
);
258 if (animation_host()) {
259 DCHECK(animation_host()->mutator_host_client());
260 return animation_host()->mutator_host_client()->GetScrollOffsetForAnimation(
264 return gfx::ScrollOffset();