Fix a type mismatch on Windows caused by r201738.
[chromium-blink-merge.git] / cc / animation / animation.cc
blobe51f7171d847797960729117b0fc336b6efc8a7a
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.
5 #include "cc/animation/animation.h"
7 #include <cmath>
9 #include "base/debug/trace_event.h"
10 #include "base/string_util.h"
11 #include "cc/animation/animation_curve.h"
13 namespace {
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"
28 COMPILE_ASSERT(static_cast<int>(cc::Animation::RunStateEnumSize) ==
29 arraysize(s_runStateNames),
30 RunState_names_match_enum);
32 // This should match the TargetProperty enum.
33 static const char* const s_targetPropertyNames[] = {
34 "Transform",
35 "Opacity"
38 COMPILE_ASSERT(static_cast<int>(cc::Animation::TargetPropertyEnumSize) ==
39 arraysize(s_targetPropertyNames),
40 TargetProperty_names_match_enum);
42 } // namespace
44 namespace cc {
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)); }
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 received_finished_event_(false),
71 suspended_(false),
72 pause_time_(0),
73 total_paused_time_(0),
74 is_controlling_instance_(false),
75 is_impl_only_(false) {}
77 Animation::~Animation() {
78 if (run_state_ == Running || run_state_ == Paused)
79 SetRunState(Aborted, 0);
82 void Animation::SetRunState(RunState run_state, double monotonic_time) {
83 if (suspended_)
84 return;
86 char name_buffer[256];
87 base::snprintf(name_buffer,
88 sizeof(name_buffer),
89 "%s-%d%s",
90 s_targetPropertyNames[target_property_],
91 group_,
92 is_controlling_instance_ ? "(impl)" : "");
94 bool is_waiting_to_start = run_state_ == WaitingForNextTick ||
95 run_state_ == WaitingForTargetAvailability ||
96 run_state_ == WaitingForStartTime ||
97 run_state_ == Starting;
99 if (is_waiting_to_start && run_state == Running) {
100 TRACE_EVENT_ASYNC_BEGIN1(
101 "cc", "Animation", this, "Name", TRACE_STR_COPY(name_buffer));
104 bool was_finished = is_finished();
106 const char* old_run_state_name = s_runStateNames[run_state_];
108 if (run_state == Running && run_state_ == Paused)
109 total_paused_time_ += monotonic_time - pause_time_;
110 else if (run_state == Paused)
111 pause_time_ = monotonic_time;
112 run_state_ = run_state;
114 const char* new_run_state_name = s_runStateNames[run_state];
116 if (!was_finished && is_finished())
117 TRACE_EVENT_ASYNC_END0("cc", "Animation", this);
119 char state_buffer[256];
120 base::snprintf(state_buffer,
121 sizeof(state_buffer),
122 "%s->%s",
123 old_run_state_name,
124 new_run_state_name);
126 TRACE_EVENT_INSTANT2("cc",
127 "LayerAnimationController::SetRunState",
128 TRACE_EVENT_SCOPE_THREAD,
129 "Name",
130 TRACE_STR_COPY(name_buffer),
131 "State",
132 TRACE_STR_COPY(state_buffer));
135 void Animation::Suspend(double monotonic_time) {
136 SetRunState(Paused, monotonic_time);
137 suspended_ = true;
140 void Animation::Resume(double monotonic_time) {
141 suspended_ = false;
142 SetRunState(Running, monotonic_time);
145 bool Animation::IsFinishedAt(double monotonic_time) const {
146 if (is_finished())
147 return true;
149 if (needs_synchronized_start_time_)
150 return false;
152 return run_state_ == Running &&
153 iterations_ >= 0 &&
154 iterations_ * curve_->Duration() <= (monotonic_time -
155 start_time() -
156 total_paused_time_);
159 double Animation::TrimTimeToCurrentIteration(double monotonic_time) const {
160 double trimmed = monotonic_time + time_offset_;
162 // If we're paused, time is 'stuck' at the pause time.
163 if (run_state_ == Paused)
164 trimmed = pause_time_;
166 // Returned time should always be relative to the start time and should
167 // subtract all time spent paused.
168 trimmed -= start_time_ + total_paused_time_;
170 // Zero is always the start of the animation.
171 if (trimmed <= 0)
172 return 0;
174 // Always return zero if we have no iterations.
175 if (!iterations_)
176 return 0;
178 // Don't attempt to trim if we have no duration.
179 if (curve_->Duration() <= 0)
180 return 0;
182 // If less than an iteration duration, just return trimmed.
183 if (trimmed < curve_->Duration())
184 return trimmed;
186 // If greater than or equal to the total duration, return iteration duration.
187 if (iterations_ >= 0 && trimmed >= curve_->Duration() * iterations_) {
188 if (alternates_direction_ && !(iterations_ % 2))
189 return 0;
190 return curve_->Duration();
193 // We need to know the current iteration if we're alternating.
194 int iteration = static_cast<int>(trimmed / curve_->Duration());
196 // Calculate x where trimmed = x + n * curve_->Duration() for some positive
197 // integer n.
198 trimmed = fmod(trimmed, curve_->Duration());
200 // If we're alternating and on an odd iteration, reverse the direction.
201 if (alternates_direction_ && iteration % 2 == 1)
202 return curve_->Duration() - trimmed;
204 return trimmed;
207 scoped_ptr<Animation> Animation::Clone(InstanceType instance_type) const {
208 return CloneAndInitialize(instance_type, run_state_, start_time_);
211 scoped_ptr<Animation> Animation::CloneAndInitialize(InstanceType instance_type,
212 RunState initial_run_state,
213 double start_time) const {
214 scoped_ptr<Animation> to_return(
215 new Animation(curve_->Clone(), id_, group_, target_property_));
216 to_return->run_state_ = initial_run_state;
217 to_return->iterations_ = iterations_;
218 to_return->start_time_ = start_time;
219 to_return->pause_time_ = pause_time_;
220 to_return->total_paused_time_ = total_paused_time_;
221 to_return->time_offset_ = time_offset_;
222 to_return->alternates_direction_ = alternates_direction_;
223 to_return->is_controlling_instance_ = instance_type == ControllingInstance;
224 return to_return.Pass();
227 void Animation::PushPropertiesTo(Animation* other) const {
228 // Currently, we only push changes due to pausing and resuming animations on
229 // the main thread.
230 if (run_state_ == Animation::Paused ||
231 other->run_state_ == Animation::Paused) {
232 other->run_state_ = run_state_;
233 other->pause_time_ = pause_time_;
234 other->total_paused_time_ = total_paused_time_;
238 } // namespace cc