Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(405)

Side by Side Diff: cc/animation/element_animations.cc

Issue 2538973002: CC Animation: Make AnimationPlayer to be a unit of activation. (Closed)
Patch Set: Move ScrollOffsetAnimationWasInterrupted to AnimationPlayer Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/animation/element_animations.h" 5 #include "cc/animation/element_animations.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 10
(...skipping 10 matching lines...) Expand all
21 21
22 namespace cc { 22 namespace cc {
23 23
24 scoped_refptr<ElementAnimations> ElementAnimations::Create() { 24 scoped_refptr<ElementAnimations> ElementAnimations::Create() {
25 return make_scoped_refptr(new ElementAnimations()); 25 return make_scoped_refptr(new ElementAnimations());
26 } 26 }
27 27
28 ElementAnimations::ElementAnimations() 28 ElementAnimations::ElementAnimations()
29 : animation_host_(), 29 : animation_host_(),
30 element_id_(), 30 element_id_(),
31 is_active_(false),
32 has_element_in_active_list_(false), 31 has_element_in_active_list_(false),
33 has_element_in_pending_list_(false), 32 has_element_in_pending_list_(false),
34 scroll_offset_animation_was_interrupted_(false),
35 needs_push_properties_(false), 33 needs_push_properties_(false),
36 needs_update_impl_client_state_(false) {} 34 needs_update_impl_client_state_(false) {}
37 35
38 ElementAnimations::~ElementAnimations() {} 36 ElementAnimations::~ElementAnimations() {}
39 37
40 void ElementAnimations::SetAnimationHost(AnimationHost* host) { 38 void ElementAnimations::SetAnimationHost(AnimationHost* host) {
41 animation_host_ = host; 39 animation_host_ = host;
42 } 40 }
43 41
44 void ElementAnimations::SetElementId(ElementId element_id) { 42 void ElementAnimations::SetElementId(ElementId element_id) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 } 83 }
86 set_has_element_in_active_list(false); 84 set_has_element_in_active_list(false);
87 85
88 if (has_element_in_pending_list()) { 86 if (has_element_in_pending_list()) {
89 animation_host()->mutator_host_client()->ElementIsAnimatingChanged( 87 animation_host()->mutator_host_client()->ElementIsAnimatingChanged(
90 element_id(), ElementListType::PENDING, disabled_state_mask, 88 element_id(), ElementListType::PENDING, disabled_state_mask,
91 disabled_state); 89 disabled_state);
92 } 90 }
93 set_has_element_in_pending_list(false); 91 set_has_element_in_pending_list(false);
94 92
95 animation_host_->DidDeactivateElementAnimations(this); 93 Deactivate();
96 UpdateActivation(ActivationType::FORCE);
97 } 94 }
98 95
99 void ElementAnimations::ElementRegistered(ElementId element_id, 96 void ElementAnimations::ElementRegistered(ElementId element_id,
100 ElementListType list_type) { 97 ElementListType list_type) {
101 DCHECK_EQ(element_id_, element_id); 98 DCHECK_EQ(element_id_, element_id);
102 99
103 if (!has_element_in_any_list()) 100 if (!has_element_in_any_list())
104 UpdateActivation(ActivationType::FORCE); 101 UpdateActivation(ActivationType::FORCE);
105 102
106 if (list_type == ElementListType::ACTIVE) 103 if (list_type == ElementListType::ACTIVE)
107 set_has_element_in_active_list(true); 104 set_has_element_in_active_list(true);
108 else 105 else
109 set_has_element_in_pending_list(true); 106 set_has_element_in_pending_list(true);
110 } 107 }
111 108
112 void ElementAnimations::ElementUnregistered(ElementId element_id, 109 void ElementAnimations::ElementUnregistered(ElementId element_id,
113 ElementListType list_type) { 110 ElementListType list_type) {
114 DCHECK_EQ(this->element_id(), element_id); 111 DCHECK_EQ(this->element_id(), element_id);
115 if (list_type == ElementListType::ACTIVE) 112 if (list_type == ElementListType::ACTIVE)
116 set_has_element_in_active_list(false); 113 set_has_element_in_active_list(false);
117 else 114 else
118 set_has_element_in_pending_list(false); 115 set_has_element_in_pending_list(false);
119 116
120 if (!has_element_in_any_list()) 117 if (!has_element_in_any_list())
121 animation_host_->DidDeactivateElementAnimations(this); 118 Deactivate();
122 } 119 }
123 120
124 void ElementAnimations::AddPlayer(AnimationPlayer* player) { 121 void ElementAnimations::AddPlayer(AnimationPlayer* player) {
125 players_list_.AddObserver(player); 122 players_list_.AddObserver(player);
126 } 123 }
127 124
128 void ElementAnimations::RemovePlayer(AnimationPlayer* player) { 125 void ElementAnimations::RemovePlayer(AnimationPlayer* player) {
129 players_list_.RemoveObserver(player); 126 players_list_.RemoveObserver(player);
130 } 127 }
131 128
132 bool ElementAnimations::IsEmpty() const { 129 bool ElementAnimations::IsEmpty() const {
133 return !players_list_.might_have_observers(); 130 return !players_list_.might_have_observers();
134 } 131 }
135 132
136 void ElementAnimations::SetNeedsPushProperties() { 133 void ElementAnimations::SetNeedsPushProperties() {
137 needs_push_properties_ = true; 134 needs_push_properties_ = true;
138 } 135 }
139 136
140 void ElementAnimations::PushPropertiesTo( 137 void ElementAnimations::PushPropertiesTo(
141 scoped_refptr<ElementAnimations> element_animations_impl) const { 138 scoped_refptr<ElementAnimations> element_animations_impl) const {
142 DCHECK_NE(this, element_animations_impl); 139 DCHECK_NE(this, element_animations_impl);
143 140
144 if (!needs_push_properties_) 141 if (!needs_push_properties_)
145 return; 142 return;
146 needs_push_properties_ = false; 143 needs_push_properties_ = false;
147 144
148 element_animations_impl->scroll_offset_animation_was_interrupted_ =
149 scroll_offset_animation_was_interrupted_;
150 scroll_offset_animation_was_interrupted_ = false;
151
152 // Update impl client state. 145 // Update impl client state.
153 if (needs_update_impl_client_state_) 146 if (needs_update_impl_client_state_)
154 element_animations_impl->UpdateClientAnimationState(); 147 element_animations_impl->UpdateClientAnimationState();
155 needs_update_impl_client_state_ = false; 148 needs_update_impl_client_state_ = false;
156
157 element_animations_impl->UpdateActivation(ActivationType::NORMAL);
158 } 149 }
159 150
160 void ElementAnimations::Animate(base::TimeTicks monotonic_time) { 151 void ElementAnimations::UpdateActivation(ActivationType activation_type) const {
161 DCHECK(!monotonic_time.is_null());
162 if (!has_element_in_active_list() && !has_element_in_pending_list())
163 return;
164
165 for (auto& player : players_list_) {
166 if (player.needs_to_start_animations())
167 player.StartAnimations(monotonic_time);
168 }
169
170 for (auto& player : players_list_) 152 for (auto& player : players_list_)
171 player.TickAnimations(monotonic_time); 153 player.UpdateActivation(activation_type);
172
173 last_tick_time_ = monotonic_time;
174 UpdateClientAnimationState();
175 } 154 }
176 155
177 void ElementAnimations::UpdateState(bool start_ready_animations, 156 void ElementAnimations::Deactivate() const {
178 AnimationEvents* events) {
179 if (!has_element_in_active_list())
180 return;
181
182 // Animate hasn't been called, this happens if an element has been added
183 // between the Commit and Draw phases.
184 if (last_tick_time_ == base::TimeTicks())
185 return;
186
187 if (start_ready_animations) {
188 for (auto& player : players_list_)
189 player.PromoteStartedAnimations(last_tick_time_, events);
190 }
191
192 for (auto& player : players_list_) 157 for (auto& player : players_list_)
193 player.MarkFinishedAnimations(last_tick_time_); 158 player.Deactivate();
194
195 for (auto& player : players_list_)
196 player.MarkAnimationsForDeletion(last_tick_time_, events);
197
198 if (start_ready_animations) {
199 for (auto& player : players_list_) {
200 if (player.needs_to_start_animations()) {
201 player.StartAnimations(last_tick_time_);
202 player.PromoteStartedAnimations(last_tick_time_, events);
203 }
204 }
205 }
206
207 UpdateActivation(ActivationType::NORMAL);
208 }
209
210 void ElementAnimations::ActivateAnimations() {
211 for (auto& player : players_list_)
212 player.ActivateAnimations();
213
214 scroll_offset_animation_was_interrupted_ = false;
215 UpdateActivation(ActivationType::NORMAL);
216 } 159 }
217 160
218 void ElementAnimations::NotifyAnimationStarted(const AnimationEvent& event) { 161 void ElementAnimations::NotifyAnimationStarted(const AnimationEvent& event) {
219 DCHECK(!event.is_impl_only); 162 DCHECK(!event.is_impl_only);
220 for (auto& player : players_list_) { 163 for (auto& player : players_list_) {
221 if (player.NotifyAnimationStarted(event)) 164 if (player.NotifyAnimationStarted(event))
222 break; 165 break;
223 } 166 }
224 } 167 }
225 168
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 bool success = player.MaximumTargetScale(list_type, &player_max_scale); 291 bool success = player.MaximumTargetScale(list_type, &player_max_scale);
349 if (!success) 292 if (!success)
350 return false; 293 return false;
351 // Union: a maximum. 294 // Union: a maximum.
352 *max_scale = std::max(*max_scale, player_max_scale); 295 *max_scale = std::max(*max_scale, player_max_scale);
353 } 296 }
354 297
355 return true; 298 return true;
356 } 299 }
357 300
301 bool ElementAnimations::ScrollOffsetAnimationWasInterrupted() const {
302 for (auto& player : players_list_) {
303 if (player.scroll_offset_animation_was_interrupted())
304 return true;
305 }
306 return false;
307 }
308
358 void ElementAnimations::SetNeedsUpdateImplClientState() { 309 void ElementAnimations::SetNeedsUpdateImplClientState() {
359 needs_update_impl_client_state_ = true; 310 needs_update_impl_client_state_ = true;
360 SetNeedsPushProperties(); 311 SetNeedsPushProperties();
361 } 312 }
362 313
363 void ElementAnimations::UpdateActivation(ActivationType type) {
364 bool force = type == ActivationType::FORCE;
365 if (animation_host_) {
366 bool was_active = is_active_;
367 is_active_ = false;
368
369 for (auto& player : players_list_) {
370 if (player.HasNonDeletedAnimation()) {
371 is_active_ = true;
372 break;
373 }
374 }
375
376 if (is_active_ && ((!was_active && has_element_in_any_list()) || force)) {
377 animation_host_->DidActivateElementAnimations(this);
378 } else if (!is_active_ && (was_active || force)) {
379 // Resetting last_tick_time_ here ensures that calling ::UpdateState
380 // before ::Animate doesn't start an animation.
381 last_tick_time_ = base::TimeTicks();
382 animation_host_->DidDeactivateElementAnimations(this);
383 }
384 }
385 }
386
387 void ElementAnimations::UpdateActivationNormal() {
388 UpdateActivation(ActivationType::NORMAL);
389 }
390
391 void ElementAnimations::NotifyClientOpacityAnimated( 314 void ElementAnimations::NotifyClientOpacityAnimated(
392 float opacity, 315 float opacity,
393 bool notify_active_elements, 316 bool notify_active_elements,
394 bool notify_pending_elements) { 317 bool notify_pending_elements) {
395 if (notify_active_elements && has_element_in_active_list()) 318 if (notify_active_elements && has_element_in_active_list())
396 OnOpacityAnimated(ElementListType::ACTIVE, opacity); 319 OnOpacityAnimated(ElementListType::ACTIVE, opacity);
397 if (notify_pending_elements && has_element_in_pending_list()) 320 if (notify_pending_elements && has_element_in_pending_list())
398 OnOpacityAnimated(ElementListType::PENDING, opacity); 321 OnOpacityAnimated(ElementListType::PENDING, opacity);
399 } 322 }
400 323
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 TargetProperty::Type target_property, 437 TargetProperty::Type target_property,
515 ElementListType list_type) const { 438 ElementListType list_type) const {
516 for (auto& player : players_list_) { 439 for (auto& player : players_list_) {
517 if (player.IsCurrentlyAnimatingProperty(target_property, list_type)) 440 if (player.IsCurrentlyAnimatingProperty(target_property, list_type))
518 return true; 441 return true;
519 } 442 }
520 443
521 return false; 444 return false;
522 } 445 }
523 446
524 void ElementAnimations::SetScrollOffsetAnimationWasInterrupted() {
525 scroll_offset_animation_was_interrupted_ = true;
526 }
527
528 void ElementAnimations::OnFilterAnimated(ElementListType list_type, 447 void ElementAnimations::OnFilterAnimated(ElementListType list_type,
529 const FilterOperations& filters) { 448 const FilterOperations& filters) {
530 DCHECK(element_id()); 449 DCHECK(element_id());
531 DCHECK(animation_host()); 450 DCHECK(animation_host());
532 DCHECK(animation_host()->mutator_host_client()); 451 DCHECK(animation_host()->mutator_host_client());
533 animation_host()->mutator_host_client()->SetElementFilterMutated( 452 animation_host()->mutator_host_client()->SetElementFilterMutated(
534 element_id(), list_type, filters); 453 element_id(), list_type, filters);
535 } 454 }
536 455
537 void ElementAnimations::OnOpacityAnimated(ElementListType list_type, 456 void ElementAnimations::OnOpacityAnimated(ElementListType list_type,
(...skipping 28 matching lines...) Expand all
566 if (animation_host()) { 485 if (animation_host()) {
567 DCHECK(animation_host()->mutator_host_client()); 486 DCHECK(animation_host()->mutator_host_client());
568 return animation_host()->mutator_host_client()->GetScrollOffsetForAnimation( 487 return animation_host()->mutator_host_client()->GetScrollOffsetForAnimation(
569 element_id()); 488 element_id());
570 } 489 }
571 490
572 return gfx::ScrollOffset(); 491 return gfx::ScrollOffset();
573 } 492 }
574 493
575 } // namespace cc 494 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698