OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 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/layer_animation_controller.h" | 5 #include "cc/animation/layer_animation_controller.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "cc/animation/animation.h" | 9 #include "cc/animation/animation.h" |
10 #include "cc/animation/animation_delegate.h" | 10 #include "cc/animation/animation_delegate.h" |
11 #include "cc/animation/animation_registrar.h" | 11 #include "cc/animation/animation_registrar.h" |
12 #include "cc/animation/keyframed_animation_curve.h" | 12 #include "cc/animation/keyframed_animation_curve.h" |
13 #include "cc/animation/layer_animation_value_observer.h" | 13 #include "cc/animation/layer_animation_value_observer.h" |
14 #include "cc/base/scoped_ptr_algorithm.h" | 14 #include "cc/base/scoped_ptr_algorithm.h" |
15 #include "cc/output/filter_operations.h" | 15 #include "cc/output/filter_operations.h" |
16 #include "ui/gfx/box_f.h" | 16 #include "ui/gfx/box_f.h" |
17 #include "ui/gfx/transform.h" | 17 #include "ui/gfx/transform.h" |
18 | 18 |
19 namespace cc { | 19 namespace cc { |
20 | 20 |
21 LayerAnimationController::LayerAnimationController(int id) | 21 LayerAnimationController::LayerAnimationController(int id) |
22 : force_sync_(false), | 22 : registrar_(0), |
23 registrar_(0), | |
24 id_(id), | 23 id_(id), |
25 is_active_(false), | 24 is_active_(false), |
26 last_tick_time_(0), | 25 last_tick_time_(0), |
27 layer_animation_delegate_(NULL) {} | 26 layer_animation_delegate_(NULL) {} |
28 | 27 |
29 LayerAnimationController::~LayerAnimationController() { | 28 LayerAnimationController::~LayerAnimationController() { |
30 if (registrar_) | 29 if (registrar_) |
31 registrar_->UnregisterAnimationController(this); | 30 registrar_->UnregisterAnimationController(this); |
32 } | 31 } |
33 | 32 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 !active_animations_[i]->is_finished()) | 98 !active_animations_[i]->is_finished()) |
100 active_animations_[i]->SetRunState(Animation::Aborted, last_tick_time_); | 99 active_animations_[i]->SetRunState(Animation::Aborted, last_tick_time_); |
101 } | 100 } |
102 } | 101 } |
103 | 102 |
104 // Ensures that the list of active animations on the main thread and the impl | 103 // Ensures that the list of active animations on the main thread and the impl |
105 // thread are kept in sync. | 104 // thread are kept in sync. |
106 void LayerAnimationController::PushAnimationUpdatesTo( | 105 void LayerAnimationController::PushAnimationUpdatesTo( |
107 LayerAnimationController* controller_impl) { | 106 LayerAnimationController* controller_impl) { |
108 DCHECK(this != controller_impl); | 107 DCHECK(this != controller_impl); |
109 if (force_sync_) { | 108 if (!has_any_animation() && !controller_impl->has_any_animation()) |
110 ReplaceImplThreadAnimations(controller_impl); | 109 return; |
111 force_sync_ = false; | 110 PurgeAnimationsMarkedForDeletion(); |
112 } else { | 111 PushNewAnimationsToImplThread(controller_impl); |
113 PurgeAnimationsMarkedForDeletion(); | |
114 PushNewAnimationsToImplThread(controller_impl); | |
115 | 112 |
116 // Remove finished impl side animations only after pushing, | 113 // Remove finished impl side animations only after pushing, |
117 // and only after the animations are deleted on the main thread | 114 // and only after the animations are deleted on the main thread |
118 // this insures we will never push an animation twice. | 115 // this insures we will never push an animation twice. |
119 RemoveAnimationsCompletedOnMainThread(controller_impl); | 116 RemoveAnimationsCompletedOnMainThread(controller_impl); |
120 | 117 |
121 PushPropertiesToImplThread(controller_impl); | 118 PushPropertiesToImplThread(controller_impl); |
122 } | |
123 controller_impl->UpdateActivation(NormalActivation); | 119 controller_impl->UpdateActivation(NormalActivation); |
124 UpdateActivation(NormalActivation); | 120 UpdateActivation(NormalActivation); |
125 } | 121 } |
126 | 122 |
127 void LayerAnimationController::Animate(double monotonic_time) { | 123 void LayerAnimationController::Animate(double monotonic_time) { |
128 if (!HasValueObserver()) | 124 if (!HasValueObserver()) |
129 return; | 125 return; |
130 | 126 |
131 StartAnimationsWaitingForNextTick(monotonic_time); | 127 StartAnimationsWaitingForNextTick(monotonic_time); |
132 StartAnimationsWaitingForStartTime(monotonic_time); | 128 StartAnimationsWaitingForStartTime(monotonic_time); |
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 monotonic_time); | 590 monotonic_time); |
595 } | 591 } |
596 } | 592 } |
597 } | 593 } |
598 } | 594 } |
599 } | 595 } |
600 } | 596 } |
601 | 597 |
602 void LayerAnimationController::MarkAnimationsForDeletion( | 598 void LayerAnimationController::MarkAnimationsForDeletion( |
603 double monotonic_time, AnimationEventsVector* events) { | 599 double monotonic_time, AnimationEventsVector* events) { |
| 600 bool marked_animations_for_deletions = false; |
| 601 |
604 // Non-aborted animations are marked for deletion after a corresponding | 602 // Non-aborted animations are marked for deletion after a corresponding |
605 // AnimationEvent::Finished event is sent or received. This means that if | 603 // AnimationEvent::Finished event is sent or received. This means that if |
606 // we don't have an events vector, we must ensure that non-aborted animations | 604 // we don't have an events vector, we must ensure that non-aborted animations |
607 // have received a finished event before marking them for deletion. | 605 // have received a finished event before marking them for deletion. |
608 for (size_t i = 0; i < active_animations_.size(); i++) { | 606 for (size_t i = 0; i < active_animations_.size(); i++) { |
609 int group_id = active_animations_[i]->group(); | 607 int group_id = active_animations_[i]->group(); |
610 if (active_animations_[i]->run_state() == Animation::Aborted) { | 608 if (active_animations_[i]->run_state() == Animation::Aborted) { |
611 if (events && !active_animations_[i]->is_impl_only()) { | 609 if (events && !active_animations_[i]->is_impl_only()) { |
612 AnimationEvent aborted_event( | 610 AnimationEvent aborted_event( |
613 AnimationEvent::Aborted, | 611 AnimationEvent::Aborted, |
614 id_, | 612 id_, |
615 group_id, | 613 group_id, |
616 active_animations_[i]->target_property(), | 614 active_animations_[i]->target_property(), |
617 monotonic_time); | 615 monotonic_time); |
618 events->push_back(aborted_event); | 616 events->push_back(aborted_event); |
619 } | 617 } |
620 active_animations_[i]->SetRunState(Animation::WaitingForDeletion, | 618 active_animations_[i]->SetRunState(Animation::WaitingForDeletion, |
621 monotonic_time); | 619 monotonic_time); |
| 620 marked_animations_for_deletions = true; |
622 continue; | 621 continue; |
623 } | 622 } |
624 | 623 |
625 bool all_anims_with_same_id_are_finished = false; | 624 bool all_anims_with_same_id_are_finished = false; |
626 | 625 |
627 // Since deleting an animation on the main thread leads to its deletion | 626 // Since deleting an animation on the main thread leads to its deletion |
628 // on the impl thread, we only mark a Finished main thread animation for | 627 // on the impl thread, we only mark a Finished main thread animation for |
629 // deletion once it has received a Finished event from the impl thread. | 628 // deletion once it has received a Finished event from the impl thread. |
630 bool animation_i_will_send_or_has_received_finish_event = | 629 bool animation_i_will_send_or_has_received_finish_event = |
631 events || active_animations_[i]->received_finished_event(); | 630 events || active_animations_[i]->received_finished_event(); |
(...skipping 28 matching lines...) Expand all Loading... |
660 active_animations_[j]->group(), | 659 active_animations_[j]->group(), |
661 active_animations_[j]->target_property(), | 660 active_animations_[j]->target_property(), |
662 monotonic_time); | 661 monotonic_time); |
663 finished_event.is_impl_only = active_animations_[j]->is_impl_only(); | 662 finished_event.is_impl_only = active_animations_[j]->is_impl_only(); |
664 events->push_back(finished_event); | 663 events->push_back(finished_event); |
665 } | 664 } |
666 active_animations_[j]->SetRunState(Animation::WaitingForDeletion, | 665 active_animations_[j]->SetRunState(Animation::WaitingForDeletion, |
667 monotonic_time); | 666 monotonic_time); |
668 } | 667 } |
669 } | 668 } |
| 669 marked_animations_for_deletions = true; |
670 } | 670 } |
671 } | 671 } |
| 672 if (marked_animations_for_deletions) |
| 673 NotifyObserversAnimationWaitingForDeletion(); |
672 } | 674 } |
673 | 675 |
674 static bool IsWaitingForDeletion(Animation* animation) { | 676 static bool IsWaitingForDeletion(Animation* animation) { |
675 return animation->run_state() == Animation::WaitingForDeletion; | 677 return animation->run_state() == Animation::WaitingForDeletion; |
676 } | 678 } |
677 | 679 |
678 void LayerAnimationController::PurgeAnimationsMarkedForDeletion() { | 680 void LayerAnimationController::PurgeAnimationsMarkedForDeletion() { |
679 ScopedPtrVector<Animation>& animations = active_animations_; | 681 ScopedPtrVector<Animation>& animations = active_animations_; |
680 animations.erase(cc::remove_if(&animations, | 682 animations.erase(cc::remove_if(&animations, |
681 animations.begin(), | 683 animations.begin(), |
682 animations.end(), | 684 animations.end(), |
683 IsWaitingForDeletion), | 685 IsWaitingForDeletion), |
684 animations.end()); | 686 animations.end()); |
685 } | 687 } |
686 | 688 |
687 void LayerAnimationController::ReplaceImplThreadAnimations( | |
688 LayerAnimationController* controller_impl) const { | |
689 controller_impl->active_animations_.clear(); | |
690 for (size_t i = 0; i < active_animations_.size(); ++i) { | |
691 scoped_ptr<Animation> to_add; | |
692 if (active_animations_[i]->needs_synchronized_start_time()) { | |
693 // We haven't received an animation started notification yet, so it | |
694 // is important that we add it in a 'waiting' and not 'running' state. | |
695 Animation::RunState initial_run_state = | |
696 Animation::WaitingForTargetAvailability; | |
697 double start_time = 0; | |
698 to_add = active_animations_[i]->CloneAndInitialize( | |
699 initial_run_state, start_time).Pass(); | |
700 } else { | |
701 to_add = active_animations_[i]->Clone().Pass(); | |
702 } | |
703 | |
704 controller_impl->AddAnimation(to_add.Pass()); | |
705 } | |
706 } | |
707 | |
708 void LayerAnimationController::TickAnimations(double monotonic_time) { | 689 void LayerAnimationController::TickAnimations(double monotonic_time) { |
709 for (size_t i = 0; i < active_animations_.size(); ++i) { | 690 for (size_t i = 0; i < active_animations_.size(); ++i) { |
710 if (active_animations_[i]->run_state() == Animation::Starting || | 691 if (active_animations_[i]->run_state() == Animation::Starting || |
711 active_animations_[i]->run_state() == Animation::Running || | 692 active_animations_[i]->run_state() == Animation::Running || |
712 active_animations_[i]->run_state() == Animation::Paused) { | 693 active_animations_[i]->run_state() == Animation::Paused) { |
713 double trimmed = | 694 double trimmed = |
714 active_animations_[i]->TrimTimeToCurrentIteration(monotonic_time); | 695 active_animations_[i]->TrimTimeToCurrentIteration(monotonic_time); |
715 | 696 |
716 switch (active_animations_[i]->target_property()) { | 697 switch (active_animations_[i]->target_property()) { |
717 case Animation::Transform: { | 698 case Animation::Transform: { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
785 OnTransformAnimated(transform)); | 766 OnTransformAnimated(transform)); |
786 } | 767 } |
787 | 768 |
788 void LayerAnimationController::NotifyObserversFilterAnimated( | 769 void LayerAnimationController::NotifyObserversFilterAnimated( |
789 const FilterOperations& filters) { | 770 const FilterOperations& filters) { |
790 FOR_EACH_OBSERVER(LayerAnimationValueObserver, | 771 FOR_EACH_OBSERVER(LayerAnimationValueObserver, |
791 value_observers_, | 772 value_observers_, |
792 OnFilterAnimated(filters)); | 773 OnFilterAnimated(filters)); |
793 } | 774 } |
794 | 775 |
| 776 void LayerAnimationController::NotifyObserversAnimationWaitingForDeletion() { |
| 777 FOR_EACH_OBSERVER(LayerAnimationValueObserver, |
| 778 value_observers_, |
| 779 OnAnimationWaitingForDeletion()); |
| 780 } |
| 781 |
795 bool LayerAnimationController::HasValueObserver() { | 782 bool LayerAnimationController::HasValueObserver() { |
796 if (value_observers_.might_have_observers()) { | 783 if (value_observers_.might_have_observers()) { |
797 ObserverListBase<LayerAnimationValueObserver>::Iterator it( | 784 ObserverListBase<LayerAnimationValueObserver>::Iterator it( |
798 value_observers_); | 785 value_observers_); |
799 return it.GetNext() != NULL; | 786 return it.GetNext() != NULL; |
800 } | 787 } |
801 return false; | 788 return false; |
802 } | 789 } |
803 | 790 |
804 bool LayerAnimationController::HasActiveValueObserver() { | 791 bool LayerAnimationController::HasActiveValueObserver() { |
805 if (value_observers_.might_have_observers()) { | 792 if (value_observers_.might_have_observers()) { |
806 ObserverListBase<LayerAnimationValueObserver>::Iterator it( | 793 ObserverListBase<LayerAnimationValueObserver>::Iterator it( |
807 value_observers_); | 794 value_observers_); |
808 LayerAnimationValueObserver* obs; | 795 LayerAnimationValueObserver* obs; |
809 while ((obs = it.GetNext()) != NULL) | 796 while ((obs = it.GetNext()) != NULL) |
810 if (obs->IsActive()) | 797 if (obs->IsActive()) |
811 return true; | 798 return true; |
812 } | 799 } |
813 return false; | 800 return false; |
814 } | 801 } |
815 | 802 |
816 } // namespace cc | 803 } // namespace cc |
OLD | NEW |