| 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 "base/stl_util.h" | 9 #include "base/stl_util.h" |
| 10 #include "cc/animation/animation_delegate.h" | 10 #include "cc/animation/animation_delegate.h" |
| 11 #include "cc/animation/animation_events.h" | 11 #include "cc/animation/animation_events.h" |
| 12 #include "cc/animation/animation_host.h" | 12 #include "cc/animation/animation_host.h" |
| 13 #include "cc/animation/animation_observer.h" |
| 13 #include "cc/animation/animation_timeline.h" | 14 #include "cc/animation/animation_timeline.h" |
| 14 #include "cc/animation/scroll_offset_animation_curve.h" | 15 #include "cc/animation/scroll_offset_animation_curve.h" |
| 16 #include "cc/animation/transform_operations.h" |
| 15 #include "cc/trees/property_animation_state.h" | 17 #include "cc/trees/property_animation_state.h" |
| 16 | 18 |
| 17 namespace cc { | 19 namespace cc { |
| 18 | 20 |
| 19 scoped_refptr<AnimationPlayer> AnimationPlayer::Create(int id) { | 21 scoped_refptr<AnimationPlayer> AnimationPlayer::Create(int id) { |
| 20 return make_scoped_refptr(new AnimationPlayer(id)); | 22 return make_scoped_refptr(new AnimationPlayer(id)); |
| 21 } | 23 } |
| 22 | 24 |
| 23 AnimationPlayer::AnimationPlayer(int id) | 25 AnimationPlayer::AnimationPlayer(int id) |
| 24 : animation_host_(), | 26 : animation_host_(), |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 | 103 |
| 102 UnbindElementAnimations(); | 104 UnbindElementAnimations(); |
| 103 // Destroy ElementAnimations or release it if it's still needed. | 105 // Destroy ElementAnimations or release it if it's still needed. |
| 104 animation_host_->UnregisterPlayerForElement(element_id_, this); | 106 animation_host_->UnregisterPlayerForElement(element_id_, this); |
| 105 } | 107 } |
| 106 | 108 |
| 107 void AnimationPlayer::BindElementAnimations() { | 109 void AnimationPlayer::BindElementAnimations() { |
| 108 DCHECK(!element_animations_); | 110 DCHECK(!element_animations_); |
| 109 element_animations_ = | 111 element_animations_ = |
| 110 animation_host_->GetElementAnimationsForElementId(element_id_); | 112 animation_host_->GetElementAnimationsForElementId(element_id_); |
| 113 observers_.AddObserver(element_animations_.get()); |
| 111 DCHECK(element_animations_); | 114 DCHECK(element_animations_); |
| 112 | 115 |
| 113 if (!animations_.empty()) | 116 if (!animations_.empty()) |
| 114 AnimationAdded(); | 117 AnimationAdded(); |
| 115 | 118 |
| 116 SetNeedsPushProperties(); | 119 SetNeedsPushProperties(); |
| 117 } | 120 } |
| 118 | 121 |
| 119 void AnimationPlayer::UnbindElementAnimations() { | 122 void AnimationPlayer::UnbindElementAnimations() { |
| 120 SetNeedsPushProperties(); | 123 SetNeedsPushProperties(); |
| 124 if (element_animations_) { |
| 125 observers_.RemoveObserver(element_animations_.get()); |
| 126 } |
| 121 element_animations_ = nullptr; | 127 element_animations_ = nullptr; |
| 122 } | 128 } |
| 123 | 129 |
| 124 void AnimationPlayer::AddAnimation(std::unique_ptr<Animation> animation) { | 130 void AnimationPlayer::AddAnimation(std::unique_ptr<Animation> animation) { |
| 125 DCHECK(animation->target_property() != TargetProperty::SCROLL_OFFSET || | 131 DCHECK(animation->target_property() != TargetProperty::SCROLL_OFFSET || |
| 126 (animation_host_ && animation_host_->SupportsScrollAnimations())); | 132 (animation_host_ && animation_host_->SupportsScrollAnimations())); |
| 127 DCHECK(!animation->is_impl_only() || | 133 DCHECK(!animation->is_impl_only() || |
| 128 animation->target_property() == TargetProperty::SCROLL_OFFSET); | 134 animation->target_property() == TargetProperty::SCROLL_OFFSET); |
| 129 | 135 |
| 130 animations_.push_back(std::move(animation)); | 136 animations_.push_back(std::move(animation)); |
| 137 AnimationAdded(); |
| 131 if (element_animations_) { | 138 if (element_animations_) { |
| 132 AnimationAdded(); | |
| 133 SetNeedsPushProperties(); | 139 SetNeedsPushProperties(); |
| 134 } | 140 } |
| 135 } | 141 } |
| 136 | 142 |
| 137 void AnimationPlayer::AnimationAdded() { | 143 void AnimationPlayer::AnimationAdded() { |
| 138 DCHECK(element_animations_); | 144 if (element_animations_) |
| 139 | 145 SetNeedsCommit(); |
| 140 SetNeedsCommit(); | |
| 141 needs_to_start_animations_ = true; | 146 needs_to_start_animations_ = true; |
| 142 | 147 if (element_animations_) { |
| 143 UpdateTickingState(UpdateTickingType::NORMAL); | 148 UpdateTickingState(UpdateTickingType::NORMAL); |
| 144 element_animations_->UpdateClientAnimationState(); | 149 element_animations_->UpdateClientAnimationState(); |
| 150 } |
| 145 } | 151 } |
| 146 | 152 |
| 147 void AnimationPlayer::PauseAnimation(int animation_id, double time_offset) { | 153 void AnimationPlayer::PauseAnimation(int animation_id, double time_offset) { |
| 148 const base::TimeDelta time_delta = base::TimeDelta::FromSecondsD(time_offset); | 154 const base::TimeDelta time_delta = base::TimeDelta::FromSecondsD(time_offset); |
| 149 | 155 |
| 150 for (size_t i = 0; i < animations_.size(); ++i) { | 156 for (size_t i = 0; i < animations_.size(); ++i) { |
| 151 if (animations_[i]->id() == animation_id) { | 157 if (animations_[i]->id() == animation_id) { |
| 152 animations_[i]->SetRunState(Animation::PAUSED, | 158 animations_[i]->SetRunState(Animation::PAUSED, |
| 153 time_delta + animations_[i]->start_time() + | 159 time_delta + animations_[i]->start_time() + |
| 154 animations_[i]->time_offset()); | 160 animations_[i]->time_offset()); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 // this insures we will never push an animation twice. | 267 // this insures we will never push an animation twice. |
| 262 RemoveAnimationsCompletedOnMainThread(player_impl); | 268 RemoveAnimationsCompletedOnMainThread(player_impl); |
| 263 | 269 |
| 264 PushPropertiesToImplThread(player_impl); | 270 PushPropertiesToImplThread(player_impl); |
| 265 | 271 |
| 266 player_impl->UpdateTickingState(UpdateTickingType::NORMAL); | 272 player_impl->UpdateTickingState(UpdateTickingType::NORMAL); |
| 267 } | 273 } |
| 268 | 274 |
| 269 void AnimationPlayer::Tick(base::TimeTicks monotonic_time) { | 275 void AnimationPlayer::Tick(base::TimeTicks monotonic_time) { |
| 270 DCHECK(!monotonic_time.is_null()); | 276 DCHECK(!monotonic_time.is_null()); |
| 271 DCHECK(element_animations_); | |
| 272 | 277 |
| 273 if (!element_animations_->has_element_in_any_list()) | 278 if (element_animations_ && !element_animations_->has_element_in_any_list()) |
| 274 return; | 279 return; |
| 275 | 280 |
| 276 if (needs_to_start_animations()) | 281 if (needs_to_start_animations()) |
| 277 StartAnimations(monotonic_time); | 282 StartAnimations(monotonic_time); |
| 278 | 283 |
| 279 TickAnimations(monotonic_time); | 284 TickAnimations(monotonic_time); |
| 280 | 285 |
| 281 last_tick_time_ = monotonic_time; | 286 last_tick_time_ = monotonic_time; |
| 282 element_animations_->UpdateClientAnimationState(); | 287 if (element_animations_) |
| 288 element_animations_->UpdateClientAnimationState(); |
| 283 } | 289 } |
| 284 | 290 |
| 285 void AnimationPlayer::UpdateState(bool start_ready_animations, | 291 void AnimationPlayer::UpdateState(bool start_ready_animations, |
| 286 AnimationEvents* events) { | 292 AnimationEvents* events) { |
| 287 DCHECK(element_animations_); | 293 if (element_animations_ && !element_animations_->has_element_in_active_list()) |
| 288 if (!element_animations_->has_element_in_active_list()) | |
| 289 return; | 294 return; |
| 290 | 295 |
| 291 // Animate hasn't been called, this happens if an element has been added | 296 // Animate hasn't been called, this happens if an element has been added |
| 292 // between the Commit and Draw phases. | 297 // between the Commit and Draw phases. |
| 293 if (last_tick_time_ == base::TimeTicks()) | 298 if (last_tick_time_ == base::TimeTicks()) |
| 294 return; | 299 return; |
| 295 | 300 |
| 296 if (start_ready_animations) | 301 if (start_ready_animations) |
| 297 PromoteStartedAnimations(last_tick_time_, events); | 302 PromoteStartedAnimations(last_tick_time_, events); |
| 298 | 303 |
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 716 } | 721 } |
| 717 | 722 |
| 718 // Notify about animations waiting for deletion. | 723 // Notify about animations waiting for deletion. |
| 719 // We need to purge animations marked for deletion, which happens in | 724 // We need to purge animations marked for deletion, which happens in |
| 720 // PushProperties(). | 725 // PushProperties(). |
| 721 if (marked_animations_for_deletions) | 726 if (marked_animations_for_deletions) |
| 722 SetNeedsPushProperties(); | 727 SetNeedsPushProperties(); |
| 723 } | 728 } |
| 724 | 729 |
| 725 void AnimationPlayer::TickAnimations(base::TimeTicks monotonic_time) { | 730 void AnimationPlayer::TickAnimations(base::TimeTicks monotonic_time) { |
| 726 DCHECK(element_animations_); | |
| 727 | |
| 728 for (size_t i = 0; i < animations_.size(); ++i) { | 731 for (size_t i = 0; i < animations_.size(); ++i) { |
| 729 if (animations_[i]->run_state() == Animation::STARTING || | 732 if (animations_[i]->run_state() == Animation::STARTING || |
| 730 animations_[i]->run_state() == Animation::RUNNING || | 733 animations_[i]->run_state() == Animation::RUNNING || |
| 731 animations_[i]->run_state() == Animation::PAUSED) { | 734 animations_[i]->run_state() == Animation::PAUSED) { |
| 732 if (!animations_[i]->InEffect(monotonic_time)) | 735 if (!animations_[i]->InEffect(monotonic_time)) |
| 733 continue; | 736 continue; |
| 734 | 737 |
| 735 base::TimeDelta trimmed = | 738 base::TimeDelta trimmed = |
| 736 animations_[i]->TrimTimeToCurrentIteration(monotonic_time); | 739 animations_[i]->TrimTimeToCurrentIteration(monotonic_time); |
| 737 | 740 |
| 738 switch (animations_[i]->target_property()) { | 741 switch (animations_[i]->target_property()) { |
| 739 case TargetProperty::TRANSFORM: { | 742 case TargetProperty::TRANSFORM: { |
| 740 const TransformAnimationCurve* transform_animation_curve = | 743 const TransformAnimationCurve* transform_animation_curve = |
| 741 animations_[i]->curve()->ToTransformAnimationCurve(); | 744 animations_[i]->curve()->ToTransformAnimationCurve(); |
| 742 const gfx::Transform transform = | 745 const TransformOperations operations = |
| 743 transform_animation_curve->GetValue(trimmed); | 746 transform_animation_curve->GetValue(trimmed); |
| 744 element_animations_->NotifyClientTransformAnimated( | 747 for (auto& observer : observers_) { |
| 745 transform, animations_[i]->affects_active_elements(), | 748 observer.NotifyClientTransformOperationsAnimated( |
| 746 animations_[i]->affects_pending_elements()); | 749 operations, animations_[i]->affects_active_elements(), |
| 750 animations_[i]->affects_pending_elements()); |
| 751 } |
| 747 break; | 752 break; |
| 748 } | 753 } |
| 749 | 754 |
| 750 case TargetProperty::OPACITY: { | 755 case TargetProperty::OPACITY: { |
| 751 const FloatAnimationCurve* float_animation_curve = | 756 const FloatAnimationCurve* float_animation_curve = |
| 752 animations_[i]->curve()->ToFloatAnimationCurve(); | 757 animations_[i]->curve()->ToFloatAnimationCurve(); |
| 753 const float opacity = std::max( | 758 const float opacity = std::max( |
| 754 std::min(float_animation_curve->GetValue(trimmed), 1.0f), 0.f); | 759 std::min(float_animation_curve->GetValue(trimmed), 1.0f), 0.f); |
| 755 element_animations_->NotifyClientOpacityAnimated( | 760 for (auto& observer : observers_) { |
| 756 opacity, animations_[i]->affects_active_elements(), | 761 observer.NotifyClientOpacityAnimated( |
| 757 animations_[i]->affects_pending_elements()); | 762 opacity, animations_[i]->affects_active_elements(), |
| 763 animations_[i]->affects_pending_elements()); |
| 764 } |
| 758 break; | 765 break; |
| 759 } | 766 } |
| 760 | 767 |
| 761 case TargetProperty::FILTER: { | 768 case TargetProperty::FILTER: { |
| 762 const FilterAnimationCurve* filter_animation_curve = | 769 const FilterAnimationCurve* filter_animation_curve = |
| 763 animations_[i]->curve()->ToFilterAnimationCurve(); | 770 animations_[i]->curve()->ToFilterAnimationCurve(); |
| 764 const FilterOperations filter = | 771 const FilterOperations filter = |
| 765 filter_animation_curve->GetValue(trimmed); | 772 filter_animation_curve->GetValue(trimmed); |
| 766 element_animations_->NotifyClientFilterAnimated( | 773 for (auto& observer : observers_) { |
| 767 filter, animations_[i]->affects_active_elements(), | 774 observer.NotifyClientFilterAnimated( |
| 768 animations_[i]->affects_pending_elements()); | 775 filter, animations_[i]->affects_active_elements(), |
| 776 animations_[i]->affects_pending_elements()); |
| 777 } |
| 769 break; | 778 break; |
| 770 } | 779 } |
| 771 | 780 |
| 772 case TargetProperty::BACKGROUND_COLOR: { | 781 case TargetProperty::BACKGROUND_COLOR: { |
| 773 // Not yet implemented. | 782 // Not yet implemented. |
| 774 break; | 783 break; |
| 775 } | 784 } |
| 776 | 785 |
| 777 case TargetProperty::SCROLL_OFFSET: { | 786 case TargetProperty::SCROLL_OFFSET: { |
| 778 const ScrollOffsetAnimationCurve* scroll_offset_animation_curve = | 787 const ScrollOffsetAnimationCurve* scroll_offset_animation_curve = |
| 779 animations_[i]->curve()->ToScrollOffsetAnimationCurve(); | 788 animations_[i]->curve()->ToScrollOffsetAnimationCurve(); |
| 780 const gfx::ScrollOffset scroll_offset = | 789 const gfx::ScrollOffset scroll_offset = |
| 781 scroll_offset_animation_curve->GetValue(trimmed); | 790 scroll_offset_animation_curve->GetValue(trimmed); |
| 782 element_animations_->NotifyClientScrollOffsetAnimated( | 791 for (auto& observer : observers_) { |
| 783 scroll_offset, animations_[i]->affects_active_elements(), | 792 observer.NotifyClientScrollOffsetAnimated( |
| 784 animations_[i]->affects_pending_elements()); | 793 scroll_offset, animations_[i]->affects_active_elements(), |
| 794 animations_[i]->affects_pending_elements()); |
| 795 } |
| 796 break; |
| 797 } |
| 798 |
| 799 case TargetProperty::BOUNDS: { |
| 800 const SizeAnimationCurve* size_animation_curve = |
| 801 animations_[i]->curve()->ToSizeAnimationCurve(); |
| 802 const gfx::SizeF size = size_animation_curve->GetValue(trimmed); |
| 803 for (auto& observer : observers_) { |
| 804 observer.NotifyClientBoundsAnimated( |
| 805 size, animations_[i]->affects_active_elements(), |
| 806 animations_[i]->affects_pending_elements()); |
| 807 } |
| 785 break; | 808 break; |
| 786 } | 809 } |
| 787 } | 810 } |
| 788 } | 811 } |
| 789 } | 812 } |
| 790 | 813 |
| 791 last_tick_time_ = monotonic_time; | 814 last_tick_time_ = monotonic_time; |
| 792 } | 815 } |
| 793 | 816 |
| 794 void AnimationPlayer::MarkFinishedAnimations(base::TimeTicks monotonic_time) { | 817 void AnimationPlayer::MarkFinishedAnimations(base::TimeTicks monotonic_time) { |
| 795 bool animation_finished = false; | 818 bool animation_finished = false; |
| 796 | 819 |
| 797 for (size_t i = 0; i < animations_.size(); ++i) { | 820 for (size_t i = 0; i < animations_.size(); ++i) { |
| 798 if (!animations_[i]->is_finished() && | 821 if (!animations_[i]->is_finished() && |
| 799 animations_[i]->IsFinishedAt(monotonic_time)) { | 822 animations_[i]->IsFinishedAt(monotonic_time)) { |
| 800 animations_[i]->SetRunState(Animation::FINISHED, monotonic_time); | 823 animations_[i]->SetRunState(Animation::FINISHED, monotonic_time); |
| 801 animation_finished = true; | 824 animation_finished = true; |
| 802 SetNeedsPushProperties(); | 825 if (element_animations_) { |
| 826 SetNeedsPushProperties(); |
| 827 } |
| 803 } | 828 } |
| 804 if (!animations_[i]->affects_active_elements() && | 829 if (!animations_[i]->affects_active_elements() && |
| 805 !animations_[i]->affects_pending_elements()) { | 830 !animations_[i]->affects_pending_elements()) { |
| 806 switch (animations_[i]->run_state()) { | 831 switch (animations_[i]->run_state()) { |
| 807 case Animation::WAITING_FOR_TARGET_AVAILABILITY: | 832 case Animation::WAITING_FOR_TARGET_AVAILABILITY: |
| 808 case Animation::STARTING: | 833 case Animation::STARTING: |
| 809 case Animation::RUNNING: | 834 case Animation::RUNNING: |
| 810 case Animation::PAUSED: | 835 case Animation::PAUSED: |
| 811 animations_[i]->SetRunState(Animation::FINISHED, monotonic_time); | 836 animations_[i]->SetRunState(Animation::FINISHED, monotonic_time); |
| 812 animation_finished = true; | 837 animation_finished = true; |
| 813 break; | 838 break; |
| 814 default: | 839 default: |
| 815 break; | 840 break; |
| 816 } | 841 } |
| 817 } | 842 } |
| 818 } | 843 } |
| 819 | 844 |
| 820 DCHECK(element_animations_); | 845 if (element_animations_ && animation_finished) |
| 821 if (animation_finished) | |
| 822 element_animations_->UpdateClientAnimationState(); | 846 element_animations_->UpdateClientAnimationState(); |
| 823 } | 847 } |
| 824 | 848 |
| 825 void AnimationPlayer::ActivateAnimations() { | 849 void AnimationPlayer::ActivateAnimations() { |
| 826 bool animation_activated = false; | 850 bool animation_activated = false; |
| 827 | 851 |
| 828 for (size_t i = 0; i < animations_.size(); ++i) { | 852 for (size_t i = 0; i < animations_.size(); ++i) { |
| 829 if (animations_[i]->affects_active_elements() != | 853 if (animations_[i]->affects_active_elements() != |
| 830 animations_[i]->affects_pending_elements()) { | 854 animations_[i]->affects_pending_elements()) { |
| 831 animation_activated = true; | 855 animation_activated = true; |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1204 animation_player_impl->GetAnimationById(animations_[i]->id()); | 1228 animation_player_impl->GetAnimationById(animations_[i]->id()); |
| 1205 if (current_impl) | 1229 if (current_impl) |
| 1206 animations_[i]->PushPropertiesTo(current_impl); | 1230 animations_[i]->PushPropertiesTo(current_impl); |
| 1207 } | 1231 } |
| 1208 | 1232 |
| 1209 animation_player_impl->scroll_offset_animation_was_interrupted_ = | 1233 animation_player_impl->scroll_offset_animation_was_interrupted_ = |
| 1210 scroll_offset_animation_was_interrupted_; | 1234 scroll_offset_animation_was_interrupted_; |
| 1211 scroll_offset_animation_was_interrupted_ = false; | 1235 scroll_offset_animation_was_interrupted_ = false; |
| 1212 } | 1236 } |
| 1213 | 1237 |
| 1238 void AnimationPlayer::AddObserver(AnimationObserver* observer) { |
| 1239 observers_.AddObserver(observer); |
| 1240 } |
| 1241 |
| 1242 void AnimationPlayer::RemoveObserver(AnimationObserver* observer) { |
| 1243 observers_.RemoveObserver(observer); |
| 1244 } |
| 1245 |
| 1214 } // namespace cc | 1246 } // namespace cc |
| OLD | NEW |