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/active_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 "Running", | |
22 "Paused", | |
23 "Finished", | |
24 "Aborted" | |
25 }; | |
26 | |
27 COMPILE_ASSERT(static_cast<int>(cc::ActiveAnimation::RunStateEnumSize) == arrays
ize(s_runStateNames), RunState_names_match_enum); | |
28 | |
29 // This should match the TargetProperty enum. | |
30 static const char* const s_targetPropertyNames[] = { | |
31 "Transform", | |
32 "Opacity" | |
33 }; | |
34 | |
35 COMPILE_ASSERT(static_cast<int>(cc::ActiveAnimation::TargetPropertyEnumSize) ==
arraysize(s_targetPropertyNames), TargetProperty_names_match_enum); | |
36 | |
37 } // namespace | |
38 | |
39 namespace cc { | |
40 | |
41 scoped_ptr<ActiveAnimation> ActiveAnimation::create(scoped_ptr<AnimationCurve> c
urve, int animationId, int groupId, TargetProperty targetProperty) | |
42 { | |
43 return make_scoped_ptr(new ActiveAnimation(curve.Pass(), animationId, groupI
d, targetProperty)); | |
44 } | |
45 | |
46 ActiveAnimation::ActiveAnimation(scoped_ptr<AnimationCurve> curve, int animation
Id, int groupId, TargetProperty targetProperty) | |
47 : m_curve(curve.Pass()) | |
48 , m_id(animationId) | |
49 , m_group(groupId) | |
50 , m_targetProperty(targetProperty) | |
51 , m_runState(WaitingForTargetAvailability) | |
52 , m_iterations(1) | |
53 , m_startTime(0) | |
54 , m_alternatesDirection(false) | |
55 , m_timeOffset(0) | |
56 , m_needsSynchronizedStartTime(false) | |
57 , m_suspended(false) | |
58 , m_pauseTime(0) | |
59 , m_totalPausedTime(0) | |
60 , m_isControllingInstance(false) | |
61 { | |
62 } | |
63 | |
64 ActiveAnimation::~ActiveAnimation() | |
65 { | |
66 if (m_runState == Running || m_runState == Paused) | |
67 setRunState(Aborted, 0); | |
68 } | |
69 | |
70 void ActiveAnimation::setRunState(RunState runState, double monotonicTime) | |
71 { | |
72 if (m_suspended) | |
73 return; | |
74 | |
75 char nameBuffer[256]; | |
76 base::snprintf(nameBuffer, sizeof(nameBuffer), "%s-%d%s", s_targetPropertyNa
mes[m_targetProperty], m_group, m_isControllingInstance ? "(impl)" : ""); | |
77 | |
78 bool isWaitingToStart = m_runState == WaitingForNextTick | |
79 || m_runState == WaitingForTargetAvailability | |
80 || m_runState == WaitingForStartTime; | |
81 | |
82 if (isWaitingToStart && runState == Running) | |
83 TRACE_EVENT_ASYNC_BEGIN1("cc", "ActiveAnimation", this, "Name", TRACE_ST
R_COPY(nameBuffer)); | |
84 | |
85 bool wasFinished = isFinished(); | |
86 | |
87 const char* oldRunStateName = s_runStateNames[m_runState]; | |
88 | |
89 if (runState == Running && m_runState == Paused) | |
90 m_totalPausedTime += monotonicTime - m_pauseTime; | |
91 else if (runState == Paused) | |
92 m_pauseTime = monotonicTime; | |
93 m_runState = runState; | |
94 | |
95 const char* newRunStateName = s_runStateNames[runState]; | |
96 | |
97 if (!wasFinished && isFinished()) | |
98 TRACE_EVENT_ASYNC_END0("cc", "ActiveAnimation", this); | |
99 | |
100 char stateBuffer[256]; | |
101 base::snprintf(stateBuffer, sizeof(stateBuffer), "%s->%s", oldRunStateName,
newRunStateName); | |
102 | |
103 TRACE_EVENT_INSTANT2("cc", "LayerAnimationController::setRunState", "Name",
TRACE_STR_COPY(nameBuffer), "State", TRACE_STR_COPY(stateBuffer)); | |
104 } | |
105 | |
106 void ActiveAnimation::suspend(double monotonicTime) | |
107 { | |
108 setRunState(Paused, monotonicTime); | |
109 m_suspended = true; | |
110 } | |
111 | |
112 void ActiveAnimation::resume(double monotonicTime) | |
113 { | |
114 m_suspended = false; | |
115 setRunState(Running, monotonicTime); | |
116 } | |
117 | |
118 bool ActiveAnimation::isFinishedAt(double monotonicTime) const | |
119 { | |
120 if (isFinished()) | |
121 return true; | |
122 | |
123 if (m_needsSynchronizedStartTime) | |
124 return false; | |
125 | |
126 return m_runState == Running | |
127 && m_iterations >= 0 | |
128 && m_iterations * m_curve->duration() <= monotonicTime - startTime() - m
_totalPausedTime; | |
129 } | |
130 | |
131 double ActiveAnimation::trimTimeToCurrentIteration(double monotonicTime) const | |
132 { | |
133 double trimmed = monotonicTime + m_timeOffset; | |
134 | |
135 // If we're paused, time is 'stuck' at the pause time. | |
136 if (m_runState == Paused) | |
137 trimmed = m_pauseTime; | |
138 | |
139 // Returned time should always be relative to the start time and should subt
ract | |
140 // all time spent paused. | |
141 trimmed -= m_startTime + m_totalPausedTime; | |
142 | |
143 // Zero is always the start of the animation. | |
144 if (trimmed <= 0) | |
145 return 0; | |
146 | |
147 // Always return zero if we have no iterations. | |
148 if (!m_iterations) | |
149 return 0; | |
150 | |
151 // Don't attempt to trim if we have no duration. | |
152 if (m_curve->duration() <= 0) | |
153 return 0; | |
154 | |
155 // If less than an iteration duration, just return trimmed. | |
156 if (trimmed < m_curve->duration()) | |
157 return trimmed; | |
158 | |
159 // If greater than or equal to the total duration, return iteration duration
. | |
160 if (m_iterations >= 0 && trimmed >= m_curve->duration() * m_iterations) { | |
161 if (m_alternatesDirection && !(m_iterations % 2)) | |
162 return 0; | |
163 return m_curve->duration(); | |
164 } | |
165 | |
166 // We need to know the current iteration if we're alternating. | |
167 int iteration = static_cast<int>(trimmed / m_curve->duration()); | |
168 | |
169 // Calculate x where trimmed = x + n * m_curve->duration() for some positive
integer n. | |
170 trimmed = fmod(trimmed, m_curve->duration()); | |
171 | |
172 // If we're alternating and on an odd iteration, reverse the direction. | |
173 if (m_alternatesDirection && iteration % 2 == 1) | |
174 return m_curve->duration() - trimmed; | |
175 | |
176 return trimmed; | |
177 } | |
178 | |
179 scoped_ptr<ActiveAnimation> ActiveAnimation::clone(InstanceType instanceType) co
nst | |
180 { | |
181 return cloneAndInitialize(instanceType, m_runState, m_startTime); | |
182 } | |
183 | |
184 scoped_ptr<ActiveAnimation> ActiveAnimation::cloneAndInitialize(InstanceType ins
tanceType, RunState initialRunState, double startTime) const | |
185 { | |
186 scoped_ptr<ActiveAnimation> toReturn(new ActiveAnimation(m_curve->clone(), m
_id, m_group, m_targetProperty)); | |
187 toReturn->m_runState = initialRunState; | |
188 toReturn->m_iterations = m_iterations; | |
189 toReturn->m_startTime = startTime; | |
190 toReturn->m_pauseTime = m_pauseTime; | |
191 toReturn->m_totalPausedTime = m_totalPausedTime; | |
192 toReturn->m_timeOffset = m_timeOffset; | |
193 toReturn->m_alternatesDirection = m_alternatesDirection; | |
194 toReturn->m_isControllingInstance = instanceType == ControllingInstance; | |
195 return toReturn.Pass(); | |
196 } | |
197 | |
198 void ActiveAnimation::pushPropertiesTo(ActiveAnimation* other) const | |
199 { | |
200 // Currently, we only push changes due to pausing and resuming animations on
the main thread. | |
201 if (m_runState == ActiveAnimation::Paused || other->m_runState == ActiveAnim
ation::Paused) { | |
202 other->m_runState = m_runState; | |
203 other->m_pauseTime = m_pauseTime; | |
204 other->m_totalPausedTime = m_totalPausedTime; | |
205 } | |
206 } | |
207 | |
208 } // namespace cc | |
OLD | NEW |