OLD | NEW |
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/animation_player.h" | 5 #include "cc/animation/animation_player.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "cc/animation/animation_delegate.h" | 9 #include "cc/animation/animation_delegate.h" |
10 #include "cc/animation/animation_events.h" | 10 #include "cc/animation/animation_events.h" |
11 #include "cc/animation/animation_host.h" | 11 #include "cc/animation/animation_host.h" |
12 #include "cc/animation/animation_timeline.h" | 12 #include "cc/animation/animation_timeline.h" |
13 #include "cc/animation/scroll_offset_animation_curve.h" | 13 #include "cc/animation/scroll_offset_animation_curve.h" |
14 #include "cc/trees/property_animation_state.h" | 14 #include "cc/trees/property_animation_state.h" |
15 | 15 |
16 namespace cc { | 16 namespace cc { |
17 | 17 |
18 scoped_refptr<AnimationPlayer> AnimationPlayer::Create(int id) { | 18 scoped_refptr<AnimationPlayer> AnimationPlayer::Create(int id) { |
19 return make_scoped_refptr(new AnimationPlayer(id)); | 19 return make_scoped_refptr(new AnimationPlayer(id)); |
20 } | 20 } |
21 | 21 |
22 AnimationPlayer::AnimationPlayer(int id) | 22 AnimationPlayer::AnimationPlayer(int id) |
23 : animation_host_(), | 23 : animation_host_(), |
24 animation_timeline_(), | 24 animation_timeline_(), |
25 element_animations_(), | 25 element_animations_(), |
26 animation_delegate_(), | 26 animation_delegate_(), |
27 id_(id), | 27 id_(id), |
28 needs_push_properties_(false), | 28 needs_push_properties_(false), |
29 needs_to_start_animations_(false) { | 29 needs_to_start_animations_(false), |
| 30 is_active_(false), |
| 31 scroll_offset_animation_was_interrupted_(false) { |
30 DCHECK(id_); | 32 DCHECK(id_); |
31 } | 33 } |
32 | 34 |
33 AnimationPlayer::~AnimationPlayer() { | 35 AnimationPlayer::~AnimationPlayer() { |
34 DCHECK(!animation_timeline_); | 36 DCHECK(!animation_timeline_); |
35 DCHECK(!element_animations_); | 37 DCHECK(!element_animations_); |
36 } | 38 } |
37 | 39 |
38 scoped_refptr<AnimationPlayer> AnimationPlayer::CreateImplInstance() const { | 40 scoped_refptr<AnimationPlayer> AnimationPlayer::CreateImplInstance() const { |
39 scoped_refptr<AnimationPlayer> player = AnimationPlayer::Create(id()); | 41 scoped_refptr<AnimationPlayer> player = AnimationPlayer::Create(id()); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 SetNeedsPushProperties(); | 132 SetNeedsPushProperties(); |
131 } | 133 } |
132 } | 134 } |
133 | 135 |
134 void AnimationPlayer::AnimationAdded() { | 136 void AnimationPlayer::AnimationAdded() { |
135 DCHECK(element_animations_); | 137 DCHECK(element_animations_); |
136 | 138 |
137 SetNeedsCommit(); | 139 SetNeedsCommit(); |
138 needs_to_start_animations_ = true; | 140 needs_to_start_animations_ = true; |
139 | 141 |
140 element_animations_->UpdateActivationNormal(); | 142 UpdateActivation(ActivationType::NORMAL); |
141 element_animations_->UpdateClientAnimationState(); | 143 element_animations_->UpdateClientAnimationState(); |
142 } | 144 } |
143 | 145 |
144 void AnimationPlayer::PauseAnimation(int animation_id, double time_offset) { | 146 void AnimationPlayer::PauseAnimation(int animation_id, double time_offset) { |
145 const base::TimeDelta time_delta = base::TimeDelta::FromSecondsD(time_offset); | 147 const base::TimeDelta time_delta = base::TimeDelta::FromSecondsD(time_offset); |
146 | 148 |
147 for (size_t i = 0; i < animations_.size(); ++i) { | 149 for (size_t i = 0; i < animations_.size(); ++i) { |
148 if (animations_[i]->id() == animation_id) { | 150 if (animations_[i]->id() == animation_id) { |
149 animations_[i]->SetRunState(Animation::PAUSED, | 151 animations_[i]->SetRunState(Animation::PAUSED, |
150 time_delta + animations_[i]->start_time() + | 152 time_delta + animations_[i]->start_time() + |
(...skipping 14 matching lines...) Expand all Loading... |
165 // use a stable_parition here instead of remove_if. Remove_if leaves the | 167 // use a stable_parition here instead of remove_if. Remove_if leaves the |
166 // removed items in an unspecified state. | 168 // removed items in an unspecified state. |
167 auto animations_to_remove = std::stable_partition( | 169 auto animations_to_remove = std::stable_partition( |
168 animations_.begin(), animations_.end(), | 170 animations_.begin(), animations_.end(), |
169 [animation_id](const std::unique_ptr<Animation>& animation) { | 171 [animation_id](const std::unique_ptr<Animation>& animation) { |
170 return animation->id() != animation_id; | 172 return animation->id() != animation_id; |
171 }); | 173 }); |
172 for (auto it = animations_to_remove; it != animations_.end(); ++it) { | 174 for (auto it = animations_to_remove; it != animations_.end(); ++it) { |
173 if ((*it)->target_property() == TargetProperty::SCROLL_OFFSET) { | 175 if ((*it)->target_property() == TargetProperty::SCROLL_OFFSET) { |
174 if (element_animations_) | 176 if (element_animations_) |
175 element_animations_->SetScrollOffsetAnimationWasInterrupted(); | 177 scroll_offset_animation_was_interrupted_ = true; |
176 } else if (!(*it)->is_finished()) { | 178 } else if (!(*it)->is_finished()) { |
177 animation_removed = true; | 179 animation_removed = true; |
178 } | 180 } |
179 } | 181 } |
180 | 182 |
181 animations_.erase(animations_to_remove, animations_.end()); | 183 animations_.erase(animations_to_remove, animations_.end()); |
182 | 184 |
183 if (element_animations_) { | 185 if (element_animations_) { |
184 element_animations_->UpdateActivationNormal(); | 186 UpdateActivation(ActivationType::NORMAL); |
185 if (animation_removed) | 187 if (animation_removed) |
186 element_animations_->UpdateClientAnimationState(); | 188 element_animations_->UpdateClientAnimationState(); |
187 SetNeedsCommit(); | 189 SetNeedsCommit(); |
188 SetNeedsPushProperties(); | 190 SetNeedsPushProperties(); |
189 } | 191 } |
190 } | 192 } |
191 | 193 |
192 void AnimationPlayer::AbortAnimation(int animation_id) { | 194 void AnimationPlayer::AbortAnimation(int animation_id) { |
193 if (Animation* animation = GetAnimationById(animation_id)) { | 195 if (Animation* animation = GetAnimationById(animation_id)) { |
194 if (!animation->is_finished()) { | 196 if (!animation->is_finished()) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 MarkAbortedAnimationsForDeletion(player_impl); | 254 MarkAbortedAnimationsForDeletion(player_impl); |
253 PurgeAnimationsMarkedForDeletion(); | 255 PurgeAnimationsMarkedForDeletion(); |
254 PushNewAnimationsToImplThread(player_impl); | 256 PushNewAnimationsToImplThread(player_impl); |
255 | 257 |
256 // Remove finished impl side animations only after pushing, | 258 // Remove finished impl side animations only after pushing, |
257 // and only after the animations are deleted on the main thread | 259 // and only after the animations are deleted on the main thread |
258 // this insures we will never push an animation twice. | 260 // this insures we will never push an animation twice. |
259 RemoveAnimationsCompletedOnMainThread(player_impl); | 261 RemoveAnimationsCompletedOnMainThread(player_impl); |
260 | 262 |
261 PushPropertiesToImplThread(player_impl); | 263 PushPropertiesToImplThread(player_impl); |
| 264 |
| 265 player_impl->UpdateActivation(ActivationType::NORMAL); |
| 266 } |
| 267 |
| 268 void AnimationPlayer::Animate(base::TimeTicks monotonic_time) { |
| 269 DCHECK(!monotonic_time.is_null()); |
| 270 DCHECK(element_animations_); |
| 271 |
| 272 if (!element_animations_->has_element_in_any_list()) |
| 273 return; |
| 274 |
| 275 if (needs_to_start_animations()) |
| 276 StartAnimations(monotonic_time); |
| 277 |
| 278 TickAnimations(monotonic_time); |
| 279 |
| 280 last_tick_time_ = monotonic_time; |
| 281 element_animations_->UpdateClientAnimationState(); |
| 282 } |
| 283 |
| 284 void AnimationPlayer::UpdateState(bool start_ready_animations, |
| 285 AnimationEvents* events) { |
| 286 DCHECK(element_animations_); |
| 287 if (!element_animations_->has_element_in_active_list()) |
| 288 return; |
| 289 |
| 290 // Animate hasn't been called, this happens if an element has been added |
| 291 // between the Commit and Draw phases. |
| 292 if (last_tick_time_ == base::TimeTicks()) |
| 293 return; |
| 294 |
| 295 if (start_ready_animations) |
| 296 PromoteStartedAnimations(last_tick_time_, events); |
| 297 |
| 298 MarkFinishedAnimations(last_tick_time_); |
| 299 MarkAnimationsForDeletion(last_tick_time_, events); |
| 300 |
| 301 if (start_ready_animations) { |
| 302 if (needs_to_start_animations()) { |
| 303 StartAnimations(last_tick_time_); |
| 304 PromoteStartedAnimations(last_tick_time_, events); |
| 305 } |
| 306 } |
| 307 |
| 308 UpdateActivation(ActivationType::NORMAL); |
| 309 } |
| 310 |
| 311 void AnimationPlayer::UpdateActivation(ActivationType type) { |
| 312 bool force = type == ActivationType::FORCE; |
| 313 if (animation_host_) { |
| 314 bool was_active = is_active_; |
| 315 is_active_ = HasNonDeletedAnimation(); |
| 316 |
| 317 bool has_element_in_any_list = |
| 318 element_animations_->has_element_in_any_list(); |
| 319 |
| 320 if (is_active_ && ((!was_active && has_element_in_any_list) || force)) { |
| 321 animation_host_->ActivateAnimationPlayer(this); |
| 322 } else if (!is_active_ && (was_active || force)) { |
| 323 Deactivate(); |
| 324 } |
| 325 } |
| 326 } |
| 327 |
| 328 void AnimationPlayer::Deactivate() { |
| 329 DCHECK(animation_host_); |
| 330 // Resetting last_tick_time_ here ensures that calling ::UpdateState |
| 331 // before ::Animate doesn't start an animation. |
| 332 last_tick_time_ = base::TimeTicks(); |
| 333 animation_host_->DeactivateAnimationPlayer(this); |
262 } | 334 } |
263 | 335 |
264 bool AnimationPlayer::NotifyAnimationStarted(const AnimationEvent& event) { | 336 bool AnimationPlayer::NotifyAnimationStarted(const AnimationEvent& event) { |
265 DCHECK(!event.is_impl_only); | 337 DCHECK(!event.is_impl_only); |
266 | 338 |
267 for (size_t i = 0; i < animations_.size(); ++i) { | 339 for (size_t i = 0; i < animations_.size(); ++i) { |
268 if (animations_[i]->group() == event.group_id && | 340 if (animations_[i]->group() == event.group_id && |
269 animations_[i]->target_property() == event.target_property && | 341 animations_[i]->target_property() == event.target_property && |
270 animations_[i]->needs_synchronized_start_time()) { | 342 animations_[i]->needs_synchronized_start_time()) { |
271 animations_[i]->set_needs_synchronized_start_time(false); | 343 animations_[i]->set_needs_synchronized_start_time(false); |
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
742 auto affects_no_elements = [](const std::unique_ptr<Animation>& animation) { | 814 auto affects_no_elements = [](const std::unique_ptr<Animation>& animation) { |
743 return !animation->affects_active_elements() && | 815 return !animation->affects_active_elements() && |
744 !animation->affects_pending_elements(); | 816 !animation->affects_pending_elements(); |
745 }; | 817 }; |
746 animations_.erase(std::remove_if(animations_.begin(), animations_.end(), | 818 animations_.erase(std::remove_if(animations_.begin(), animations_.end(), |
747 affects_no_elements), | 819 affects_no_elements), |
748 animations_.end()); | 820 animations_.end()); |
749 | 821 |
750 if (animation_activated) | 822 if (animation_activated) |
751 element_animations_->UpdateClientAnimationState(); | 823 element_animations_->UpdateClientAnimationState(); |
| 824 |
| 825 scroll_offset_animation_was_interrupted_ = false; |
| 826 UpdateActivation(ActivationType::NORMAL); |
752 } | 827 } |
753 | 828 |
754 bool AnimationPlayer::HasFilterAnimationThatInflatesBounds() const { | 829 bool AnimationPlayer::HasFilterAnimationThatInflatesBounds() const { |
755 for (size_t i = 0; i < animations_.size(); ++i) { | 830 for (size_t i = 0; i < animations_.size(); ++i) { |
756 if (!animations_[i]->is_finished() && | 831 if (!animations_[i]->is_finished() && |
757 animations_[i]->target_property() == TargetProperty::FILTER && | 832 animations_[i]->target_property() == TargetProperty::FILTER && |
758 animations_[i] | 833 animations_[i] |
759 ->curve() | 834 ->curve() |
760 ->ToFilterAnimationCurve() | 835 ->ToFilterAnimationCurve() |
761 ->HasFilterThatMovesPixels()) | 836 ->HasFilterThatMovesPixels()) |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1111 } | 1186 } |
1112 | 1187 |
1113 void AnimationPlayer::PushPropertiesToImplThread( | 1188 void AnimationPlayer::PushPropertiesToImplThread( |
1114 AnimationPlayer* animation_player_impl) { | 1189 AnimationPlayer* animation_player_impl) { |
1115 for (size_t i = 0; i < animations_.size(); ++i) { | 1190 for (size_t i = 0; i < animations_.size(); ++i) { |
1116 Animation* current_impl = | 1191 Animation* current_impl = |
1117 animation_player_impl->GetAnimationById(animations_[i]->id()); | 1192 animation_player_impl->GetAnimationById(animations_[i]->id()); |
1118 if (current_impl) | 1193 if (current_impl) |
1119 animations_[i]->PushPropertiesTo(current_impl); | 1194 animations_[i]->PushPropertiesTo(current_impl); |
1120 } | 1195 } |
| 1196 |
| 1197 animation_player_impl->scroll_offset_animation_was_interrupted_ = |
| 1198 scroll_offset_animation_was_interrupted_; |
| 1199 scroll_offset_animation_was_interrupted_ = false; |
1121 } | 1200 } |
1122 | 1201 |
1123 } // namespace cc | 1202 } // namespace cc |
OLD | NEW |