OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 "ui/compositor/layer_animation_sequence.h" | 5 #include "ui/compositor/layer_animation_sequence.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <iterator> | 8 #include <iterator> |
9 | 9 |
10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
(...skipping 20 matching lines...) Expand all Loading... |
31 DetachedFromSequence(this, true)); | 31 DetachedFromSequence(this, true)); |
32 } | 32 } |
33 | 33 |
34 void LayerAnimationSequence::Progress(base::TimeDelta elapsed, | 34 void LayerAnimationSequence::Progress(base::TimeDelta elapsed, |
35 LayerAnimationDelegate* delegate) { | 35 LayerAnimationDelegate* delegate) { |
36 bool redraw_required = false; | 36 bool redraw_required = false; |
37 | 37 |
38 if (elements_.empty()) | 38 if (elements_.empty()) |
39 return; | 39 return; |
40 | 40 |
41 if (is_cyclic_ && duration_ > base::TimeDelta()) { | |
42 // If delta = elapsed - last_start_ is huge, we can skip ahead by complete | |
43 // loops to save time. | |
44 base::TimeDelta delta = elapsed - last_start_; | |
45 int64 k = delta.ToInternalValue() / duration_.ToInternalValue() - 1; | |
46 | |
47 last_start_ += base::TimeDelta::FromInternalValue( | |
48 k * duration_.ToInternalValue()); | |
49 } | |
50 | |
51 size_t current_index = last_element_ % elements_.size(); | 41 size_t current_index = last_element_ % elements_.size(); |
| 42 base::TimeDelta element_duration; |
52 while ((is_cyclic_ || last_element_ < elements_.size()) && | 43 while ((is_cyclic_ || last_element_ < elements_.size()) && |
53 (last_start_ + elements_[current_index]->duration() < elapsed)) { | 44 elements_[current_index]->IsFinished(elapsed - last_start_, |
| 45 &element_duration)) { |
54 // Let the element we're passing finish. | 46 // Let the element we're passing finish. |
55 if (elements_[current_index]->Progress(1.0, delegate)) | 47 if (elements_[current_index]->Progress(elapsed - last_start_, delegate)) |
56 redraw_required = true; | 48 redraw_required = true; |
57 last_start_ += elements_[current_index]->duration(); | 49 last_start_ += element_duration; |
58 ++last_element_; | 50 ++last_element_; |
59 current_index = last_element_ % elements_.size(); | 51 current_index = last_element_ % elements_.size(); |
60 } | 52 } |
61 | 53 |
62 if (is_cyclic_ || last_element_ < elements_.size()) { | 54 if (is_cyclic_ || last_element_ < elements_.size()) { |
63 double t = 1.0; | 55 if (elements_[current_index]->Progress(elapsed - last_start_, delegate)) |
64 if (elements_[current_index]->duration() > base::TimeDelta()) { | |
65 t = (elapsed - last_start_).InMillisecondsF() / | |
66 elements_[current_index]->duration().InMillisecondsF(); | |
67 } | |
68 if (elements_[current_index]->Progress(t, delegate)) | |
69 redraw_required = true; | 56 redraw_required = true; |
70 } | 57 } |
71 | 58 |
72 // Since the delegate may be deleted due to the notifications below, it is | 59 // Since the delegate may be deleted due to the notifications below, it is |
73 // important that we schedule a draw before sending them. | 60 // important that we schedule a draw before sending them. |
74 if (redraw_required) | 61 if (redraw_required) |
75 delegate->ScheduleDrawForAnimation(); | 62 delegate->ScheduleDrawForAnimation(); |
76 | 63 |
77 if (!is_cyclic_ && elapsed == duration_) { | 64 if (!is_cyclic_ && last_element_ == elements_.size()) { |
78 last_element_ = 0; | 65 last_element_ = 0; |
79 last_start_ = base::TimeDelta::FromMilliseconds(0); | 66 last_start_ = base::TimeDelta::FromMilliseconds(0); |
80 NotifyEnded(); | 67 NotifyEnded(); |
| 68 } |
| 69 } |
| 70 |
| 71 bool LayerAnimationSequence::IsFinished(base::TimeDelta elapsed) { |
| 72 if (is_cyclic_) |
| 73 return false; |
| 74 |
| 75 if (elements_.empty()) |
| 76 return true; |
| 77 |
| 78 base::TimeDelta current_start = last_start_; |
| 79 size_t current_index = last_element_; |
| 80 base::TimeDelta element_duration; |
| 81 while ((current_index < elements_.size()) && |
| 82 elements_[current_index]->IsFinished(elapsed - current_start, |
| 83 &element_duration)) { |
| 84 current_start += element_duration; |
| 85 ++current_index; |
| 86 } |
| 87 |
| 88 return (current_index == elements_.size()); |
| 89 } |
| 90 |
| 91 void LayerAnimationSequence::ProgressToEnd(LayerAnimationDelegate* delegate) { |
| 92 bool redraw_required = false; |
| 93 |
| 94 if (elements_.empty()) |
| 95 return; |
| 96 |
| 97 size_t current_index = last_element_ % elements_.size(); |
| 98 while (current_index < elements_.size()) { |
| 99 if (elements_[current_index]->ProgressToEnd(delegate)) |
| 100 redraw_required = true; |
| 101 ++current_index; |
| 102 ++last_element_; |
| 103 } |
| 104 |
| 105 if (redraw_required) |
| 106 delegate->ScheduleDrawForAnimation(); |
| 107 |
| 108 if (!is_cyclic_) { |
| 109 last_element_ = 0; |
| 110 last_start_ = base::TimeDelta::FromMilliseconds(0); |
| 111 NotifyEnded(); |
81 } | 112 } |
82 } | 113 } |
83 | 114 |
84 void LayerAnimationSequence::GetTargetValue( | 115 void LayerAnimationSequence::GetTargetValue( |
85 LayerAnimationElement::TargetValue* target) const { | 116 LayerAnimationElement::TargetValue* target) const { |
86 if (is_cyclic_) | 117 if (is_cyclic_) |
87 return; | 118 return; |
88 | 119 |
89 for (size_t i = last_element_; i < elements_.size(); ++i) | 120 for (size_t i = last_element_; i < elements_.size(); ++i) |
90 elements_[i]->GetTargetValue(target); | 121 elements_[i]->GetTargetValue(target); |
91 } | 122 } |
92 | 123 |
93 void LayerAnimationSequence::Abort() { | 124 void LayerAnimationSequence::Abort() { |
94 size_t current_index = last_element_ % elements_.size(); | 125 size_t current_index = last_element_ % elements_.size(); |
95 while (current_index < elements_.size()) { | 126 while (current_index < elements_.size()) { |
96 elements_[current_index]->Abort(); | 127 elements_[current_index]->Abort(); |
97 ++current_index; | 128 ++current_index; |
98 } | 129 } |
99 last_element_ = 0; | 130 last_element_ = 0; |
100 last_start_ = base::TimeDelta::FromMilliseconds(0); | 131 last_start_ = base::TimeDelta::FromMilliseconds(0); |
101 NotifyAborted(); | 132 NotifyAborted(); |
102 } | 133 } |
103 | 134 |
104 void LayerAnimationSequence::AddElement(LayerAnimationElement* element) { | 135 void LayerAnimationSequence::AddElement(LayerAnimationElement* element) { |
105 // Update duration and properties. | |
106 duration_ += element->duration(); | |
107 properties_.insert(element->properties().begin(), | 136 properties_.insert(element->properties().begin(), |
108 element->properties().end()); | 137 element->properties().end()); |
109 elements_.push_back(make_linked_ptr(element)); | 138 elements_.push_back(make_linked_ptr(element)); |
110 } | 139 } |
111 | 140 |
112 bool LayerAnimationSequence::HasCommonProperty( | 141 bool LayerAnimationSequence::HasCommonProperty( |
113 const LayerAnimationElement::AnimatableProperties& other) const { | 142 const LayerAnimationElement::AnimatableProperties& other) const { |
114 LayerAnimationElement::AnimatableProperties intersection; | 143 LayerAnimationElement::AnimatableProperties intersection; |
115 std::insert_iterator<LayerAnimationElement::AnimatableProperties> ii( | 144 std::insert_iterator<LayerAnimationElement::AnimatableProperties> ii( |
116 intersection, intersection.begin()); | 145 intersection, intersection.begin()); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 OnLayerAnimationEnded(this)); | 191 OnLayerAnimationEnded(this)); |
163 } | 192 } |
164 | 193 |
165 void LayerAnimationSequence::NotifyAborted() { | 194 void LayerAnimationSequence::NotifyAborted() { |
166 FOR_EACH_OBSERVER(LayerAnimationObserver, | 195 FOR_EACH_OBSERVER(LayerAnimationObserver, |
167 observers_, | 196 observers_, |
168 OnLayerAnimationAborted(this)); | 197 OnLayerAnimationAborted(this)); |
169 } | 198 } |
170 | 199 |
171 } // namespace ui | 200 } // namespace ui |
OLD | NEW |