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