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