| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/animation/animation.h" | 5 #include "cc/animation/animation.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
| 10 #include "base/trace_event/trace_event.h" | 10 #include "base/trace_event/trace_event.h" |
| 11 #include "cc/animation/animation_curve.h" | 11 #include "cc/animation/animation_curve.h" |
| 12 #include "cc/base/time_util.h" | 12 #include "cc/base/time_util.h" |
| 13 | 13 |
| 14 namespace { | 14 namespace { |
| 15 | 15 |
| 16 // This should match the RunState enum. | 16 // This should match the RunState enum. |
| 17 static const char* const s_runStateNames[] = {"WAITING_FOR_TARGET_AVAILABILITY", | 17 static const char* const s_runStateNames[] = { |
| 18 "WAITING_FOR_DELETION", | 18 "WaitingForTargetAvailability", |
| 19 "STARTING", | 19 "WaitingForDeletion", |
| 20 "RUNNING", | 20 "Starting", |
| 21 "PAUSED", | 21 "Running", |
| 22 "FINISHED", | 22 "Paused", |
| 23 "ABORTED"}; | 23 "Finished", |
| 24 "Aborted" |
| 25 }; |
| 24 | 26 |
| 25 static_assert(static_cast<int>(cc::Animation::LAST_RUN_STATE) + 1 == | 27 static_assert(static_cast<int>(cc::Animation::RunStateEnumSize) == |
| 26 arraysize(s_runStateNames), | 28 arraysize(s_runStateNames), |
| 27 "RunStateEnumSize should equal the number of elements in " | 29 "RunStateEnumSize should equal the number of elements in " |
| 28 "s_runStateNames"); | 30 "s_runStateNames"); |
| 29 | 31 |
| 30 // This should match the TargetProperty enum. | 32 // This should match the TargetProperty enum. |
| 31 static const char* const s_targetPropertyNames[] = {"TRANSFORM", | 33 static const char* const s_targetPropertyNames[] = { |
| 32 "OPACITY", | 34 "Transform", |
| 33 "FILTER", | 35 "Opacity", |
| 34 "SCROLL_OFFSET", | 36 "Filter", |
| 35 "BACKGROUND_COLOR"}; | 37 "ScrollOffset", |
| 38 "BackgroundColor" |
| 39 }; |
| 36 | 40 |
| 37 static_assert(static_cast<int>(cc::Animation::LAST_TARGET_PROPERTY) + 1 == | 41 static_assert(static_cast<int>(cc::Animation::TargetPropertyEnumSize) == |
| 38 arraysize(s_targetPropertyNames), | 42 arraysize(s_targetPropertyNames), |
| 39 "TargetPropertyEnumSize should equal the number of elements in " | 43 "TargetPropertyEnumSize should equal the number of elements in " |
| 40 "s_targetPropertyNames"); | 44 "s_targetPropertyNames"); |
| 41 | 45 |
| 42 } // namespace | 46 } // namespace |
| 43 | 47 |
| 44 namespace cc { | 48 namespace cc { |
| 45 | 49 |
| 46 scoped_ptr<Animation> Animation::Create( | 50 scoped_ptr<Animation> Animation::Create( |
| 47 scoped_ptr<AnimationCurve> curve, | 51 scoped_ptr<AnimationCurve> curve, |
| 48 int animation_id, | 52 int animation_id, |
| 49 int group_id, | 53 int group_id, |
| 50 TargetProperty target_property) { | 54 TargetProperty target_property) { |
| 51 return make_scoped_ptr(new Animation(curve.Pass(), | 55 return make_scoped_ptr(new Animation(curve.Pass(), |
| 52 animation_id, | 56 animation_id, |
| 53 group_id, | 57 group_id, |
| 54 target_property)); } | 58 target_property)); } |
| 55 | 59 |
| 56 Animation::Animation(scoped_ptr<AnimationCurve> curve, | 60 Animation::Animation(scoped_ptr<AnimationCurve> curve, |
| 57 int animation_id, | 61 int animation_id, |
| 58 int group_id, | 62 int group_id, |
| 59 TargetProperty target_property) | 63 TargetProperty target_property) |
| 60 : curve_(curve.Pass()), | 64 : curve_(curve.Pass()), |
| 61 id_(animation_id), | 65 id_(animation_id), |
| 62 group_(group_id), | 66 group_(group_id), |
| 63 target_property_(target_property), | 67 target_property_(target_property), |
| 64 run_state_(WAITING_FOR_TARGET_AVAILABILITY), | 68 run_state_(WaitingForTargetAvailability), |
| 65 iterations_(1), | 69 iterations_(1), |
| 66 iteration_start_(0), | 70 iteration_start_(0), |
| 67 direction_(DIRECTION_NORMAL), | 71 direction_(Normal), |
| 68 playback_rate_(1), | 72 playback_rate_(1), |
| 69 fill_mode_(FILL_MODE_BOTH), | 73 fill_mode_(FillModeBoth), |
| 70 needs_synchronized_start_time_(false), | 74 needs_synchronized_start_time_(false), |
| 71 received_finished_event_(false), | 75 received_finished_event_(false), |
| 72 suspended_(false), | 76 suspended_(false), |
| 73 is_controlling_instance_(false), | 77 is_controlling_instance_(false), |
| 74 is_impl_only_(false), | 78 is_impl_only_(false), |
| 75 affects_active_observers_(true), | 79 affects_active_observers_(true), |
| 76 affects_pending_observers_(true) { | 80 affects_pending_observers_(true) { |
| 77 } | 81 } |
| 78 | 82 |
| 79 Animation::~Animation() { | 83 Animation::~Animation() { |
| 80 if (run_state_ == RUNNING || run_state_ == PAUSED) | 84 if (run_state_ == Running || run_state_ == Paused) |
| 81 SetRunState(ABORTED, base::TimeTicks()); | 85 SetRunState(Aborted, base::TimeTicks()); |
| 82 } | 86 } |
| 83 | 87 |
| 84 void Animation::SetRunState(RunState run_state, | 88 void Animation::SetRunState(RunState run_state, |
| 85 base::TimeTicks monotonic_time) { | 89 base::TimeTicks monotonic_time) { |
| 86 if (suspended_) | 90 if (suspended_) |
| 87 return; | 91 return; |
| 88 | 92 |
| 89 char name_buffer[256]; | 93 char name_buffer[256]; |
| 90 base::snprintf(name_buffer, | 94 base::snprintf(name_buffer, |
| 91 sizeof(name_buffer), | 95 sizeof(name_buffer), |
| 92 "%s-%d", | 96 "%s-%d", |
| 93 s_targetPropertyNames[target_property_], | 97 s_targetPropertyNames[target_property_], |
| 94 group_); | 98 group_); |
| 95 | 99 |
| 96 bool is_waiting_to_start = | 100 bool is_waiting_to_start = run_state_ == WaitingForTargetAvailability || |
| 97 run_state_ == WAITING_FOR_TARGET_AVAILABILITY || run_state_ == STARTING; | 101 run_state_ == Starting; |
| 98 | 102 |
| 99 if (is_controlling_instance_ && is_waiting_to_start && run_state == RUNNING) { | 103 if (is_controlling_instance_ && is_waiting_to_start && run_state == Running) { |
| 100 TRACE_EVENT_ASYNC_BEGIN1( | 104 TRACE_EVENT_ASYNC_BEGIN1( |
| 101 "cc", "Animation", this, "Name", TRACE_STR_COPY(name_buffer)); | 105 "cc", "Animation", this, "Name", TRACE_STR_COPY(name_buffer)); |
| 102 } | 106 } |
| 103 | 107 |
| 104 bool was_finished = is_finished(); | 108 bool was_finished = is_finished(); |
| 105 | 109 |
| 106 const char* old_run_state_name = s_runStateNames[run_state_]; | 110 const char* old_run_state_name = s_runStateNames[run_state_]; |
| 107 | 111 |
| 108 if (run_state == RUNNING && run_state_ == PAUSED) | 112 if (run_state == Running && run_state_ == Paused) |
| 109 total_paused_time_ += (monotonic_time - pause_time_); | 113 total_paused_time_ += (monotonic_time - pause_time_); |
| 110 else if (run_state == PAUSED) | 114 else if (run_state == Paused) |
| 111 pause_time_ = monotonic_time; | 115 pause_time_ = monotonic_time; |
| 112 run_state_ = run_state; | 116 run_state_ = run_state; |
| 113 | 117 |
| 114 const char* new_run_state_name = s_runStateNames[run_state]; | 118 const char* new_run_state_name = s_runStateNames[run_state]; |
| 115 | 119 |
| 116 if (is_controlling_instance_ && !was_finished && is_finished()) | 120 if (is_controlling_instance_ && !was_finished && is_finished()) |
| 117 TRACE_EVENT_ASYNC_END0("cc", "Animation", this); | 121 TRACE_EVENT_ASYNC_END0("cc", "Animation", this); |
| 118 | 122 |
| 119 char state_buffer[256]; | 123 char state_buffer[256]; |
| 120 base::snprintf(state_buffer, | 124 base::snprintf(state_buffer, |
| 121 sizeof(state_buffer), | 125 sizeof(state_buffer), |
| 122 "%s->%s", | 126 "%s->%s", |
| 123 old_run_state_name, | 127 old_run_state_name, |
| 124 new_run_state_name); | 128 new_run_state_name); |
| 125 | 129 |
| 126 TRACE_EVENT_INSTANT2("cc", | 130 TRACE_EVENT_INSTANT2("cc", |
| 127 "LayerAnimationController::SetRunState", | 131 "LayerAnimationController::SetRunState", |
| 128 TRACE_EVENT_SCOPE_THREAD, | 132 TRACE_EVENT_SCOPE_THREAD, |
| 129 "Name", | 133 "Name", |
| 130 TRACE_STR_COPY(name_buffer), | 134 TRACE_STR_COPY(name_buffer), |
| 131 "State", | 135 "State", |
| 132 TRACE_STR_COPY(state_buffer)); | 136 TRACE_STR_COPY(state_buffer)); |
| 133 } | 137 } |
| 134 | 138 |
| 135 void Animation::Suspend(base::TimeTicks monotonic_time) { | 139 void Animation::Suspend(base::TimeTicks monotonic_time) { |
| 136 SetRunState(PAUSED, monotonic_time); | 140 SetRunState(Paused, monotonic_time); |
| 137 suspended_ = true; | 141 suspended_ = true; |
| 138 } | 142 } |
| 139 | 143 |
| 140 void Animation::Resume(base::TimeTicks monotonic_time) { | 144 void Animation::Resume(base::TimeTicks monotonic_time) { |
| 141 suspended_ = false; | 145 suspended_ = false; |
| 142 SetRunState(RUNNING, monotonic_time); | 146 SetRunState(Running, monotonic_time); |
| 143 } | 147 } |
| 144 | 148 |
| 145 bool Animation::IsFinishedAt(base::TimeTicks monotonic_time) const { | 149 bool Animation::IsFinishedAt(base::TimeTicks monotonic_time) const { |
| 146 if (is_finished()) | 150 if (is_finished()) |
| 147 return true; | 151 return true; |
| 148 | 152 |
| 149 if (needs_synchronized_start_time_) | 153 if (needs_synchronized_start_time_) |
| 150 return false; | 154 return false; |
| 151 | 155 |
| 152 if (playback_rate_ == 0) | 156 if (playback_rate_ == 0) |
| 153 return false; | 157 return false; |
| 154 | 158 |
| 155 return run_state_ == RUNNING && iterations_ >= 0 && | 159 return run_state_ == Running && iterations_ >= 0 && |
| 156 TimeUtil::Scale(curve_->Duration(), | 160 TimeUtil::Scale(curve_->Duration(), |
| 157 iterations_ / std::abs(playback_rate_)) <= | 161 iterations_ / std::abs(playback_rate_)) <= |
| 158 (monotonic_time + time_offset_ - start_time_ - total_paused_time_); | 162 (monotonic_time + time_offset_ - start_time_ - total_paused_time_); |
| 159 } | 163 } |
| 160 | 164 |
| 161 bool Animation::InEffect(base::TimeTicks monotonic_time) const { | 165 bool Animation::InEffect(base::TimeTicks monotonic_time) const { |
| 162 return ConvertToActiveTime(monotonic_time) >= base::TimeDelta() || | 166 return ConvertToActiveTime(monotonic_time) >= base::TimeDelta() || |
| 163 (fill_mode_ == FILL_MODE_BOTH || fill_mode_ == FILL_MODE_BACKWARDS); | 167 (fill_mode_ == FillModeBoth || fill_mode_ == FillModeBackwards); |
| 164 } | 168 } |
| 165 | 169 |
| 166 base::TimeDelta Animation::ConvertToActiveTime( | 170 base::TimeDelta Animation::ConvertToActiveTime( |
| 167 base::TimeTicks monotonic_time) const { | 171 base::TimeTicks monotonic_time) const { |
| 168 base::TimeTicks trimmed = monotonic_time + time_offset_; | 172 base::TimeTicks trimmed = monotonic_time + time_offset_; |
| 169 | 173 |
| 170 // If we're paused, time is 'stuck' at the pause time. | 174 // If we're paused, time is 'stuck' at the pause time. |
| 171 if (run_state_ == PAUSED) | 175 if (run_state_ == Paused) |
| 172 trimmed = pause_time_; | 176 trimmed = pause_time_; |
| 173 | 177 |
| 174 // Returned time should always be relative to the start time and should | 178 // Returned time should always be relative to the start time and should |
| 175 // subtract all time spent paused. | 179 // subtract all time spent paused. |
| 176 trimmed -= (start_time_ - base::TimeTicks()) + total_paused_time_; | 180 trimmed -= (start_time_ - base::TimeTicks()) + total_paused_time_; |
| 177 | 181 |
| 178 // If we're just starting or we're waiting on receiving a start time, | 182 // If we're just starting or we're waiting on receiving a start time, |
| 179 // time is 'stuck' at the initial state. | 183 // time is 'stuck' at the initial state. |
| 180 if ((run_state_ == STARTING && !has_set_start_time()) || | 184 if ((run_state_ == Starting && !has_set_start_time()) || |
| 181 needs_synchronized_start_time()) | 185 needs_synchronized_start_time()) |
| 182 trimmed = base::TimeTicks() + time_offset_; | 186 trimmed = base::TimeTicks() + time_offset_; |
| 183 | 187 |
| 184 return (trimmed - base::TimeTicks()); | 188 return (trimmed - base::TimeTicks()); |
| 185 } | 189 } |
| 186 | 190 |
| 187 base::TimeDelta Animation::TrimTimeToCurrentIteration( | 191 base::TimeDelta Animation::TrimTimeToCurrentIteration( |
| 188 base::TimeTicks monotonic_time) const { | 192 base::TimeTicks monotonic_time) const { |
| 189 // Check for valid parameters | 193 // Check for valid parameters |
| 190 DCHECK(playback_rate_); | 194 DCHECK(playback_rate_); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 int iteration; | 240 int iteration; |
| 237 if (scaled_active_time <= base::TimeDelta()) | 241 if (scaled_active_time <= base::TimeDelta()) |
| 238 iteration = 0; | 242 iteration = 0; |
| 239 else if (iteration_time == curve_->Duration()) | 243 else if (iteration_time == curve_->Duration()) |
| 240 iteration = ceil(iteration_start_ + iterations_ - 1); | 244 iteration = ceil(iteration_start_ + iterations_ - 1); |
| 241 else | 245 else |
| 242 iteration = static_cast<int>(scaled_active_time / curve_->Duration()); | 246 iteration = static_cast<int>(scaled_active_time / curve_->Duration()); |
| 243 | 247 |
| 244 // Check if we are running the animation in reverse direction for the current | 248 // Check if we are running the animation in reverse direction for the current |
| 245 // iteration | 249 // iteration |
| 246 bool reverse = | 250 bool reverse = (direction_ == Reverse) || |
| 247 (direction_ == DIRECTION_REVERSE) || | 251 (direction_ == Alternate && iteration % 2 == 1) || |
| 248 (direction_ == DIRECTION_ALTERNATE && iteration % 2 == 1) || | 252 (direction_ == AlternateReverse && iteration % 2 == 0); |
| 249 (direction_ == DIRECTION_ALTERNATE_REVERSE && iteration % 2 == 0); | |
| 250 | 253 |
| 251 // If we are running the animation in reverse direction, reverse the result | 254 // If we are running the animation in reverse direction, reverse the result |
| 252 if (reverse) | 255 if (reverse) |
| 253 iteration_time = curve_->Duration() - iteration_time; | 256 iteration_time = curve_->Duration() - iteration_time; |
| 254 | 257 |
| 255 return iteration_time; | 258 return iteration_time; |
| 256 } | 259 } |
| 257 | 260 |
| 258 scoped_ptr<Animation> Animation::CloneAndInitialize( | 261 scoped_ptr<Animation> Animation::CloneAndInitialize( |
| 259 RunState initial_run_state) const { | 262 RunState initial_run_state) const { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 270 to_return->playback_rate_ = playback_rate_; | 273 to_return->playback_rate_ = playback_rate_; |
| 271 to_return->fill_mode_ = fill_mode_; | 274 to_return->fill_mode_ = fill_mode_; |
| 272 DCHECK(!to_return->is_controlling_instance_); | 275 DCHECK(!to_return->is_controlling_instance_); |
| 273 to_return->is_controlling_instance_ = true; | 276 to_return->is_controlling_instance_ = true; |
| 274 return to_return.Pass(); | 277 return to_return.Pass(); |
| 275 } | 278 } |
| 276 | 279 |
| 277 void Animation::PushPropertiesTo(Animation* other) const { | 280 void Animation::PushPropertiesTo(Animation* other) const { |
| 278 // Currently, we only push changes due to pausing and resuming animations on | 281 // Currently, we only push changes due to pausing and resuming animations on |
| 279 // the main thread. | 282 // the main thread. |
| 280 if (run_state_ == Animation::PAUSED || | 283 if (run_state_ == Animation::Paused || |
| 281 other->run_state_ == Animation::PAUSED) { | 284 other->run_state_ == Animation::Paused) { |
| 282 other->run_state_ = run_state_; | 285 other->run_state_ = run_state_; |
| 283 other->pause_time_ = pause_time_; | 286 other->pause_time_ = pause_time_; |
| 284 other->total_paused_time_ = total_paused_time_; | 287 other->total_paused_time_ = total_paused_time_; |
| 285 } | 288 } |
| 286 } | 289 } |
| 287 | 290 |
| 288 } // namespace cc | 291 } // namespace cc |
| OLD | NEW |