| OLD | NEW |
| (Empty) |
| 1 // Copyright 2012 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. | |
| 4 | |
| 5 #include "cc/animation/layer_animation_controller.h" | |
| 6 | |
| 7 #include <stddef.h> | |
| 8 | |
| 9 #include <algorithm> | |
| 10 #include <vector> | |
| 11 | |
| 12 #include "cc/animation/animation.h" | |
| 13 #include "cc/animation/animation_curve.h" | |
| 14 #include "cc/animation/animation_delegate.h" | |
| 15 #include "cc/animation/animation_events.h" | |
| 16 #include "cc/animation/animation_host.h" | |
| 17 #include "cc/animation/keyframed_animation_curve.h" | |
| 18 #include "cc/animation/layer_animation_value_observer.h" | |
| 19 #include "cc/animation/layer_animation_value_provider.h" | |
| 20 #include "cc/animation/scroll_offset_animation_curve.h" | |
| 21 #include "cc/output/filter_operations.h" | |
| 22 #include "ui/gfx/geometry/box_f.h" | |
| 23 #include "ui/gfx/transform.h" | |
| 24 | |
| 25 namespace cc { | |
| 26 | |
| 27 LayerAnimationController::LayerAnimationController(int id) | |
| 28 : host_(0), | |
| 29 id_(id), | |
| 30 is_active_(false), | |
| 31 value_observer_(nullptr), | |
| 32 value_provider_(nullptr), | |
| 33 layer_animation_delegate_(nullptr), | |
| 34 needs_active_value_observations_(false), | |
| 35 needs_pending_value_observations_(false), | |
| 36 needs_to_start_animations_(false), | |
| 37 scroll_offset_animation_was_interrupted_(false), | |
| 38 potentially_animating_transform_for_active_observers_(false), | |
| 39 potentially_animating_transform_for_pending_observers_(false) {} | |
| 40 | |
| 41 LayerAnimationController::~LayerAnimationController() { | |
| 42 if (host_) | |
| 43 host_->UnregisterAnimationController(this); | |
| 44 } | |
| 45 | |
| 46 scoped_refptr<LayerAnimationController> LayerAnimationController::Create( | |
| 47 int id) { | |
| 48 return make_scoped_refptr(new LayerAnimationController(id)); | |
| 49 } | |
| 50 | |
| 51 void LayerAnimationController::PauseAnimation(int animation_id, | |
| 52 base::TimeDelta time_offset) { | |
| 53 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 54 if (animations_[i]->id() == animation_id) { | |
| 55 animations_[i]->SetRunState(Animation::PAUSED, | |
| 56 time_offset + animations_[i]->start_time() + | |
| 57 animations_[i]->time_offset()); | |
| 58 } | |
| 59 } | |
| 60 } | |
| 61 | |
| 62 void LayerAnimationController::UpdatePotentiallyAnimatingTransform() { | |
| 63 bool was_potentially_animating_transform_for_active_observers = | |
| 64 potentially_animating_transform_for_active_observers_; | |
| 65 bool was_potentially_animating_transform_for_pending_observers = | |
| 66 potentially_animating_transform_for_pending_observers_; | |
| 67 | |
| 68 potentially_animating_transform_for_active_observers_ = false; | |
| 69 potentially_animating_transform_for_pending_observers_ = false; | |
| 70 | |
| 71 for (const auto& animation : animations_) { | |
| 72 if (!animation->is_finished() && | |
| 73 animation->target_property() == TargetProperty::TRANSFORM) { | |
| 74 potentially_animating_transform_for_active_observers_ |= | |
| 75 animation->affects_active_observers(); | |
| 76 potentially_animating_transform_for_pending_observers_ |= | |
| 77 animation->affects_pending_observers(); | |
| 78 } | |
| 79 } | |
| 80 | |
| 81 bool changed_for_active_observers = | |
| 82 was_potentially_animating_transform_for_active_observers != | |
| 83 potentially_animating_transform_for_active_observers_; | |
| 84 bool changed_for_pending_observers = | |
| 85 was_potentially_animating_transform_for_pending_observers != | |
| 86 potentially_animating_transform_for_pending_observers_; | |
| 87 | |
| 88 if (!changed_for_active_observers && !changed_for_pending_observers) | |
| 89 return; | |
| 90 | |
| 91 NotifyObserversTransformIsPotentiallyAnimatingChanged( | |
| 92 changed_for_active_observers, changed_for_pending_observers); | |
| 93 } | |
| 94 | |
| 95 void LayerAnimationController::RemoveAnimation(int animation_id) { | |
| 96 bool removed_transform_animation = false; | |
| 97 // Since we want to use the animations that we're going to remove, we need to | |
| 98 // use a stable_parition here instead of remove_if. Remove_if leaves the | |
| 99 // removed items in an unspecified state. | |
| 100 auto animations_to_remove = std::stable_partition( | |
| 101 animations_.begin(), animations_.end(), | |
| 102 [animation_id](const std::unique_ptr<Animation>& animation) { | |
| 103 return animation->id() != animation_id; | |
| 104 }); | |
| 105 for (auto it = animations_to_remove; it != animations_.end(); ++it) { | |
| 106 if ((*it)->target_property() == TargetProperty::SCROLL_OFFSET) { | |
| 107 scroll_offset_animation_was_interrupted_ = true; | |
| 108 } else if ((*it)->target_property() == TargetProperty::TRANSFORM && | |
| 109 !(*it)->is_finished()) { | |
| 110 removed_transform_animation = true; | |
| 111 } | |
| 112 } | |
| 113 | |
| 114 animations_.erase(animations_to_remove, animations_.end()); | |
| 115 UpdateActivation(NORMAL_ACTIVATION); | |
| 116 if (removed_transform_animation) | |
| 117 UpdatePotentiallyAnimatingTransform(); | |
| 118 } | |
| 119 | |
| 120 void LayerAnimationController::AbortAnimation(int animation_id) { | |
| 121 bool aborted_transform_animation = false; | |
| 122 if (Animation* animation = GetAnimationById(animation_id)) { | |
| 123 if (!animation->is_finished()) { | |
| 124 animation->SetRunState(Animation::ABORTED, last_tick_time_); | |
| 125 if (animation->target_property() == TargetProperty::TRANSFORM) | |
| 126 aborted_transform_animation = true; | |
| 127 } | |
| 128 } | |
| 129 if (aborted_transform_animation) | |
| 130 UpdatePotentiallyAnimatingTransform(); | |
| 131 } | |
| 132 | |
| 133 void LayerAnimationController::AbortAnimations( | |
| 134 TargetProperty::Type target_property, | |
| 135 bool needs_completion) { | |
| 136 if (needs_completion) | |
| 137 DCHECK(target_property == TargetProperty::SCROLL_OFFSET); | |
| 138 | |
| 139 bool aborted_transform_animation = false; | |
| 140 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 141 if (animations_[i]->target_property() == target_property && | |
| 142 !animations_[i]->is_finished()) { | |
| 143 // Currently only impl-only scroll offset animations can be completed on | |
| 144 // the main thread. | |
| 145 if (needs_completion && animations_[i]->is_impl_only()) { | |
| 146 animations_[i]->SetRunState(Animation::ABORTED_BUT_NEEDS_COMPLETION, | |
| 147 last_tick_time_); | |
| 148 } else { | |
| 149 animations_[i]->SetRunState(Animation::ABORTED, last_tick_time_); | |
| 150 } | |
| 151 if (target_property == TargetProperty::TRANSFORM) | |
| 152 aborted_transform_animation = true; | |
| 153 } | |
| 154 } | |
| 155 if (aborted_transform_animation) | |
| 156 UpdatePotentiallyAnimatingTransform(); | |
| 157 } | |
| 158 | |
| 159 // Ensures that the list of active animations on the main thread and the impl | |
| 160 // thread are kept in sync. | |
| 161 void LayerAnimationController::PushAnimationUpdatesTo( | |
| 162 LayerAnimationController* controller_impl) { | |
| 163 DCHECK(this != controller_impl); | |
| 164 if (!has_any_animation() && !controller_impl->has_any_animation()) | |
| 165 return; | |
| 166 MarkAbortedAnimationsForDeletion(controller_impl); | |
| 167 PurgeAnimationsMarkedForDeletion(); | |
| 168 PushNewAnimationsToImplThread(controller_impl); | |
| 169 | |
| 170 // Remove finished impl side animations only after pushing, | |
| 171 // and only after the animations are deleted on the main thread | |
| 172 // this insures we will never push an animation twice. | |
| 173 RemoveAnimationsCompletedOnMainThread(controller_impl); | |
| 174 | |
| 175 PushPropertiesToImplThread(controller_impl); | |
| 176 controller_impl->UpdateActivation(NORMAL_ACTIVATION); | |
| 177 UpdateActivation(NORMAL_ACTIVATION); | |
| 178 } | |
| 179 | |
| 180 void LayerAnimationController::Animate(base::TimeTicks monotonic_time) { | |
| 181 DCHECK(!monotonic_time.is_null()); | |
| 182 if (!HasValueObserver()) | |
| 183 return; | |
| 184 | |
| 185 if (needs_to_start_animations_) | |
| 186 StartAnimations(monotonic_time); | |
| 187 TickAnimations(monotonic_time); | |
| 188 last_tick_time_ = monotonic_time; | |
| 189 } | |
| 190 | |
| 191 void LayerAnimationController::AccumulatePropertyUpdates( | |
| 192 base::TimeTicks monotonic_time, | |
| 193 AnimationEvents* events) { | |
| 194 if (!events) | |
| 195 return; | |
| 196 | |
| 197 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 198 Animation* animation = animations_[i].get(); | |
| 199 if (!animation->is_impl_only()) | |
| 200 continue; | |
| 201 | |
| 202 if (!animation->InEffect(monotonic_time)) | |
| 203 continue; | |
| 204 | |
| 205 base::TimeDelta trimmed = | |
| 206 animation->TrimTimeToCurrentIteration(monotonic_time); | |
| 207 switch (animation->target_property()) { | |
| 208 case TargetProperty::OPACITY: { | |
| 209 AnimationEvent event(AnimationEvent::PROPERTY_UPDATE, id_, | |
| 210 animation->group(), TargetProperty::OPACITY, | |
| 211 monotonic_time); | |
| 212 const FloatAnimationCurve* float_animation_curve = | |
| 213 animation->curve()->ToFloatAnimationCurve(); | |
| 214 event.opacity = float_animation_curve->GetValue(trimmed); | |
| 215 event.is_impl_only = true; | |
| 216 events->events_.push_back(event); | |
| 217 break; | |
| 218 } | |
| 219 | |
| 220 case TargetProperty::TRANSFORM: { | |
| 221 AnimationEvent event(AnimationEvent::PROPERTY_UPDATE, id_, | |
| 222 animation->group(), TargetProperty::TRANSFORM, | |
| 223 monotonic_time); | |
| 224 const TransformAnimationCurve* transform_animation_curve = | |
| 225 animation->curve()->ToTransformAnimationCurve(); | |
| 226 event.transform = transform_animation_curve->GetValue(trimmed); | |
| 227 event.is_impl_only = true; | |
| 228 events->events_.push_back(event); | |
| 229 break; | |
| 230 } | |
| 231 | |
| 232 case TargetProperty::FILTER: { | |
| 233 AnimationEvent event(AnimationEvent::PROPERTY_UPDATE, id_, | |
| 234 animation->group(), TargetProperty::FILTER, | |
| 235 monotonic_time); | |
| 236 const FilterAnimationCurve* filter_animation_curve = | |
| 237 animation->curve()->ToFilterAnimationCurve(); | |
| 238 event.filters = filter_animation_curve->GetValue(trimmed); | |
| 239 event.is_impl_only = true; | |
| 240 events->events_.push_back(event); | |
| 241 break; | |
| 242 } | |
| 243 | |
| 244 case TargetProperty::BACKGROUND_COLOR: { | |
| 245 break; | |
| 246 } | |
| 247 | |
| 248 case TargetProperty::SCROLL_OFFSET: { | |
| 249 // Impl-side changes to scroll offset are already sent back to the | |
| 250 // main thread (e.g. for user-driven scrolling), so a PROPERTY_UPDATE | |
| 251 // isn't needed. | |
| 252 break; | |
| 253 } | |
| 254 } | |
| 255 } | |
| 256 } | |
| 257 | |
| 258 void LayerAnimationController::UpdateState(bool start_ready_animations, | |
| 259 AnimationEvents* events) { | |
| 260 if (!HasActiveValueObserver()) | |
| 261 return; | |
| 262 | |
| 263 // Animate hasn't been called, this happens if an observer has been added | |
| 264 // between the Commit and Draw phases. | |
| 265 if (last_tick_time_ == base::TimeTicks()) | |
| 266 return; | |
| 267 | |
| 268 if (start_ready_animations) | |
| 269 PromoteStartedAnimations(last_tick_time_, events); | |
| 270 | |
| 271 MarkFinishedAnimations(last_tick_time_); | |
| 272 MarkAnimationsForDeletion(last_tick_time_, events); | |
| 273 | |
| 274 if (needs_to_start_animations_ && start_ready_animations) { | |
| 275 StartAnimations(last_tick_time_); | |
| 276 PromoteStartedAnimations(last_tick_time_, events); | |
| 277 } | |
| 278 | |
| 279 AccumulatePropertyUpdates(last_tick_time_, events); | |
| 280 | |
| 281 UpdateActivation(NORMAL_ACTIVATION); | |
| 282 } | |
| 283 | |
| 284 void LayerAnimationController::ActivateAnimations() { | |
| 285 bool changed_transform_animation = false; | |
| 286 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 287 if (animations_[i]->affects_active_observers() != | |
| 288 animations_[i]->affects_pending_observers() && | |
| 289 animations_[i]->target_property() == TargetProperty::TRANSFORM) | |
| 290 changed_transform_animation = true; | |
| 291 animations_[i]->set_affects_active_observers( | |
| 292 animations_[i]->affects_pending_observers()); | |
| 293 } | |
| 294 auto affects_no_observers = [](const std::unique_ptr<Animation>& animation) { | |
| 295 return !animation->affects_active_observers() && | |
| 296 !animation->affects_pending_observers(); | |
| 297 }; | |
| 298 animations_.erase(std::remove_if(animations_.begin(), animations_.end(), | |
| 299 affects_no_observers), | |
| 300 animations_.end()); | |
| 301 scroll_offset_animation_was_interrupted_ = false; | |
| 302 UpdateActivation(NORMAL_ACTIVATION); | |
| 303 if (changed_transform_animation) | |
| 304 UpdatePotentiallyAnimatingTransform(); | |
| 305 } | |
| 306 | |
| 307 void LayerAnimationController::AddAnimation( | |
| 308 std::unique_ptr<Animation> animation) { | |
| 309 bool added_transform_animation = | |
| 310 animation->target_property() == TargetProperty::TRANSFORM; | |
| 311 animations_.push_back(std::move(animation)); | |
| 312 needs_to_start_animations_ = true; | |
| 313 UpdateActivation(NORMAL_ACTIVATION); | |
| 314 if (added_transform_animation) | |
| 315 UpdatePotentiallyAnimatingTransform(); | |
| 316 } | |
| 317 | |
| 318 Animation* LayerAnimationController::GetAnimation( | |
| 319 TargetProperty::Type target_property) const { | |
| 320 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 321 size_t index = animations_.size() - i - 1; | |
| 322 if (animations_[index]->target_property() == target_property) | |
| 323 return animations_[index].get(); | |
| 324 } | |
| 325 return nullptr; | |
| 326 } | |
| 327 | |
| 328 Animation* LayerAnimationController::GetAnimationById(int animation_id) const { | |
| 329 for (size_t i = 0; i < animations_.size(); ++i) | |
| 330 if (animations_[i]->id() == animation_id) | |
| 331 return animations_[i].get(); | |
| 332 return nullptr; | |
| 333 } | |
| 334 | |
| 335 bool LayerAnimationController::HasActiveAnimation() const { | |
| 336 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 337 if (!animations_[i]->is_finished()) | |
| 338 return true; | |
| 339 } | |
| 340 return false; | |
| 341 } | |
| 342 | |
| 343 bool LayerAnimationController::IsPotentiallyAnimatingProperty( | |
| 344 TargetProperty::Type target_property, | |
| 345 ObserverType observer_type) const { | |
| 346 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 347 if (!animations_[i]->is_finished() && | |
| 348 animations_[i]->target_property() == target_property) { | |
| 349 if ((observer_type == ObserverType::ACTIVE && | |
| 350 animations_[i]->affects_active_observers()) || | |
| 351 (observer_type == ObserverType::PENDING && | |
| 352 animations_[i]->affects_pending_observers())) | |
| 353 return true; | |
| 354 } | |
| 355 } | |
| 356 return false; | |
| 357 } | |
| 358 | |
| 359 bool LayerAnimationController::IsCurrentlyAnimatingProperty( | |
| 360 TargetProperty::Type target_property, | |
| 361 ObserverType observer_type) const { | |
| 362 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 363 if (!animations_[i]->is_finished() && | |
| 364 animations_[i]->InEffect(last_tick_time_) && | |
| 365 animations_[i]->target_property() == target_property) { | |
| 366 if ((observer_type == ObserverType::ACTIVE && | |
| 367 animations_[i]->affects_active_observers()) || | |
| 368 (observer_type == ObserverType::PENDING && | |
| 369 animations_[i]->affects_pending_observers())) | |
| 370 return true; | |
| 371 } | |
| 372 } | |
| 373 return false; | |
| 374 } | |
| 375 | |
| 376 void LayerAnimationController::SetAnimationHost(AnimationHost* host) { | |
| 377 if (host_ == host) | |
| 378 return; | |
| 379 | |
| 380 if (host_) | |
| 381 host_->UnregisterAnimationController(this); | |
| 382 | |
| 383 host_ = host; | |
| 384 if (host_) | |
| 385 host_->RegisterAnimationController(this); | |
| 386 | |
| 387 UpdateActivation(FORCE_ACTIVATION); | |
| 388 } | |
| 389 | |
| 390 void LayerAnimationController::NotifyAnimationStarted( | |
| 391 const AnimationEvent& event) { | |
| 392 if (event.is_impl_only) { | |
| 393 if (layer_animation_delegate_) | |
| 394 layer_animation_delegate_->NotifyAnimationStarted( | |
| 395 event.monotonic_time, event.target_property, event.group_id); | |
| 396 return; | |
| 397 } | |
| 398 | |
| 399 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 400 if (animations_[i]->group() == event.group_id && | |
| 401 animations_[i]->target_property() == event.target_property && | |
| 402 animations_[i]->needs_synchronized_start_time()) { | |
| 403 animations_[i]->set_needs_synchronized_start_time(false); | |
| 404 if (!animations_[i]->has_set_start_time()) | |
| 405 animations_[i]->set_start_time(event.monotonic_time); | |
| 406 | |
| 407 if (layer_animation_delegate_) | |
| 408 layer_animation_delegate_->NotifyAnimationStarted( | |
| 409 event.monotonic_time, event.target_property, event.group_id); | |
| 410 | |
| 411 return; | |
| 412 } | |
| 413 } | |
| 414 } | |
| 415 | |
| 416 void LayerAnimationController::NotifyAnimationFinished( | |
| 417 const AnimationEvent& event) { | |
| 418 if (event.is_impl_only) { | |
| 419 if (layer_animation_delegate_) | |
| 420 layer_animation_delegate_->NotifyAnimationFinished( | |
| 421 event.monotonic_time, event.target_property, event.group_id); | |
| 422 return; | |
| 423 } | |
| 424 | |
| 425 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 426 if (animations_[i]->group() == event.group_id && | |
| 427 animations_[i]->target_property() == event.target_property) { | |
| 428 animations_[i]->set_received_finished_event(true); | |
| 429 if (layer_animation_delegate_) | |
| 430 layer_animation_delegate_->NotifyAnimationFinished( | |
| 431 event.monotonic_time, event.target_property, event.group_id); | |
| 432 | |
| 433 return; | |
| 434 } | |
| 435 } | |
| 436 } | |
| 437 | |
| 438 void LayerAnimationController::NotifyAnimationTakeover( | |
| 439 const AnimationEvent& event) { | |
| 440 DCHECK(event.target_property == TargetProperty::SCROLL_OFFSET); | |
| 441 if (layer_animation_delegate_) { | |
| 442 std::unique_ptr<AnimationCurve> animation_curve = event.curve->Clone(); | |
| 443 layer_animation_delegate_->NotifyAnimationTakeover( | |
| 444 event.monotonic_time, event.target_property, event.animation_start_time, | |
| 445 std::move(animation_curve)); | |
| 446 } | |
| 447 } | |
| 448 | |
| 449 void LayerAnimationController::NotifyAnimationAborted( | |
| 450 const AnimationEvent& event) { | |
| 451 bool aborted_transform_animation = false; | |
| 452 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 453 if (animations_[i]->group() == event.group_id && | |
| 454 animations_[i]->target_property() == event.target_property) { | |
| 455 animations_[i]->SetRunState(Animation::ABORTED, event.monotonic_time); | |
| 456 animations_[i]->set_received_finished_event(true); | |
| 457 if (layer_animation_delegate_) | |
| 458 layer_animation_delegate_->NotifyAnimationAborted( | |
| 459 event.monotonic_time, event.target_property, event.group_id); | |
| 460 if (event.target_property == TargetProperty::TRANSFORM) | |
| 461 aborted_transform_animation = true; | |
| 462 break; | |
| 463 } | |
| 464 } | |
| 465 if (aborted_transform_animation) | |
| 466 UpdatePotentiallyAnimatingTransform(); | |
| 467 } | |
| 468 | |
| 469 void LayerAnimationController::NotifyAnimationPropertyUpdate( | |
| 470 const AnimationEvent& event) { | |
| 471 bool notify_active_observers = true; | |
| 472 bool notify_pending_observers = true; | |
| 473 switch (event.target_property) { | |
| 474 case TargetProperty::OPACITY: | |
| 475 NotifyObserversOpacityAnimated( | |
| 476 event.opacity, notify_active_observers, notify_pending_observers); | |
| 477 break; | |
| 478 case TargetProperty::TRANSFORM: | |
| 479 NotifyObserversTransformAnimated( | |
| 480 event.transform, notify_active_observers, notify_pending_observers); | |
| 481 break; | |
| 482 default: | |
| 483 NOTREACHED(); | |
| 484 } | |
| 485 } | |
| 486 | |
| 487 bool LayerAnimationController::HasFilterAnimationThatInflatesBounds() const { | |
| 488 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 489 if (!animations_[i]->is_finished() && | |
| 490 animations_[i]->target_property() == TargetProperty::FILTER && | |
| 491 animations_[i] | |
| 492 ->curve() | |
| 493 ->ToFilterAnimationCurve() | |
| 494 ->HasFilterThatMovesPixels()) | |
| 495 return true; | |
| 496 } | |
| 497 | |
| 498 return false; | |
| 499 } | |
| 500 | |
| 501 bool LayerAnimationController::HasTransformAnimationThatInflatesBounds() const { | |
| 502 return IsCurrentlyAnimatingProperty(TargetProperty::TRANSFORM, | |
| 503 ObserverType::ACTIVE) || | |
| 504 IsCurrentlyAnimatingProperty(TargetProperty::TRANSFORM, | |
| 505 ObserverType::PENDING); | |
| 506 } | |
| 507 | |
| 508 bool LayerAnimationController::FilterAnimationBoundsForBox( | |
| 509 const gfx::BoxF& box, gfx::BoxF* bounds) const { | |
| 510 // TODO(avallee): Implement. | |
| 511 return false; | |
| 512 } | |
| 513 | |
| 514 bool LayerAnimationController::TransformAnimationBoundsForBox( | |
| 515 const gfx::BoxF& box, | |
| 516 gfx::BoxF* bounds) const { | |
| 517 DCHECK(HasTransformAnimationThatInflatesBounds()) | |
| 518 << "TransformAnimationBoundsForBox will give incorrect results if there " | |
| 519 << "are no transform animations affecting bounds, non-animated transform " | |
| 520 << "is not known"; | |
| 521 | |
| 522 // Compute bounds based on animations for which is_finished() is false. | |
| 523 // Do nothing if there are no such animations; in this case, it is assumed | |
| 524 // that callers will take care of computing bounds based on the owning layer's | |
| 525 // actual transform. | |
| 526 *bounds = gfx::BoxF(); | |
| 527 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 528 if (animations_[i]->is_finished() || | |
| 529 animations_[i]->target_property() != TargetProperty::TRANSFORM) | |
| 530 continue; | |
| 531 | |
| 532 const TransformAnimationCurve* transform_animation_curve = | |
| 533 animations_[i]->curve()->ToTransformAnimationCurve(); | |
| 534 gfx::BoxF animation_bounds; | |
| 535 bool success = | |
| 536 transform_animation_curve->AnimatedBoundsForBox(box, &animation_bounds); | |
| 537 if (!success) | |
| 538 return false; | |
| 539 bounds->Union(animation_bounds); | |
| 540 } | |
| 541 | |
| 542 return true; | |
| 543 } | |
| 544 | |
| 545 bool LayerAnimationController::HasAnimationThatAffectsScale() const { | |
| 546 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 547 if (animations_[i]->is_finished() || | |
| 548 animations_[i]->target_property() != TargetProperty::TRANSFORM) | |
| 549 continue; | |
| 550 | |
| 551 const TransformAnimationCurve* transform_animation_curve = | |
| 552 animations_[i]->curve()->ToTransformAnimationCurve(); | |
| 553 if (transform_animation_curve->AffectsScale()) | |
| 554 return true; | |
| 555 } | |
| 556 | |
| 557 return false; | |
| 558 } | |
| 559 | |
| 560 bool LayerAnimationController::HasOnlyTranslationTransforms( | |
| 561 ObserverType observer_type) const { | |
| 562 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 563 if (animations_[i]->is_finished() || | |
| 564 animations_[i]->target_property() != TargetProperty::TRANSFORM) | |
| 565 continue; | |
| 566 | |
| 567 if ((observer_type == ObserverType::ACTIVE && | |
| 568 !animations_[i]->affects_active_observers()) || | |
| 569 (observer_type == ObserverType::PENDING && | |
| 570 !animations_[i]->affects_pending_observers())) | |
| 571 continue; | |
| 572 | |
| 573 const TransformAnimationCurve* transform_animation_curve = | |
| 574 animations_[i]->curve()->ToTransformAnimationCurve(); | |
| 575 if (!transform_animation_curve->IsTranslation()) | |
| 576 return false; | |
| 577 } | |
| 578 | |
| 579 return true; | |
| 580 } | |
| 581 | |
| 582 bool LayerAnimationController::AnimationsPreserveAxisAlignment() const { | |
| 583 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 584 if (animations_[i]->is_finished() || | |
| 585 animations_[i]->target_property() != TargetProperty::TRANSFORM) | |
| 586 continue; | |
| 587 | |
| 588 const TransformAnimationCurve* transform_animation_curve = | |
| 589 animations_[i]->curve()->ToTransformAnimationCurve(); | |
| 590 if (!transform_animation_curve->PreservesAxisAlignment()) | |
| 591 return false; | |
| 592 } | |
| 593 | |
| 594 return true; | |
| 595 } | |
| 596 | |
| 597 bool LayerAnimationController::AnimationStartScale(ObserverType observer_type, | |
| 598 float* start_scale) const { | |
| 599 *start_scale = 0.f; | |
| 600 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 601 if (animations_[i]->is_finished() || | |
| 602 animations_[i]->target_property() != TargetProperty::TRANSFORM) | |
| 603 continue; | |
| 604 | |
| 605 if ((observer_type == ObserverType::ACTIVE && | |
| 606 !animations_[i]->affects_active_observers()) || | |
| 607 (observer_type == ObserverType::PENDING && | |
| 608 !animations_[i]->affects_pending_observers())) | |
| 609 continue; | |
| 610 | |
| 611 bool forward_direction = true; | |
| 612 switch (animations_[i]->direction()) { | |
| 613 case Animation::DIRECTION_NORMAL: | |
| 614 case Animation::DIRECTION_ALTERNATE: | |
| 615 forward_direction = animations_[i]->playback_rate() >= 0.0; | |
| 616 break; | |
| 617 case Animation::DIRECTION_REVERSE: | |
| 618 case Animation::DIRECTION_ALTERNATE_REVERSE: | |
| 619 forward_direction = animations_[i]->playback_rate() < 0.0; | |
| 620 break; | |
| 621 } | |
| 622 | |
| 623 const TransformAnimationCurve* transform_animation_curve = | |
| 624 animations_[i]->curve()->ToTransformAnimationCurve(); | |
| 625 float animation_start_scale = 0.f; | |
| 626 if (!transform_animation_curve->AnimationStartScale(forward_direction, | |
| 627 &animation_start_scale)) | |
| 628 return false; | |
| 629 *start_scale = std::max(*start_scale, animation_start_scale); | |
| 630 } | |
| 631 return true; | |
| 632 } | |
| 633 | |
| 634 bool LayerAnimationController::MaximumTargetScale(ObserverType observer_type, | |
| 635 float* max_scale) const { | |
| 636 *max_scale = 0.f; | |
| 637 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 638 if (animations_[i]->is_finished() || | |
| 639 animations_[i]->target_property() != TargetProperty::TRANSFORM) | |
| 640 continue; | |
| 641 | |
| 642 if ((observer_type == ObserverType::ACTIVE && | |
| 643 !animations_[i]->affects_active_observers()) || | |
| 644 (observer_type == ObserverType::PENDING && | |
| 645 !animations_[i]->affects_pending_observers())) | |
| 646 continue; | |
| 647 | |
| 648 bool forward_direction = true; | |
| 649 switch (animations_[i]->direction()) { | |
| 650 case Animation::DIRECTION_NORMAL: | |
| 651 case Animation::DIRECTION_ALTERNATE: | |
| 652 forward_direction = animations_[i]->playback_rate() >= 0.0; | |
| 653 break; | |
| 654 case Animation::DIRECTION_REVERSE: | |
| 655 case Animation::DIRECTION_ALTERNATE_REVERSE: | |
| 656 forward_direction = animations_[i]->playback_rate() < 0.0; | |
| 657 break; | |
| 658 } | |
| 659 | |
| 660 const TransformAnimationCurve* transform_animation_curve = | |
| 661 animations_[i]->curve()->ToTransformAnimationCurve(); | |
| 662 float animation_scale = 0.f; | |
| 663 if (!transform_animation_curve->MaximumTargetScale(forward_direction, | |
| 664 &animation_scale)) | |
| 665 return false; | |
| 666 *max_scale = std::max(*max_scale, animation_scale); | |
| 667 } | |
| 668 | |
| 669 return true; | |
| 670 } | |
| 671 | |
| 672 void LayerAnimationController::PushNewAnimationsToImplThread( | |
| 673 LayerAnimationController* controller_impl) const { | |
| 674 // Any new animations owned by the main thread's controller are cloned and | |
| 675 // add to the impl thread's controller. | |
| 676 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 677 // If the animation is already running on the impl thread, there is no | |
| 678 // need to copy it over. | |
| 679 if (controller_impl->GetAnimationById(animations_[i]->id())) | |
| 680 continue; | |
| 681 | |
| 682 if (animations_[i]->target_property() == TargetProperty::SCROLL_OFFSET && | |
| 683 !animations_[i] | |
| 684 ->curve() | |
| 685 ->ToScrollOffsetAnimationCurve() | |
| 686 ->HasSetInitialValue()) { | |
| 687 gfx::ScrollOffset current_scroll_offset; | |
| 688 if (controller_impl->value_provider_) { | |
| 689 current_scroll_offset = | |
| 690 controller_impl->value_provider_->ScrollOffsetForAnimation(); | |
| 691 } else { | |
| 692 // The owning layer isn't yet in the active tree, so the main thread | |
| 693 // scroll offset will be up-to-date. | |
| 694 current_scroll_offset = value_provider_->ScrollOffsetForAnimation(); | |
| 695 } | |
| 696 animations_[i]->curve()->ToScrollOffsetAnimationCurve()->SetInitialValue( | |
| 697 current_scroll_offset); | |
| 698 } | |
| 699 | |
| 700 // The new animation should be set to run as soon as possible. | |
| 701 Animation::RunState initial_run_state = | |
| 702 Animation::WAITING_FOR_TARGET_AVAILABILITY; | |
| 703 std::unique_ptr<Animation> to_add( | |
| 704 animations_[i]->CloneAndInitialize(initial_run_state)); | |
| 705 DCHECK(!to_add->needs_synchronized_start_time()); | |
| 706 to_add->set_affects_active_observers(false); | |
| 707 controller_impl->AddAnimation(std::move(to_add)); | |
| 708 } | |
| 709 } | |
| 710 | |
| 711 static bool IsCompleted( | |
| 712 Animation* animation, | |
| 713 const LayerAnimationController* main_thread_controller) { | |
| 714 if (animation->is_impl_only()) { | |
| 715 return (animation->run_state() == Animation::WAITING_FOR_DELETION); | |
| 716 } else { | |
| 717 return !main_thread_controller->GetAnimationById(animation->id()); | |
| 718 } | |
| 719 } | |
| 720 | |
| 721 void LayerAnimationController::RemoveAnimationsCompletedOnMainThread( | |
| 722 LayerAnimationController* controller_impl) const { | |
| 723 bool removed_transform_animation = false; | |
| 724 // Animations removed on the main thread should no longer affect pending | |
| 725 // observers, and should stop affecting active observers after the next call | |
| 726 // to ActivateAnimations. If already WAITING_FOR_DELETION, they can be removed | |
| 727 // immediately. | |
| 728 auto& animations = controller_impl->animations_; | |
| 729 for (const auto& animation : animations) { | |
| 730 if (IsCompleted(animation.get(), this)) { | |
| 731 animation->set_affects_pending_observers(false); | |
| 732 if (animation->target_property() == TargetProperty::TRANSFORM) | |
| 733 removed_transform_animation = true; | |
| 734 } | |
| 735 } | |
| 736 auto affects_active_only_and_is_waiting_for_deletion = []( | |
| 737 const std::unique_ptr<Animation>& animation) { | |
| 738 return animation->run_state() == Animation::WAITING_FOR_DELETION && | |
| 739 !animation->affects_pending_observers(); | |
| 740 }; | |
| 741 animations.erase( | |
| 742 std::remove_if(animations.begin(), animations.end(), | |
| 743 affects_active_only_and_is_waiting_for_deletion), | |
| 744 animations.end()); | |
| 745 | |
| 746 if (removed_transform_animation) | |
| 747 controller_impl->UpdatePotentiallyAnimatingTransform(); | |
| 748 } | |
| 749 | |
| 750 void LayerAnimationController::PushPropertiesToImplThread( | |
| 751 LayerAnimationController* controller_impl) { | |
| 752 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 753 Animation* current_impl = | |
| 754 controller_impl->GetAnimationById(animations_[i]->id()); | |
| 755 if (current_impl) | |
| 756 animations_[i]->PushPropertiesTo(current_impl); | |
| 757 } | |
| 758 controller_impl->scroll_offset_animation_was_interrupted_ = | |
| 759 scroll_offset_animation_was_interrupted_; | |
| 760 scroll_offset_animation_was_interrupted_ = false; | |
| 761 } | |
| 762 | |
| 763 void LayerAnimationController::StartAnimations(base::TimeTicks monotonic_time) { | |
| 764 DCHECK(needs_to_start_animations_); | |
| 765 needs_to_start_animations_ = false; | |
| 766 // First collect running properties affecting each type of observer. | |
| 767 TargetProperties blocked_properties_for_active_observers; | |
| 768 TargetProperties blocked_properties_for_pending_observers; | |
| 769 std::vector<size_t> animations_waiting_for_target; | |
| 770 | |
| 771 animations_waiting_for_target.reserve(animations_.size()); | |
| 772 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 773 if (animations_[i]->run_state() == Animation::STARTING || | |
| 774 animations_[i]->run_state() == Animation::RUNNING) { | |
| 775 if (animations_[i]->affects_active_observers()) { | |
| 776 blocked_properties_for_active_observers[animations_[i] | |
| 777 ->target_property()] = true; | |
| 778 } | |
| 779 if (animations_[i]->affects_pending_observers()) { | |
| 780 blocked_properties_for_pending_observers[animations_[i] | |
| 781 ->target_property()] = | |
| 782 true; | |
| 783 } | |
| 784 } else if (animations_[i]->run_state() == | |
| 785 Animation::WAITING_FOR_TARGET_AVAILABILITY) { | |
| 786 animations_waiting_for_target.push_back(i); | |
| 787 } | |
| 788 } | |
| 789 | |
| 790 for (size_t i = 0; i < animations_waiting_for_target.size(); ++i) { | |
| 791 // Collect all properties for animations with the same group id (they | |
| 792 // should all also be in the list of animations). | |
| 793 size_t animation_index = animations_waiting_for_target[i]; | |
| 794 Animation* animation_waiting_for_target = | |
| 795 animations_[animation_index].get(); | |
| 796 // Check for the run state again even though the animation was waiting | |
| 797 // for target because it might have changed the run state while handling | |
| 798 // previous animation in this loop (if they belong to same group). | |
| 799 if (animation_waiting_for_target->run_state() == | |
| 800 Animation::WAITING_FOR_TARGET_AVAILABILITY) { | |
| 801 TargetProperties enqueued_properties; | |
| 802 bool affects_active_observers = | |
| 803 animation_waiting_for_target->affects_active_observers(); | |
| 804 bool affects_pending_observers = | |
| 805 animation_waiting_for_target->affects_pending_observers(); | |
| 806 enqueued_properties[animation_waiting_for_target->target_property()] = | |
| 807 true; | |
| 808 for (size_t j = animation_index + 1; j < animations_.size(); ++j) { | |
| 809 if (animation_waiting_for_target->group() == animations_[j]->group()) { | |
| 810 enqueued_properties[animations_[j]->target_property()] = true; | |
| 811 affects_active_observers |= | |
| 812 animations_[j]->affects_active_observers(); | |
| 813 affects_pending_observers |= | |
| 814 animations_[j]->affects_pending_observers(); | |
| 815 } | |
| 816 } | |
| 817 | |
| 818 // Check to see if intersection of the list of properties affected by | |
| 819 // the group and the list of currently blocked properties is null, taking | |
| 820 // into account the type(s) of observers affected by the group. In any | |
| 821 // case, the group's target properties need to be added to the lists of | |
| 822 // blocked properties. | |
| 823 bool null_intersection = true; | |
| 824 static_assert(TargetProperty::FIRST_TARGET_PROPERTY == 0, | |
| 825 "TargetProperty must be 0-based enum"); | |
| 826 for (int property = TargetProperty::FIRST_TARGET_PROPERTY; | |
| 827 property <= TargetProperty::LAST_TARGET_PROPERTY; ++property) { | |
| 828 if (enqueued_properties[property]) { | |
| 829 if (affects_active_observers) { | |
| 830 if (blocked_properties_for_active_observers[property]) | |
| 831 null_intersection = false; | |
| 832 else | |
| 833 blocked_properties_for_active_observers[property] = true; | |
| 834 } | |
| 835 if (affects_pending_observers) { | |
| 836 if (blocked_properties_for_pending_observers[property]) | |
| 837 null_intersection = false; | |
| 838 else | |
| 839 blocked_properties_for_pending_observers[property] = true; | |
| 840 } | |
| 841 } | |
| 842 } | |
| 843 | |
| 844 // If the intersection is null, then we are free to start the animations | |
| 845 // in the group. | |
| 846 if (null_intersection) { | |
| 847 animation_waiting_for_target->SetRunState(Animation::STARTING, | |
| 848 monotonic_time); | |
| 849 for (size_t j = animation_index + 1; j < animations_.size(); ++j) { | |
| 850 if (animation_waiting_for_target->group() == | |
| 851 animations_[j]->group()) { | |
| 852 animations_[j]->SetRunState(Animation::STARTING, monotonic_time); | |
| 853 } | |
| 854 } | |
| 855 } else { | |
| 856 needs_to_start_animations_ = true; | |
| 857 } | |
| 858 } | |
| 859 } | |
| 860 } | |
| 861 | |
| 862 void LayerAnimationController::PromoteStartedAnimations( | |
| 863 base::TimeTicks monotonic_time, | |
| 864 AnimationEvents* events) { | |
| 865 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 866 if (animations_[i]->run_state() == Animation::STARTING && | |
| 867 animations_[i]->affects_active_observers()) { | |
| 868 animations_[i]->SetRunState(Animation::RUNNING, monotonic_time); | |
| 869 if (!animations_[i]->has_set_start_time() && | |
| 870 !animations_[i]->needs_synchronized_start_time()) | |
| 871 animations_[i]->set_start_time(monotonic_time); | |
| 872 if (events) { | |
| 873 base::TimeTicks start_time; | |
| 874 if (animations_[i]->has_set_start_time()) | |
| 875 start_time = animations_[i]->start_time(); | |
| 876 else | |
| 877 start_time = monotonic_time; | |
| 878 AnimationEvent started_event( | |
| 879 AnimationEvent::STARTED, id_, animations_[i]->group(), | |
| 880 animations_[i]->target_property(), start_time); | |
| 881 started_event.is_impl_only = animations_[i]->is_impl_only(); | |
| 882 if (started_event.is_impl_only) | |
| 883 NotifyAnimationStarted(started_event); | |
| 884 else | |
| 885 events->events_.push_back(started_event); | |
| 886 } | |
| 887 } | |
| 888 } | |
| 889 } | |
| 890 | |
| 891 void LayerAnimationController::MarkFinishedAnimations( | |
| 892 base::TimeTicks monotonic_time) { | |
| 893 bool finished_transform_animation = false; | |
| 894 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 895 if (!animations_[i]->is_finished() && | |
| 896 animations_[i]->IsFinishedAt(monotonic_time)) { | |
| 897 animations_[i]->SetRunState(Animation::FINISHED, monotonic_time); | |
| 898 if (animations_[i]->target_property() == TargetProperty::TRANSFORM) { | |
| 899 finished_transform_animation = true; | |
| 900 } | |
| 901 } | |
| 902 } | |
| 903 if (finished_transform_animation) | |
| 904 UpdatePotentiallyAnimatingTransform(); | |
| 905 } | |
| 906 | |
| 907 void LayerAnimationController::MarkAnimationsForDeletion( | |
| 908 base::TimeTicks monotonic_time, | |
| 909 AnimationEvents* events) { | |
| 910 bool marked_animations_for_deletions = false; | |
| 911 std::vector<size_t> animations_with_same_group_id; | |
| 912 | |
| 913 animations_with_same_group_id.reserve(animations_.size()); | |
| 914 // Non-aborted animations are marked for deletion after a corresponding | |
| 915 // AnimationEvent::FINISHED event is sent or received. This means that if | |
| 916 // we don't have an events vector, we must ensure that non-aborted animations | |
| 917 // have received a finished event before marking them for deletion. | |
| 918 for (size_t i = 0; i < animations_.size(); i++) { | |
| 919 int group_id = animations_[i]->group(); | |
| 920 if (animations_[i]->run_state() == Animation::ABORTED) { | |
| 921 if (events && !animations_[i]->is_impl_only()) { | |
| 922 AnimationEvent aborted_event(AnimationEvent::ABORTED, id_, group_id, | |
| 923 animations_[i]->target_property(), | |
| 924 monotonic_time); | |
| 925 events->events_.push_back(aborted_event); | |
| 926 } | |
| 927 // If on the compositor or on the main thread and received finish event, | |
| 928 // animation can be marked for deletion. | |
| 929 if (events || animations_[i]->received_finished_event()) { | |
| 930 animations_[i]->SetRunState(Animation::WAITING_FOR_DELETION, | |
| 931 monotonic_time); | |
| 932 marked_animations_for_deletions = true; | |
| 933 } | |
| 934 continue; | |
| 935 } | |
| 936 | |
| 937 // If running on the compositor and need to complete an aborted animation | |
| 938 // on the main thread. | |
| 939 if (events && | |
| 940 animations_[i]->run_state() == | |
| 941 Animation::ABORTED_BUT_NEEDS_COMPLETION) { | |
| 942 AnimationEvent aborted_event(AnimationEvent::TAKEOVER, id_, group_id, | |
| 943 animations_[i]->target_property(), | |
| 944 monotonic_time); | |
| 945 aborted_event.animation_start_time = | |
| 946 (animations_[i]->start_time() - base::TimeTicks()).InSecondsF(); | |
| 947 const ScrollOffsetAnimationCurve* scroll_offset_animation_curve = | |
| 948 animations_[i]->curve()->ToScrollOffsetAnimationCurve(); | |
| 949 aborted_event.curve = scroll_offset_animation_curve->Clone(); | |
| 950 // Notify the compositor that the animation is finished. | |
| 951 if (layer_animation_delegate_) { | |
| 952 layer_animation_delegate_->NotifyAnimationFinished( | |
| 953 aborted_event.monotonic_time, aborted_event.target_property, | |
| 954 aborted_event.group_id); | |
| 955 } | |
| 956 // Notify main thread. | |
| 957 events->events_.push_back(aborted_event); | |
| 958 | |
| 959 // Remove the animation from the compositor. | |
| 960 animations_[i]->SetRunState(Animation::WAITING_FOR_DELETION, | |
| 961 monotonic_time); | |
| 962 marked_animations_for_deletions = true; | |
| 963 continue; | |
| 964 } | |
| 965 | |
| 966 bool all_anims_with_same_id_are_finished = false; | |
| 967 | |
| 968 // Since deleting an animation on the main thread leads to its deletion | |
| 969 // on the impl thread, we only mark a FINISHED main thread animation for | |
| 970 // deletion once it has received a FINISHED event from the impl thread. | |
| 971 bool animation_i_will_send_or_has_received_finish_event = | |
| 972 animations_[i]->is_controlling_instance() || | |
| 973 animations_[i]->is_impl_only() || | |
| 974 animations_[i]->received_finished_event(); | |
| 975 // If an animation is finished, and not already marked for deletion, | |
| 976 // find out if all other animations in the same group are also finished. | |
| 977 if (animations_[i]->run_state() == Animation::FINISHED && | |
| 978 animation_i_will_send_or_has_received_finish_event) { | |
| 979 // Clear the animations_with_same_group_id if it was added for | |
| 980 // the previous animation's iteration. | |
| 981 if (animations_with_same_group_id.size() > 0) | |
| 982 animations_with_same_group_id.clear(); | |
| 983 all_anims_with_same_id_are_finished = true; | |
| 984 for (size_t j = 0; j < animations_.size(); ++j) { | |
| 985 bool animation_j_will_send_or_has_received_finish_event = | |
| 986 animations_[j]->is_controlling_instance() || | |
| 987 animations_[j]->is_impl_only() || | |
| 988 animations_[j]->received_finished_event(); | |
| 989 if (group_id == animations_[j]->group()) { | |
| 990 if (!animations_[j]->is_finished() || | |
| 991 (animations_[j]->run_state() == Animation::FINISHED && | |
| 992 !animation_j_will_send_or_has_received_finish_event)) { | |
| 993 all_anims_with_same_id_are_finished = false; | |
| 994 break; | |
| 995 } else if (j >= i && | |
| 996 animations_[j]->run_state() != Animation::ABORTED) { | |
| 997 // Mark down the animations which belong to the same group | |
| 998 // and is not yet aborted. If this current iteration finds that all | |
| 999 // animations with same ID are finished, then the marked | |
| 1000 // animations below will be set to WAITING_FOR_DELETION in next | |
| 1001 // iteration. | |
| 1002 animations_with_same_group_id.push_back(j); | |
| 1003 } | |
| 1004 } | |
| 1005 } | |
| 1006 } | |
| 1007 if (all_anims_with_same_id_are_finished) { | |
| 1008 // We now need to remove all animations with the same group id as | |
| 1009 // group_id (and send along animation finished notifications, if | |
| 1010 // necessary). | |
| 1011 for (size_t j = 0; j < animations_with_same_group_id.size(); j++) { | |
| 1012 size_t animation_index = animations_with_same_group_id[j]; | |
| 1013 if (events) { | |
| 1014 AnimationEvent finished_event( | |
| 1015 AnimationEvent::FINISHED, id_, | |
| 1016 animations_[animation_index]->group(), | |
| 1017 animations_[animation_index]->target_property(), | |
| 1018 monotonic_time); | |
| 1019 finished_event.is_impl_only = | |
| 1020 animations_[animation_index]->is_impl_only(); | |
| 1021 if (finished_event.is_impl_only) | |
| 1022 NotifyAnimationFinished(finished_event); | |
| 1023 else | |
| 1024 events->events_.push_back(finished_event); | |
| 1025 } | |
| 1026 animations_[animation_index]->SetRunState( | |
| 1027 Animation::WAITING_FOR_DELETION, monotonic_time); | |
| 1028 } | |
| 1029 marked_animations_for_deletions = true; | |
| 1030 } | |
| 1031 } | |
| 1032 if (marked_animations_for_deletions) | |
| 1033 NotifyObserversAnimationWaitingForDeletion(); | |
| 1034 } | |
| 1035 | |
| 1036 void LayerAnimationController::MarkAbortedAnimationsForDeletion( | |
| 1037 LayerAnimationController* controller_impl) const { | |
| 1038 bool aborted_transform_animation = false; | |
| 1039 auto& animations_impl = controller_impl->animations_; | |
| 1040 for (const auto& animation_impl : animations_impl) { | |
| 1041 // If the animation has been aborted on the main thread, mark it for | |
| 1042 // deletion. | |
| 1043 if (Animation* animation = GetAnimationById(animation_impl->id())) { | |
| 1044 if (animation->run_state() == Animation::ABORTED) { | |
| 1045 animation_impl->SetRunState(Animation::WAITING_FOR_DELETION, | |
| 1046 controller_impl->last_tick_time_); | |
| 1047 animation->SetRunState(Animation::WAITING_FOR_DELETION, | |
| 1048 last_tick_time_); | |
| 1049 if (animation_impl->target_property() == TargetProperty::TRANSFORM) { | |
| 1050 aborted_transform_animation = true; | |
| 1051 } | |
| 1052 } | |
| 1053 } | |
| 1054 } | |
| 1055 | |
| 1056 if (aborted_transform_animation) | |
| 1057 controller_impl->UpdatePotentiallyAnimatingTransform(); | |
| 1058 } | |
| 1059 | |
| 1060 void LayerAnimationController::PurgeAnimationsMarkedForDeletion() { | |
| 1061 animations_.erase( | |
| 1062 std::remove_if(animations_.begin(), animations_.end(), | |
| 1063 [](const std::unique_ptr<Animation>& animation) { | |
| 1064 return animation->run_state() == | |
| 1065 Animation::WAITING_FOR_DELETION; | |
| 1066 }), | |
| 1067 animations_.end()); | |
| 1068 } | |
| 1069 | |
| 1070 void LayerAnimationController::TickAnimations(base::TimeTicks monotonic_time) { | |
| 1071 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 1072 if (animations_[i]->run_state() == Animation::STARTING || | |
| 1073 animations_[i]->run_state() == Animation::RUNNING || | |
| 1074 animations_[i]->run_state() == Animation::PAUSED) { | |
| 1075 if (!animations_[i]->InEffect(monotonic_time)) | |
| 1076 continue; | |
| 1077 | |
| 1078 base::TimeDelta trimmed = | |
| 1079 animations_[i]->TrimTimeToCurrentIteration(monotonic_time); | |
| 1080 | |
| 1081 switch (animations_[i]->target_property()) { | |
| 1082 case TargetProperty::TRANSFORM: { | |
| 1083 const TransformAnimationCurve* transform_animation_curve = | |
| 1084 animations_[i]->curve()->ToTransformAnimationCurve(); | |
| 1085 const gfx::Transform transform = | |
| 1086 transform_animation_curve->GetValue(trimmed); | |
| 1087 NotifyObserversTransformAnimated( | |
| 1088 transform, | |
| 1089 animations_[i]->affects_active_observers(), | |
| 1090 animations_[i]->affects_pending_observers()); | |
| 1091 break; | |
| 1092 } | |
| 1093 | |
| 1094 case TargetProperty::OPACITY: { | |
| 1095 const FloatAnimationCurve* float_animation_curve = | |
| 1096 animations_[i]->curve()->ToFloatAnimationCurve(); | |
| 1097 const float opacity = std::max( | |
| 1098 std::min(float_animation_curve->GetValue(trimmed), 1.0f), 0.f); | |
| 1099 NotifyObserversOpacityAnimated( | |
| 1100 opacity, | |
| 1101 animations_[i]->affects_active_observers(), | |
| 1102 animations_[i]->affects_pending_observers()); | |
| 1103 break; | |
| 1104 } | |
| 1105 | |
| 1106 case TargetProperty::FILTER: { | |
| 1107 const FilterAnimationCurve* filter_animation_curve = | |
| 1108 animations_[i]->curve()->ToFilterAnimationCurve(); | |
| 1109 const FilterOperations filter = | |
| 1110 filter_animation_curve->GetValue(trimmed); | |
| 1111 NotifyObserversFilterAnimated( | |
| 1112 filter, | |
| 1113 animations_[i]->affects_active_observers(), | |
| 1114 animations_[i]->affects_pending_observers()); | |
| 1115 break; | |
| 1116 } | |
| 1117 | |
| 1118 case TargetProperty::BACKGROUND_COLOR: { | |
| 1119 // Not yet implemented. | |
| 1120 break; | |
| 1121 } | |
| 1122 | |
| 1123 case TargetProperty::SCROLL_OFFSET: { | |
| 1124 const ScrollOffsetAnimationCurve* scroll_offset_animation_curve = | |
| 1125 animations_[i]->curve()->ToScrollOffsetAnimationCurve(); | |
| 1126 const gfx::ScrollOffset scroll_offset = | |
| 1127 scroll_offset_animation_curve->GetValue(trimmed); | |
| 1128 NotifyObserversScrollOffsetAnimated( | |
| 1129 scroll_offset, | |
| 1130 animations_[i]->affects_active_observers(), | |
| 1131 animations_[i]->affects_pending_observers()); | |
| 1132 break; | |
| 1133 } | |
| 1134 } | |
| 1135 } | |
| 1136 } | |
| 1137 } | |
| 1138 | |
| 1139 void LayerAnimationController::UpdateActivation(UpdateActivationType type) { | |
| 1140 bool force = type == FORCE_ACTIVATION; | |
| 1141 if (host_) { | |
| 1142 bool was_active = is_active_; | |
| 1143 is_active_ = false; | |
| 1144 for (size_t i = 0; i < animations_.size(); ++i) { | |
| 1145 if (animations_[i]->run_state() != Animation::WAITING_FOR_DELETION) { | |
| 1146 is_active_ = true; | |
| 1147 break; | |
| 1148 } | |
| 1149 } | |
| 1150 | |
| 1151 if (is_active_ && (!was_active || force)) | |
| 1152 host_->DidActivateAnimationController(this); | |
| 1153 else if (!is_active_ && (was_active || force)) | |
| 1154 host_->DidDeactivateAnimationController(this); | |
| 1155 } | |
| 1156 } | |
| 1157 | |
| 1158 void LayerAnimationController::NotifyObserversOpacityAnimated( | |
| 1159 float opacity, | |
| 1160 bool notify_active_observers, | |
| 1161 bool notify_pending_observers) { | |
| 1162 if (!value_observer_) | |
| 1163 return; | |
| 1164 if (notify_active_observers && needs_active_value_observations()) | |
| 1165 value_observer_->OnOpacityAnimated(LayerTreeType::ACTIVE, opacity); | |
| 1166 if (notify_pending_observers && needs_pending_value_observations()) | |
| 1167 value_observer_->OnOpacityAnimated(LayerTreeType::PENDING, opacity); | |
| 1168 } | |
| 1169 | |
| 1170 void LayerAnimationController::NotifyObserversTransformAnimated( | |
| 1171 const gfx::Transform& transform, | |
| 1172 bool notify_active_observers, | |
| 1173 bool notify_pending_observers) { | |
| 1174 if (!value_observer_) | |
| 1175 return; | |
| 1176 if (notify_active_observers && needs_active_value_observations()) | |
| 1177 value_observer_->OnTransformAnimated(LayerTreeType::ACTIVE, transform); | |
| 1178 if (notify_pending_observers && needs_pending_value_observations()) | |
| 1179 value_observer_->OnTransformAnimated(LayerTreeType::PENDING, transform); | |
| 1180 } | |
| 1181 | |
| 1182 void LayerAnimationController::NotifyObserversFilterAnimated( | |
| 1183 const FilterOperations& filters, | |
| 1184 bool notify_active_observers, | |
| 1185 bool notify_pending_observers) { | |
| 1186 if (!value_observer_) | |
| 1187 return; | |
| 1188 if (notify_active_observers && needs_active_value_observations()) | |
| 1189 value_observer_->OnFilterAnimated(LayerTreeType::ACTIVE, filters); | |
| 1190 if (notify_pending_observers && needs_pending_value_observations()) | |
| 1191 value_observer_->OnFilterAnimated(LayerTreeType::PENDING, filters); | |
| 1192 } | |
| 1193 | |
| 1194 void LayerAnimationController::NotifyObserversScrollOffsetAnimated( | |
| 1195 const gfx::ScrollOffset& scroll_offset, | |
| 1196 bool notify_active_observers, | |
| 1197 bool notify_pending_observers) { | |
| 1198 if (!value_observer_) | |
| 1199 return; | |
| 1200 if (notify_active_observers && needs_active_value_observations()) | |
| 1201 value_observer_->OnScrollOffsetAnimated(LayerTreeType::ACTIVE, | |
| 1202 scroll_offset); | |
| 1203 if (notify_pending_observers && needs_pending_value_observations()) | |
| 1204 value_observer_->OnScrollOffsetAnimated(LayerTreeType::PENDING, | |
| 1205 scroll_offset); | |
| 1206 } | |
| 1207 | |
| 1208 void LayerAnimationController::NotifyObserversAnimationWaitingForDeletion() { | |
| 1209 if (value_observer_) | |
| 1210 value_observer_->OnAnimationWaitingForDeletion(); | |
| 1211 } | |
| 1212 | |
| 1213 void LayerAnimationController:: | |
| 1214 NotifyObserversTransformIsPotentiallyAnimatingChanged( | |
| 1215 bool notify_active_observers, | |
| 1216 bool notify_pending_observers) { | |
| 1217 if (!value_observer_) | |
| 1218 return; | |
| 1219 if (notify_active_observers && needs_active_value_observations()) | |
| 1220 value_observer_->OnTransformIsPotentiallyAnimatingChanged( | |
| 1221 LayerTreeType::ACTIVE, | |
| 1222 potentially_animating_transform_for_active_observers_); | |
| 1223 if (notify_pending_observers && needs_pending_value_observations()) | |
| 1224 value_observer_->OnTransformIsPotentiallyAnimatingChanged( | |
| 1225 LayerTreeType::PENDING, | |
| 1226 potentially_animating_transform_for_pending_observers_); | |
| 1227 } | |
| 1228 | |
| 1229 bool LayerAnimationController::HasValueObserver() { | |
| 1230 if (!value_observer_) | |
| 1231 return false; | |
| 1232 return needs_active_value_observations() || | |
| 1233 needs_pending_value_observations(); | |
| 1234 } | |
| 1235 | |
| 1236 bool LayerAnimationController::HasActiveValueObserver() { | |
| 1237 if (!value_observer_) | |
| 1238 return false; | |
| 1239 return needs_active_value_observations(); | |
| 1240 } | |
| 1241 | |
| 1242 } // namespace cc | |
| OLD | NEW |