| 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 |