| 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/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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |