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_host.h" | 10 #include "cc/animation/animation_host.h" |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 } | 153 } |
154 } | 154 } |
155 | 155 |
156 if (element_animations_) { | 156 if (element_animations_) { |
157 SetNeedsCommit(); | 157 SetNeedsCommit(); |
158 SetNeedsPushProperties(); | 158 SetNeedsPushProperties(); |
159 } | 159 } |
160 } | 160 } |
161 | 161 |
162 void AnimationPlayer::RemoveAnimation(int animation_id) { | 162 void AnimationPlayer::RemoveAnimation(int animation_id) { |
163 bool removed_transform_animation = false; | 163 TargetProperties properties_animation_removed; |
164 bool removed_opacity_animation = false; | 164 |
165 bool removed_filter_animation = false; | |
166 // Since we want to use the animations that we're going to remove, we need to | 165 // Since we want to use the animations that we're going to remove, we need to |
167 // use a stable_parition here instead of remove_if. Remove_if leaves the | 166 // use a stable_parition here instead of remove_if. Remove_if leaves the |
168 // removed items in an unspecified state. | 167 // removed items in an unspecified state. |
169 auto animations_to_remove = std::stable_partition( | 168 auto animations_to_remove = std::stable_partition( |
170 animations_.begin(), animations_.end(), | 169 animations_.begin(), animations_.end(), |
171 [animation_id](const std::unique_ptr<Animation>& animation) { | 170 [animation_id](const std::unique_ptr<Animation>& animation) { |
172 return animation->id() != animation_id; | 171 return animation->id() != animation_id; |
173 }); | 172 }); |
174 for (auto it = animations_to_remove; it != animations_.end(); ++it) { | 173 for (auto it = animations_to_remove; it != animations_.end(); ++it) { |
175 if ((*it)->target_property() == TargetProperty::SCROLL_OFFSET) { | 174 if ((*it)->target_property() == TargetProperty::SCROLL_OFFSET) { |
176 if (element_animations_) | 175 if (element_animations_) |
177 element_animations_->SetScrollOffsetAnimationWasInterrupted(); | 176 element_animations_->SetScrollOffsetAnimationWasInterrupted(); |
178 } else if ((*it)->target_property() == TargetProperty::TRANSFORM && | 177 } else if (!(*it)->is_finished()) { |
179 !(*it)->is_finished()) { | 178 properties_animation_removed[(*it)->target_property()] = true; |
180 removed_transform_animation = true; | |
181 } else if ((*it)->target_property() == TargetProperty::OPACITY && | |
182 !(*it)->is_finished()) { | |
183 removed_opacity_animation = true; | |
184 } else if ((*it)->target_property() == TargetProperty::FILTER && | |
185 !(*it)->is_finished()) { | |
186 removed_filter_animation = true; | |
187 } | 179 } |
188 } | 180 } |
189 | 181 |
190 animations_.erase(animations_to_remove, animations_.end()); | 182 animations_.erase(animations_to_remove, animations_.end()); |
191 | 183 |
192 if (element_animations_) { | 184 if (element_animations_) { |
193 element_animations_->UpdateActivationNormal(); | 185 element_animations_->UpdateActivationNormal(); |
194 element_animations_->UpdateClientAnimationState(removed_transform_animation, | 186 element_animations_->UpdateClientAnimationState( |
195 removed_opacity_animation, | 187 properties_animation_removed); |
196 removed_filter_animation); | |
197 SetNeedsCommit(); | 188 SetNeedsCommit(); |
198 SetNeedsPushProperties(); | 189 SetNeedsPushProperties(); |
199 } | 190 } |
200 } | 191 } |
201 | 192 |
202 void AnimationPlayer::AbortAnimation(int animation_id) { | 193 void AnimationPlayer::AbortAnimation(int animation_id) { |
203 if (Animation* animation = GetAnimationById(animation_id)) { | 194 if (Animation* animation = GetAnimationById(animation_id)) { |
204 if (!animation->is_finished()) { | 195 if (!animation->is_finished()) { |
205 animation->SetRunState(Animation::ABORTED, last_tick_time_); | 196 animation->SetRunState(Animation::ABORTED, last_tick_time_); |
206 if (element_animations_) | 197 if (element_animations_) |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 animations_[j]->affects_pending_elements(); | 431 animations_[j]->affects_pending_elements(); |
441 } | 432 } |
442 } | 433 } |
443 | 434 |
444 // Check to see if intersection of the list of properties affected by | 435 // Check to see if intersection of the list of properties affected by |
445 // the group and the list of currently blocked properties is null, taking | 436 // the group and the list of currently blocked properties is null, taking |
446 // into account the type(s) of elements affected by the group. In any | 437 // into account the type(s) of elements affected by the group. In any |
447 // case, the group's target properties need to be added to the lists of | 438 // case, the group's target properties need to be added to the lists of |
448 // blocked properties. | 439 // blocked properties. |
449 bool null_intersection = true; | 440 bool null_intersection = true; |
450 static_assert(TargetProperty::FIRST_TARGET_PROPERTY == 0, | |
451 "TargetProperty must be 0-based enum"); | |
452 for (int property = TargetProperty::FIRST_TARGET_PROPERTY; | 441 for (int property = TargetProperty::FIRST_TARGET_PROPERTY; |
453 property <= TargetProperty::LAST_TARGET_PROPERTY; ++property) { | 442 property <= TargetProperty::LAST_TARGET_PROPERTY; ++property) { |
454 if (enqueued_properties[property]) { | 443 if (enqueued_properties[property]) { |
455 if (affects_active_elements) { | 444 if (affects_active_elements) { |
456 if (blocked_properties_for_active_elements[property]) | 445 if (blocked_properties_for_active_elements[property]) |
457 null_intersection = false; | 446 null_intersection = false; |
458 else | 447 else |
459 blocked_properties_for_active_elements[property] = true; | 448 blocked_properties_for_active_elements[property] = true; |
460 } | 449 } |
461 if (affects_pending_elements) { | 450 if (affects_pending_elements) { |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
719 break; | 708 break; |
720 } | 709 } |
721 } | 710 } |
722 } | 711 } |
723 } | 712 } |
724 | 713 |
725 last_tick_time_ = monotonic_time; | 714 last_tick_time_ = monotonic_time; |
726 } | 715 } |
727 | 716 |
728 void AnimationPlayer::MarkFinishedAnimations(base::TimeTicks monotonic_time) { | 717 void AnimationPlayer::MarkFinishedAnimations(base::TimeTicks monotonic_time) { |
729 bool finished_transform_animation = false; | 718 TargetProperties properties_animation_finished; |
730 bool finished_opacity_animation = false; | 719 |
731 bool finished_filter_animation = false; | |
732 for (size_t i = 0; i < animations_.size(); ++i) { | 720 for (size_t i = 0; i < animations_.size(); ++i) { |
733 if (!animations_[i]->is_finished() && | 721 if (!animations_[i]->is_finished() && |
734 animations_[i]->IsFinishedAt(monotonic_time)) { | 722 animations_[i]->IsFinishedAt(monotonic_time)) { |
735 animations_[i]->SetRunState(Animation::FINISHED, monotonic_time); | 723 animations_[i]->SetRunState(Animation::FINISHED, monotonic_time); |
736 if (animations_[i]->target_property() == TargetProperty::TRANSFORM) | 724 properties_animation_finished[animations_[i]->target_property()] = true; |
737 finished_transform_animation = true; | |
738 else if (animations_[i]->target_property() == TargetProperty::OPACITY) | |
739 finished_opacity_animation = true; | |
740 else if (animations_[i]->target_property() == TargetProperty::FILTER) | |
741 finished_filter_animation = true; | |
742 } | 725 } |
743 } | 726 } |
744 | 727 |
745 DCHECK(element_animations_); | 728 DCHECK(element_animations_); |
746 element_animations_->UpdateClientAnimationState(finished_transform_animation, | 729 element_animations_->UpdateClientAnimationState( |
747 finished_opacity_animation, | 730 properties_animation_finished); |
748 finished_filter_animation); | |
749 } | 731 } |
750 | 732 |
751 void AnimationPlayer::ActivateAnimations(bool* changed_transform_animation, | 733 TargetProperties AnimationPlayer::ActivateAnimations() { |
752 bool* changed_opacity_animation, | 734 TargetProperties activated_properties; |
753 bool* changed_filter_animation) { | 735 |
754 for (size_t i = 0; i < animations_.size(); ++i) { | 736 for (size_t i = 0; i < animations_.size(); ++i) { |
755 if (animations_[i]->affects_active_elements() != | 737 if (animations_[i]->affects_active_elements() != |
756 animations_[i]->affects_pending_elements()) { | 738 animations_[i]->affects_pending_elements()) { |
757 if (animations_[i]->target_property() == TargetProperty::TRANSFORM) | 739 activated_properties[animations_[i]->target_property()] = true; |
758 *changed_transform_animation = true; | |
759 else if (animations_[i]->target_property() == TargetProperty::OPACITY) | |
760 *changed_opacity_animation = true; | |
761 else if (animations_[i]->target_property() == TargetProperty::FILTER) | |
762 *changed_filter_animation = true; | |
763 } | 740 } |
764 animations_[i]->set_affects_active_elements( | 741 animations_[i]->set_affects_active_elements( |
765 animations_[i]->affects_pending_elements()); | 742 animations_[i]->affects_pending_elements()); |
766 } | 743 } |
767 auto affects_no_elements = [](const std::unique_ptr<Animation>& animation) { | 744 auto affects_no_elements = [](const std::unique_ptr<Animation>& animation) { |
768 return !animation->affects_active_elements() && | 745 return !animation->affects_active_elements() && |
769 !animation->affects_pending_elements(); | 746 !animation->affects_pending_elements(); |
770 }; | 747 }; |
771 animations_.erase(std::remove_if(animations_.begin(), animations_.end(), | 748 animations_.erase(std::remove_if(animations_.begin(), animations_.end(), |
772 affects_no_elements), | 749 affects_no_elements), |
773 animations_.end()); | 750 animations_.end()); |
| 751 |
| 752 return activated_properties; |
774 } | 753 } |
775 | 754 |
776 bool AnimationPlayer::HasFilterAnimationThatInflatesBounds() const { | 755 bool AnimationPlayer::HasFilterAnimationThatInflatesBounds() const { |
777 for (size_t i = 0; i < animations_.size(); ++i) { | 756 for (size_t i = 0; i < animations_.size(); ++i) { |
778 if (!animations_[i]->is_finished() && | 757 if (!animations_[i]->is_finished() && |
779 animations_[i]->target_property() == TargetProperty::FILTER && | 758 animations_[i]->target_property() == TargetProperty::FILTER && |
780 animations_[i] | 759 animations_[i] |
781 ->curve() | 760 ->curve() |
782 ->ToFilterAnimationCurve() | 761 ->ToFilterAnimationCurve() |
783 ->HasFilterThatMovesPixels()) | 762 ->HasFilterThatMovesPixels()) |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1004 return nullptr; | 983 return nullptr; |
1005 } | 984 } |
1006 | 985 |
1007 Animation* AnimationPlayer::GetAnimationById(int animation_id) const { | 986 Animation* AnimationPlayer::GetAnimationById(int animation_id) const { |
1008 for (size_t i = 0; i < animations_.size(); ++i) | 987 for (size_t i = 0; i < animations_.size(); ++i) |
1009 if (animations_[i]->id() == animation_id) | 988 if (animations_[i]->id() == animation_id) |
1010 return animations_[i].get(); | 989 return animations_[i].get(); |
1011 return nullptr; | 990 return nullptr; |
1012 } | 991 } |
1013 | 992 |
1014 void AnimationPlayer::GetPropertyAnimationStateFor( | 993 void AnimationPlayer::GetPropertyAnimationState( |
1015 TargetProperty::Type property, | 994 PropertyAnimationState* pending_state, |
1016 PropertyAnimationState* state) const { | 995 PropertyAnimationState* active_state) const { |
1017 state->Clear(); | 996 pending_state->Clear(); |
| 997 active_state->Clear(); |
| 998 |
1018 for (const auto& animation : animations_) { | 999 for (const auto& animation : animations_) { |
1019 if (!animation->is_finished() && animation->target_property() == property) { | 1000 if (!animation->is_finished()) { |
1020 state->potentially_animating_for_active_elements |= | 1001 bool in_effect = animation->InEffect(last_tick_time_); |
1021 animation->affects_active_elements(); | 1002 bool active = animation->affects_active_elements(); |
1022 state->potentially_animating_for_pending_elements |= | 1003 bool pending = animation->affects_pending_elements(); |
1023 animation->affects_pending_elements(); | 1004 TargetProperty::Type property = animation->target_property(); |
1024 state->currently_running_for_active_elements |= | 1005 |
1025 animation->affects_active_elements() && | 1006 if (pending) |
1026 animation->InEffect(last_tick_time_); | 1007 pending_state->potentially_animating[property] = true; |
1027 state->currently_running_for_pending_elements |= | 1008 if (pending && in_effect) |
1028 animation->affects_pending_elements() && | 1009 pending_state->currently_running[property] = true; |
1029 animation->InEffect(last_tick_time_); | 1010 |
| 1011 if (active) |
| 1012 active_state->potentially_animating[property] = true; |
| 1013 if (active && in_effect) |
| 1014 active_state->currently_running[property] = true; |
1030 } | 1015 } |
1031 } | 1016 } |
1032 } | 1017 } |
1033 | 1018 |
1034 void AnimationPlayer::MarkAbortedAnimationsForDeletion( | 1019 void AnimationPlayer::MarkAbortedAnimationsForDeletion( |
1035 AnimationPlayer* animation_player_impl) const { | 1020 AnimationPlayer* animation_player_impl) const { |
1036 bool aborted_transform_animation = false; | 1021 TargetProperties properties_animation_aborted; |
1037 bool aborted_opacity_animation = false; | 1022 |
1038 bool aborted_filter_animation = false; | |
1039 auto& animations_impl = animation_player_impl->animations_; | 1023 auto& animations_impl = animation_player_impl->animations_; |
1040 for (const auto& animation_impl : animations_impl) { | 1024 for (const auto& animation_impl : animations_impl) { |
1041 // If the animation has been aborted on the main thread, mark it for | 1025 // If the animation has been aborted on the main thread, mark it for |
1042 // deletion. | 1026 // deletion. |
1043 if (Animation* animation = GetAnimationById(animation_impl->id())) { | 1027 if (Animation* animation = GetAnimationById(animation_impl->id())) { |
1044 if (animation->run_state() == Animation::ABORTED) { | 1028 if (animation->run_state() == Animation::ABORTED) { |
1045 animation_impl->SetRunState(Animation::WAITING_FOR_DELETION, | 1029 animation_impl->SetRunState(Animation::WAITING_FOR_DELETION, |
1046 animation_player_impl->last_tick_time_); | 1030 animation_player_impl->last_tick_time_); |
1047 animation->SetRunState(Animation::WAITING_FOR_DELETION, | 1031 animation->SetRunState(Animation::WAITING_FOR_DELETION, |
1048 last_tick_time_); | 1032 last_tick_time_); |
1049 if (animation_impl->target_property() == TargetProperty::TRANSFORM) | 1033 properties_animation_aborted[animation_impl->target_property()] = true; |
1050 aborted_transform_animation = true; | |
1051 else if (animation_impl->target_property() == TargetProperty::OPACITY) | |
1052 aborted_opacity_animation = true; | |
1053 else if (animation_impl->target_property() == TargetProperty::FILTER) | |
1054 aborted_filter_animation = true; | |
1055 } | 1034 } |
1056 } | 1035 } |
1057 } | 1036 } |
1058 | 1037 |
1059 if (element_animations_) | 1038 if (element_animations_) |
1060 element_animations_->SetNeedsUpdateImplClientState( | 1039 element_animations_->SetNeedsUpdateImplClientState( |
1061 aborted_transform_animation, aborted_opacity_animation, | 1040 properties_animation_aborted); |
1062 aborted_filter_animation); | |
1063 } | 1041 } |
1064 | 1042 |
1065 void AnimationPlayer::PurgeAnimationsMarkedForDeletion() { | 1043 void AnimationPlayer::PurgeAnimationsMarkedForDeletion() { |
1066 animations_.erase( | 1044 animations_.erase( |
1067 std::remove_if(animations_.begin(), animations_.end(), | 1045 std::remove_if(animations_.begin(), animations_.end(), |
1068 [](const std::unique_ptr<Animation>& animation) { | 1046 [](const std::unique_ptr<Animation>& animation) { |
1069 return animation->run_state() == | 1047 return animation->run_state() == |
1070 Animation::WAITING_FOR_DELETION; | 1048 Animation::WAITING_FOR_DELETION; |
1071 }), | 1049 }), |
1072 animations_.end()); | 1050 animations_.end()); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1115 const AnimationPlayer* main_thread_player) { | 1093 const AnimationPlayer* main_thread_player) { |
1116 if (animation->is_impl_only()) { | 1094 if (animation->is_impl_only()) { |
1117 return (animation->run_state() == Animation::WAITING_FOR_DELETION); | 1095 return (animation->run_state() == Animation::WAITING_FOR_DELETION); |
1118 } else { | 1096 } else { |
1119 return !main_thread_player->GetAnimationById(animation->id()); | 1097 return !main_thread_player->GetAnimationById(animation->id()); |
1120 } | 1098 } |
1121 } | 1099 } |
1122 | 1100 |
1123 void AnimationPlayer::RemoveAnimationsCompletedOnMainThread( | 1101 void AnimationPlayer::RemoveAnimationsCompletedOnMainThread( |
1124 AnimationPlayer* animation_player_impl) const { | 1102 AnimationPlayer* animation_player_impl) const { |
1125 bool removed_transform_animation = false; | 1103 TargetProperties properties_animation_completed; |
1126 bool removed_opacity_animation = false; | 1104 |
1127 bool removed_filter_animation = false; | |
1128 // Animations removed on the main thread should no longer affect pending | 1105 // Animations removed on the main thread should no longer affect pending |
1129 // elements, and should stop affecting active elements after the next call | 1106 // elements, and should stop affecting active elements after the next call |
1130 // to ActivateAnimations. If already WAITING_FOR_DELETION, they can be removed | 1107 // to ActivateAnimations. If already WAITING_FOR_DELETION, they can be removed |
1131 // immediately. | 1108 // immediately. |
1132 auto& animations = animation_player_impl->animations_; | 1109 auto& animations = animation_player_impl->animations_; |
1133 for (const auto& animation : animations) { | 1110 for (const auto& animation : animations) { |
1134 if (IsCompleted(animation.get(), this)) { | 1111 if (IsCompleted(animation.get(), this)) { |
1135 animation->set_affects_pending_elements(false); | 1112 animation->set_affects_pending_elements(false); |
1136 if (animation->target_property() == TargetProperty::TRANSFORM) | 1113 properties_animation_completed[animation->target_property()] = true; |
1137 removed_transform_animation = true; | |
1138 else if (animation->target_property() == TargetProperty::OPACITY) | |
1139 removed_opacity_animation = true; | |
1140 else if (animation->target_property() == TargetProperty::FILTER) | |
1141 removed_filter_animation = true; | |
1142 } | 1114 } |
1143 } | 1115 } |
1144 auto affects_active_only_and_is_waiting_for_deletion = | 1116 auto affects_active_only_and_is_waiting_for_deletion = |
1145 [](const std::unique_ptr<Animation>& animation) { | 1117 [](const std::unique_ptr<Animation>& animation) { |
1146 return animation->run_state() == Animation::WAITING_FOR_DELETION && | 1118 return animation->run_state() == Animation::WAITING_FOR_DELETION && |
1147 !animation->affects_pending_elements(); | 1119 !animation->affects_pending_elements(); |
1148 }; | 1120 }; |
1149 animations.erase( | 1121 animations.erase( |
1150 std::remove_if(animations.begin(), animations.end(), | 1122 std::remove_if(animations.begin(), animations.end(), |
1151 affects_active_only_and_is_waiting_for_deletion), | 1123 affects_active_only_and_is_waiting_for_deletion), |
1152 animations.end()); | 1124 animations.end()); |
1153 | 1125 |
1154 if (element_animations_) | 1126 if (element_animations_) |
1155 element_animations_->SetNeedsUpdateImplClientState( | 1127 element_animations_->SetNeedsUpdateImplClientState( |
1156 removed_transform_animation, removed_opacity_animation, | 1128 properties_animation_completed); |
1157 removed_filter_animation); | |
1158 } | 1129 } |
1159 | 1130 |
1160 void AnimationPlayer::PushPropertiesToImplThread( | 1131 void AnimationPlayer::PushPropertiesToImplThread( |
1161 AnimationPlayer* animation_player_impl) { | 1132 AnimationPlayer* animation_player_impl) { |
1162 for (size_t i = 0; i < animations_.size(); ++i) { | 1133 for (size_t i = 0; i < animations_.size(); ++i) { |
1163 Animation* current_impl = | 1134 Animation* current_impl = |
1164 animation_player_impl->GetAnimationById(animations_[i]->id()); | 1135 animation_player_impl->GetAnimationById(animations_[i]->id()); |
1165 if (current_impl) | 1136 if (current_impl) |
1166 animations_[i]->PushPropertiesTo(current_impl); | 1137 animations_[i]->PushPropertiesTo(current_impl); |
1167 } | 1138 } |
1168 } | 1139 } |
1169 | 1140 |
1170 } // namespace cc | 1141 } // namespace cc |
OLD | NEW |