OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "cc/animation.h" | |
6 | |
7 #include <cmath> | |
8 | |
9 #include "base/debug/trace_event.h" | |
10 #include "base/string_util.h" | |
11 #include "cc/animation_curve.h" | |
12 | |
13 namespace { | |
14 | |
15 // This should match the RunState enum. | |
16 static const char* const s_runStateNames[] = { | |
17 "WaitingForNextTick", | |
18 "WaitingForTargetAvailability", | |
19 "WaitingForStartTime", | |
20 "WaitingForDeletion", | |
21 "Starting", | |
22 "Running", | |
23 "Paused", | |
24 "Finished", | |
25 "Aborted" | |
26 }; | |
27 | |
28 COMPILE_ASSERT(static_cast<int>(cc::Animation::RunStateEnumSize) == | |
29 arraysize(s_runStateNames), | |
30 RunState_names_match_enum); | |
31 | |
32 // This should match the TargetProperty enum. | |
33 static const char* const s_targetPropertyNames[] = { | |
34 "Transform", | |
35 "Opacity" | |
36 }; | |
37 | |
38 COMPILE_ASSERT(static_cast<int>(cc::Animation::TargetPropertyEnumSize) == | |
39 arraysize(s_targetPropertyNames), | |
40 TargetProperty_names_match_enum); | |
41 | |
42 } // namespace | |
43 | |
44 namespace cc { | |
45 | |
46 scoped_ptr<Animation> Animation::Create( | |
47 scoped_ptr<AnimationCurve> curve, | |
48 int animation_id, | |
49 int group_id, | |
50 TargetProperty target_property) { | |
51 return make_scoped_ptr(new Animation(curve.Pass(), | |
52 animation_id, | |
53 group_id, | |
54 target_property)); } | |
55 | |
56 Animation::Animation(scoped_ptr<AnimationCurve> curve, | |
57 int animation_id, | |
58 int group_id, | |
59 TargetProperty target_property) | |
60 : curve_(curve.Pass()), | |
61 id_(animation_id), | |
62 group_(group_id), | |
63 target_property_(target_property), | |
64 run_state_(WaitingForTargetAvailability), | |
65 iterations_(1), | |
66 start_time_(0), | |
67 alternates_direction_(false), | |
68 time_offset_(0), | |
69 needs_synchronized_start_time_(false), | |
70 suspended_(false), | |
71 pause_time_(0), | |
72 total_paused_time_(0), | |
73 is_controlling_instance_(false), | |
74 is_impl_only_(false) {} | |
75 | |
76 Animation::~Animation() { | |
77 if (run_state_ == Running || run_state_ == Paused) | |
78 SetRunState(Aborted, 0); | |
79 } | |
80 | |
81 void Animation::SetRunState(RunState run_state, double monotonic_time) { | |
82 if (suspended_) | |
83 return; | |
84 | |
85 char nameBuffer[256]; | |
86 base::snprintf(nameBuffer, | |
87 sizeof(nameBuffer), | |
88 "%s-%d%s", | |
89 s_targetPropertyNames[target_property_], | |
90 group_, | |
91 is_controlling_instance_ ? "(impl)" : ""); | |
92 | |
93 bool is_waiting_to_start = run_state_ == WaitingForNextTick || | |
94 run_state_ == WaitingForTargetAvailability || | |
95 run_state_ == WaitingForStartTime || | |
96 run_state_ == Starting; | |
97 | |
98 if (is_waiting_to_start && run_state == Running) { | |
99 TRACE_EVENT_ASYNC_BEGIN1( | |
100 "cc", "Animation", this, "Name", TRACE_STR_COPY(nameBuffer)); | |
101 } | |
102 | |
103 bool was_finished = is_finished(); | |
104 | |
105 const char* old_run_state_name = s_runStateNames[run_state_]; | |
106 | |
107 if (run_state == Running && run_state_ == Paused) | |
108 total_paused_time_ += monotonic_time - pause_time_; | |
109 else if (run_state == Paused) | |
110 pause_time_ = monotonic_time; | |
111 run_state_ = run_state; | |
112 | |
113 const char* new_run_state_name = s_runStateNames[run_state]; | |
114 | |
115 if (!was_finished && is_finished()) | |
116 TRACE_EVENT_ASYNC_END0("cc", "Animation", this); | |
117 | |
118 char stateBuffer[256]; | |
119 base::snprintf(stateBuffer, | |
120 sizeof(stateBuffer), | |
121 "%s->%s", | |
122 old_run_state_name, | |
123 new_run_state_name); | |
124 | |
125 TRACE_EVENT_INSTANT2("cc", | |
126 "LayerAnimationController::setRunState", | |
127 "Name", | |
128 TRACE_STR_COPY(nameBuffer), | |
129 "State", | |
130 TRACE_STR_COPY(stateBuffer)); | |
131 } | |
132 | |
133 void Animation::Suspend(double monotonic_time) { | |
134 SetRunState(Paused, monotonic_time); | |
135 suspended_ = true; | |
136 } | |
137 | |
138 void Animation::Resume(double monotonic_time) { | |
139 suspended_ = false; | |
140 SetRunState(Running, monotonic_time); | |
141 } | |
142 | |
143 bool Animation::IsFinishedAt(double monotonic_time) const { | |
144 if (is_finished()) | |
145 return true; | |
146 | |
147 if (needs_synchronized_start_time_) | |
148 return false; | |
149 | |
150 return run_state_ == Running && | |
151 iterations_ >= 0 && | |
152 iterations_ * curve_->Duration() <= (monotonic_time - | |
153 start_time() - | |
154 total_paused_time_); | |
155 } | |
156 | |
157 double Animation::TrimTimeToCurrentIteration(double monotonic_time) const { | |
158 double trimmed = monotonic_time + time_offset_; | |
159 | |
160 // If we're paused, time is 'stuck' at the pause time. | |
161 if (run_state_ == Paused) | |
162 trimmed = pause_time_; | |
163 | |
164 // Returned time should always be relative to the start time and should | |
165 // subtract all time spent paused. | |
166 trimmed -= start_time_ + total_paused_time_; | |
167 | |
168 // Zero is always the start of the animation. | |
169 if (trimmed <= 0) | |
170 return 0; | |
171 | |
172 // Always return zero if we have no iterations. | |
173 if (!iterations_) | |
174 return 0; | |
175 | |
176 // Don't attempt to trim if we have no duration. | |
177 if (curve_->Duration() <= 0) | |
178 return 0; | |
179 | |
180 // If less than an iteration duration, just return trimmed. | |
181 if (trimmed < curve_->Duration()) | |
182 return trimmed; | |
183 | |
184 // If greater than or equal to the total duration, return iteration duration. | |
185 if (iterations_ >= 0 && trimmed >= curve_->Duration() * iterations_) { | |
186 if (alternates_direction_ && !(iterations_ % 2)) | |
187 return 0; | |
188 return curve_->Duration(); | |
189 } | |
190 | |
191 // We need to know the current iteration if we're alternating. | |
192 int iteration = static_cast<int>(trimmed / curve_->Duration()); | |
193 | |
194 // Calculate x where trimmed = x + n * curve_->Duration() for some positive | |
195 // integer n. | |
196 trimmed = fmod(trimmed, curve_->Duration()); | |
197 | |
198 // If we're alternating and on an odd iteration, reverse the direction. | |
199 if (alternates_direction_ && iteration % 2 == 1) | |
200 return curve_->Duration() - trimmed; | |
201 | |
202 return trimmed; | |
203 } | |
204 | |
205 scoped_ptr<Animation> Animation::Clone(InstanceType instance_type) const { | |
206 return CloneAndInitialize(instance_type, run_state_, start_time_); | |
207 } | |
208 | |
209 scoped_ptr<Animation> Animation::CloneAndInitialize(InstanceType instance_type, | |
210 RunState initial_run_state, | |
211 double start_time) const { | |
212 scoped_ptr<Animation> to_return( | |
213 new Animation(curve_->Clone(), id_, group_, target_property_)); | |
214 to_return->run_state_ = initial_run_state; | |
215 to_return->iterations_ = iterations_; | |
216 to_return->start_time_ = start_time; | |
217 to_return->pause_time_ = pause_time_; | |
218 to_return->total_paused_time_ = total_paused_time_; | |
219 to_return->time_offset_ = time_offset_; | |
220 to_return->alternates_direction_ = alternates_direction_; | |
221 to_return->is_controlling_instance_ = instance_type == ControllingInstance; | |
222 return to_return.Pass(); | |
223 } | |
224 | |
225 void Animation::PushPropertiesTo(Animation* other) const { | |
226 // Currently, we only push changes due to pausing and resuming animations on | |
227 // the main thread. | |
228 if (run_state_ == Animation::Paused || | |
229 other->run_state_ == Animation::Paused) { | |
230 other->run_state_ = run_state_; | |
231 other->pause_time_ = pause_time_; | |
232 other->total_paused_time_ = total_paused_time_; | |
233 } | |
234 } | |
235 | |
236 } // namespace cc | |
OLD | NEW |