Chromium Code Reviews| Index: cc/animation/element_animations.cc |
| diff --git a/cc/animation/element_animations.cc b/cc/animation/element_animations.cc |
| index be4b9687d99075a6e8b8aa7cc5c3bdb9e74e164b..ddcdd3489b0d25f987f47ee122c1fa22a32f690d 100644 |
| --- a/cc/animation/element_animations.cc |
| +++ b/cc/animation/element_animations.cc |
| @@ -35,7 +35,11 @@ ElementAnimations::ElementAnimations() |
| needs_to_start_animations_(false), |
| scroll_offset_animation_was_interrupted_(false), |
| potentially_animating_transform_for_active_elements_(false), |
| - potentially_animating_transform_for_pending_elements_(false) {} |
| + potentially_animating_transform_for_pending_elements_(false), |
| + currently_running_opacity_animation_for_active_elements_(false), |
| + currently_running_opacity_animation_for_pending_elements_(false), |
| + potentially_animating_opacity_for_active_elements_(false), |
| + potentially_animating_opacity_for_pending_elements_(false) {} |
| ElementAnimations::~ElementAnimations() {} |
| @@ -67,12 +71,18 @@ void ElementAnimations::InitAffectedElementTypes() { |
| void ElementAnimations::ClearAffectedElementTypes() { |
| DCHECK(animation_host_); |
| - if (has_element_in_active_list()) |
| + if (has_element_in_active_list()) { |
| OnTransformIsPotentiallyAnimatingChanged(ElementListType::ACTIVE, false); |
| + OnOpacityIsAnimatingChanged(ElementListType::ACTIVE, |
| + AnimationChangeType::BOTH, false); |
| + } |
| set_has_element_in_active_list(false); |
| - if (has_element_in_pending_list()) |
| + if (has_element_in_pending_list()) { |
| OnTransformIsPotentiallyAnimatingChanged(ElementListType::PENDING, false); |
| + OnOpacityIsAnimatingChanged(ElementListType::PENDING, |
| + AnimationChangeType::BOTH, false); |
| + } |
| set_has_element_in_pending_list(false); |
| animation_host_->DidDeactivateElementAnimations(this); |
| @@ -138,11 +148,15 @@ void ElementAnimations::PushPropertiesTo( |
| void ElementAnimations::AddAnimation(std::unique_ptr<Animation> animation) { |
| bool added_transform_animation = |
| animation->target_property() == TargetProperty::TRANSFORM; |
| + bool added_opacity_animation = |
| + animation->target_property() == TargetProperty::OPACITY; |
| animations_.push_back(std::move(animation)); |
| needs_to_start_animations_ = true; |
| UpdateActivation(NORMAL_ACTIVATION); |
| if (added_transform_animation) |
| UpdatePotentiallyAnimatingTransform(); |
| + if (added_opacity_animation) |
| + UpdateAnimatingOpacity(); |
| } |
| void ElementAnimations::Animate(base::TimeTicks monotonic_time) { |
| @@ -154,6 +168,7 @@ void ElementAnimations::Animate(base::TimeTicks monotonic_time) { |
| StartAnimations(monotonic_time); |
| TickAnimations(monotonic_time); |
| last_tick_time_ = monotonic_time; |
| + UpdateAnimatingOpacity(); |
| } |
| void ElementAnimations::AccumulatePropertyUpdates( |
| @@ -251,11 +266,15 @@ void ElementAnimations::UpdateState(bool start_ready_animations, |
| void ElementAnimations::ActivateAnimations() { |
| bool changed_transform_animation = false; |
| + bool changed_opacity_animation = false; |
| for (size_t i = 0; i < animations_.size(); ++i) { |
| if (animations_[i]->affects_active_elements() != |
| - animations_[i]->affects_pending_elements() && |
| - animations_[i]->target_property() == TargetProperty::TRANSFORM) |
| - changed_transform_animation = true; |
| + animations_[i]->affects_pending_elements()) { |
| + if (animations_[i]->target_property() == TargetProperty::TRANSFORM) |
| + changed_transform_animation = true; |
| + else if (animations_[i]->target_property() == TargetProperty::OPACITY) |
| + changed_opacity_animation = true; |
| + } |
| animations_[i]->set_affects_active_elements( |
| animations_[i]->affects_pending_elements()); |
| } |
| @@ -270,6 +289,8 @@ void ElementAnimations::ActivateAnimations() { |
| UpdateActivation(NORMAL_ACTIVATION); |
| if (changed_transform_animation) |
| UpdatePotentiallyAnimatingTransform(); |
| + if (changed_opacity_animation) |
| + UpdateAnimatingOpacity(); |
| } |
| void ElementAnimations::NotifyAnimationStarted(const AnimationEvent& event) { |
| @@ -326,6 +347,7 @@ void ElementAnimations::NotifyAnimationTakeover(const AnimationEvent& event) { |
| void ElementAnimations::NotifyAnimationAborted(const AnimationEvent& event) { |
| bool aborted_transform_animation = false; |
| + bool aborted_opacity_animation = false; |
| for (size_t i = 0; i < animations_.size(); ++i) { |
| if (animations_[i]->group() == event.group_id && |
| animations_[i]->target_property() == event.target_property) { |
| @@ -335,11 +357,15 @@ void ElementAnimations::NotifyAnimationAborted(const AnimationEvent& event) { |
| event.group_id); |
| if (event.target_property == TargetProperty::TRANSFORM) |
| aborted_transform_animation = true; |
| + else if (event.target_property == TargetProperty::OPACITY) |
| + aborted_opacity_animation = true; |
| break; |
| } |
| } |
| if (aborted_transform_animation) |
| UpdatePotentiallyAnimatingTransform(); |
| + if (aborted_opacity_animation) |
| + UpdateAnimatingOpacity(); |
| } |
| void ElementAnimations::NotifyAnimationPropertyUpdate( |
| @@ -597,6 +623,7 @@ static bool IsCompleted( |
| void ElementAnimations::RemoveAnimationsCompletedOnMainThread( |
| ElementAnimations* element_animations_impl) const { |
| bool removed_transform_animation = false; |
| + bool removed_opacity_animation = false; |
| // Animations removed on the main thread should no longer affect pending |
| // elements, and should stop affecting active elements after the next call |
| // to ActivateAnimations. If already WAITING_FOR_DELETION, they can be removed |
| @@ -607,6 +634,8 @@ void ElementAnimations::RemoveAnimationsCompletedOnMainThread( |
| animation->set_affects_pending_elements(false); |
| if (animation->target_property() == TargetProperty::TRANSFORM) |
| removed_transform_animation = true; |
| + else if (animation->target_property() == TargetProperty::OPACITY) |
| + removed_opacity_animation = true; |
| } |
| } |
| auto affects_active_only_and_is_waiting_for_deletion = |
| @@ -621,6 +650,8 @@ void ElementAnimations::RemoveAnimationsCompletedOnMainThread( |
| if (removed_transform_animation) |
| element_animations_impl->UpdatePotentiallyAnimatingTransform(); |
| + if (removed_opacity_animation) |
| + element_animations_impl->UpdateAnimatingOpacity(); |
| } |
| void ElementAnimations::PushPropertiesToImplThread( |
| @@ -763,17 +794,21 @@ void ElementAnimations::PromoteStartedAnimations(base::TimeTicks monotonic_time, |
| void ElementAnimations::MarkFinishedAnimations(base::TimeTicks monotonic_time) { |
| bool finished_transform_animation = false; |
| + bool finished_opacity_animation = false; |
| for (size_t i = 0; i < animations_.size(); ++i) { |
| if (!animations_[i]->is_finished() && |
| animations_[i]->IsFinishedAt(monotonic_time)) { |
| animations_[i]->SetRunState(Animation::FINISHED, monotonic_time); |
| - if (animations_[i]->target_property() == TargetProperty::TRANSFORM) { |
| + if (animations_[i]->target_property() == TargetProperty::TRANSFORM) |
| finished_transform_animation = true; |
| - } |
| + else if (animations_[i]->target_property() == TargetProperty::OPACITY) |
| + finished_opacity_animation = true; |
| } |
| } |
| if (finished_transform_animation) |
| UpdatePotentiallyAnimatingTransform(); |
| + if (finished_opacity_animation) |
| + UpdateAnimatingOpacity(); |
| } |
| void ElementAnimations::MarkAnimationsForDeletion( |
| @@ -905,6 +940,7 @@ void ElementAnimations::MarkAnimationsForDeletion( |
| void ElementAnimations::MarkAbortedAnimationsForDeletion( |
| ElementAnimations* element_animations_impl) const { |
| bool aborted_transform_animation = false; |
| + bool aborted_opacity_animation = false; |
| auto& animations_impl = element_animations_impl->animations_; |
| for (const auto& animation_impl : animations_impl) { |
| // If the animation has been aborted on the main thread, mark it for |
| @@ -915,15 +951,18 @@ void ElementAnimations::MarkAbortedAnimationsForDeletion( |
| element_animations_impl->last_tick_time_); |
| animation->SetRunState(Animation::WAITING_FOR_DELETION, |
| last_tick_time_); |
| - if (animation_impl->target_property() == TargetProperty::TRANSFORM) { |
| + if (animation_impl->target_property() == TargetProperty::TRANSFORM) |
| aborted_transform_animation = true; |
| - } |
| + else if (animation_impl->target_property() == TargetProperty::OPACITY) |
| + aborted_opacity_animation = true; |
| } |
| } |
| } |
| if (aborted_transform_animation) |
| element_animations_impl->UpdatePotentiallyAnimatingTransform(); |
| + if (aborted_opacity_animation) |
| + element_animations_impl->UpdateAnimatingOpacity(); |
| } |
| void ElementAnimations::PurgeAnimationsMarkedForDeletion() { |
| @@ -1077,6 +1116,53 @@ void ElementAnimations::NotifyClientTransformIsPotentiallyAnimatingChanged( |
| potentially_animating_transform_for_pending_elements_); |
| } |
| +void ElementAnimations::NotifyClientOpacityAnimationChanged( |
| + bool notify_active_elements_about_potential_animation, |
| + bool notify_pending_elements_about_potential_animation, |
| + bool notify_active_elements_about_running_animation, |
| + bool notify_pending_elements_about_running_animation) { |
| + bool notify_active_elements_about_potential_and_running_animation = |
| + notify_active_elements_about_potential_animation && |
| + notify_active_elements_about_running_animation; |
| + bool notify_pending_elements_about_potential_and_running_animation = |
| + notify_pending_elements_about_potential_animation && |
| + notify_pending_elements_about_running_animation; |
| + if (has_element_in_active_list()) { |
| + if (notify_active_elements_about_potential_and_running_animation) { |
| + DCHECK_EQ(potentially_animating_opacity_for_active_elements_, |
| + currently_running_opacity_animation_for_active_elements_); |
| + OnOpacityIsAnimatingChanged( |
| + ElementListType::ACTIVE, AnimationChangeType::BOTH, |
| + potentially_animating_opacity_for_active_elements_); |
| + } else if (notify_active_elements_about_potential_animation) { |
| + OnOpacityIsAnimatingChanged( |
| + ElementListType::ACTIVE, AnimationChangeType::POTENTIAL, |
| + potentially_animating_opacity_for_active_elements_); |
| + } else if (notify_active_elements_about_running_animation) { |
| + OnOpacityIsAnimatingChanged( |
| + ElementListType::ACTIVE, AnimationChangeType::RUNNING, |
| + currently_running_opacity_animation_for_active_elements_); |
| + } |
| + } |
| + if (has_element_in_pending_list()) { |
| + if (notify_pending_elements_about_potential_and_running_animation) { |
| + DCHECK_EQ(potentially_animating_opacity_for_pending_elements_, |
| + currently_running_opacity_animation_for_pending_elements_); |
| + OnOpacityIsAnimatingChanged( |
| + ElementListType::PENDING, AnimationChangeType::BOTH, |
| + potentially_animating_opacity_for_pending_elements_); |
| + } else if (notify_pending_elements_about_potential_animation) { |
| + OnOpacityIsAnimatingChanged( |
| + ElementListType::PENDING, AnimationChangeType::POTENTIAL, |
| + potentially_animating_opacity_for_pending_elements_); |
| + } else if (notify_pending_elements_about_running_animation) { |
| + OnOpacityIsAnimatingChanged( |
| + ElementListType::PENDING, AnimationChangeType::RUNNING, |
| + currently_running_opacity_animation_for_pending_elements_); |
| + } |
| + } |
| +} |
| + |
| void ElementAnimations::UpdatePotentiallyAnimatingTransform() { |
| bool was_potentially_animating_transform_for_active_elements = |
| potentially_animating_transform_for_active_elements_; |
| @@ -1110,6 +1196,65 @@ void ElementAnimations::UpdatePotentiallyAnimatingTransform() { |
| changed_for_active_elements, changed_for_pending_elements); |
| } |
| +void ElementAnimations::UpdateAnimatingOpacity() { |
| + bool was_currently_running_opacity_animation_for_active_elements = |
| + currently_running_opacity_animation_for_active_elements_; |
| + bool was_currently_running_opacity_animation_for_pending_elements = |
| + currently_running_opacity_animation_for_pending_elements_; |
| + bool was_potentially_animating_opacity_for_active_elements = |
| + potentially_animating_opacity_for_active_elements_; |
| + bool was_potentially_animating_opacity_for_pending_elements = |
| + potentially_animating_opacity_for_pending_elements_; |
| + |
| + DCHECK(was_potentially_animating_opacity_for_active_elements || |
| + !was_currently_running_opacity_animation_for_active_elements); |
| + DCHECK(was_potentially_animating_opacity_for_pending_elements || |
| + !was_currently_running_opacity_animation_for_pending_elements); |
| + currently_running_opacity_animation_for_active_elements_ = false; |
| + currently_running_opacity_animation_for_pending_elements_ = false; |
| + potentially_animating_opacity_for_active_elements_ = false; |
| + potentially_animating_opacity_for_pending_elements_ = false; |
| + |
| + for (const auto& animation : animations_) { |
| + if (!animation->is_finished() && |
| + animation->target_property() == TargetProperty::OPACITY) { |
| + potentially_animating_opacity_for_active_elements_ |= |
| + animation->affects_active_elements(); |
| + potentially_animating_opacity_for_pending_elements_ |= |
| + animation->affects_pending_elements(); |
| + currently_running_opacity_animation_for_active_elements_ = |
| + potentially_animating_opacity_for_active_elements_ && |
| + animation->InEffect(last_tick_time_); |
| + currently_running_opacity_animation_for_pending_elements_ = |
| + potentially_animating_opacity_for_pending_elements_ && |
| + animation->InEffect(last_tick_time_); |
| + } |
| + } |
| + |
| + bool potentially_animating_changed_for_active_elements = |
| + was_potentially_animating_opacity_for_active_elements != |
| + potentially_animating_opacity_for_active_elements_; |
| + bool potentially_animating_changed_for_pending_elements = |
| + was_potentially_animating_opacity_for_pending_elements != |
| + potentially_animating_opacity_for_pending_elements_; |
| + bool currently_running_animation_changed_for_active_elements = |
| + was_currently_running_opacity_animation_for_active_elements != |
| + currently_running_opacity_animation_for_active_elements_; |
| + bool currently_running_animation_changed_for_pending_elements = |
| + was_currently_running_opacity_animation_for_pending_elements != |
| + currently_running_opacity_animation_for_pending_elements_; |
| + if (!potentially_animating_changed_for_active_elements && |
| + !potentially_animating_changed_for_pending_elements && |
| + !currently_running_animation_changed_for_active_elements && |
| + !currently_running_animation_changed_for_pending_elements) |
| + return; |
| + NotifyClientOpacityAnimationChanged( |
| + potentially_animating_changed_for_active_elements, |
| + potentially_animating_changed_for_pending_elements, |
| + currently_running_animation_changed_for_active_elements, |
| + currently_running_animation_changed_for_pending_elements); |
| +} |
| + |
| bool ElementAnimations::HasActiveAnimation() const { |
| for (size_t i = 0; i < animations_.size(); ++i) { |
| if (!animations_[i]->is_finished()) |
| @@ -1164,6 +1309,7 @@ void ElementAnimations::PauseAnimation(int animation_id, |
| void ElementAnimations::RemoveAnimation(int animation_id) { |
| bool removed_transform_animation = false; |
| + bool removed_opacity_animation = false; |
| // Since we want to use the animations that we're going to remove, we need to |
| // use a stable_parition here instead of remove_if. Remove_if leaves the |
| // removed items in an unspecified state. |
| @@ -1178,6 +1324,9 @@ void ElementAnimations::RemoveAnimation(int animation_id) { |
| } else if ((*it)->target_property() == TargetProperty::TRANSFORM && |
| !(*it)->is_finished()) { |
| removed_transform_animation = true; |
| + } else if ((*it)->target_property() == TargetProperty::OPACITY && |
| + !(*it)->is_finished()) { |
| + removed_opacity_animation = true; |
| } |
| } |
| @@ -1185,19 +1334,26 @@ void ElementAnimations::RemoveAnimation(int animation_id) { |
| UpdateActivation(NORMAL_ACTIVATION); |
| if (removed_transform_animation) |
| UpdatePotentiallyAnimatingTransform(); |
| + if (removed_opacity_animation) |
| + UpdateAnimatingOpacity(); |
| } |
| void ElementAnimations::AbortAnimation(int animation_id) { |
| bool aborted_transform_animation = false; |
| + bool aborted_opacity_animation = false; |
| if (Animation* animation = GetAnimationById(animation_id)) { |
| if (!animation->is_finished()) { |
| animation->SetRunState(Animation::ABORTED, last_tick_time_); |
| if (animation->target_property() == TargetProperty::TRANSFORM) |
| aborted_transform_animation = true; |
| + else if (animation->target_property() == TargetProperty::OPACITY) |
| + aborted_opacity_animation = true; |
| } |
| } |
| if (aborted_transform_animation) |
| UpdatePotentiallyAnimatingTransform(); |
| + if (aborted_opacity_animation) |
| + UpdateAnimatingOpacity(); |
| } |
| void ElementAnimations::AbortAnimations(TargetProperty::Type target_property, |
| @@ -1206,6 +1362,7 @@ void ElementAnimations::AbortAnimations(TargetProperty::Type target_property, |
| DCHECK(target_property == TargetProperty::SCROLL_OFFSET); |
| bool aborted_transform_animation = false; |
| + bool aborted_opacity_animation = false; |
| for (size_t i = 0; i < animations_.size(); ++i) { |
| if (animations_[i]->target_property() == target_property && |
| !animations_[i]->is_finished()) { |
| @@ -1219,10 +1376,14 @@ void ElementAnimations::AbortAnimations(TargetProperty::Type target_property, |
| } |
| if (target_property == TargetProperty::TRANSFORM) |
| aborted_transform_animation = true; |
| + else if (target_property == TargetProperty::OPACITY) |
| + aborted_opacity_animation = true; |
| } |
| } |
| if (aborted_transform_animation) |
| UpdatePotentiallyAnimatingTransform(); |
| + if (aborted_opacity_animation) |
| + UpdateAnimatingOpacity(); |
| } |
| Animation* ElementAnimations::GetAnimation( |
| @@ -1298,6 +1459,18 @@ void ElementAnimations::OnTransformIsPotentiallyAnimatingChanged( |
| is_animating); |
| } |
| +void ElementAnimations::OnOpacityIsAnimatingChanged( |
| + ElementListType list_type, |
| + AnimationChangeType change_type, |
| + bool is_animating) { |
| + if (!element_id()) |
| + return; |
| + DCHECK(animation_host()); |
| + if (animation_host()->mutator_host_client()) |
| + animation_host()->mutator_host_client()->ElementOpacityIsAnimatingChanged( |
| + element_id(), list_type, change_type, is_animating); |
|
ajuma
2016/05/10 20:46:20
Nit: Use curly braces here (multi-line 'if' statem
jaydasika
2016/05/10 21:26:25
Done.
|
| +} |
| + |
| void ElementAnimations::NotifyPlayersAnimationStarted( |
| base::TimeTicks monotonic_time, |
| TargetProperty::Type target_property, |