Revert of Enabling audio quality test on mac. (patchset #1 id:1 of https://codereview...
[chromium-blink-merge.git] / cc / animation / keyframed_animation_curve.cc
blobbcf067ebb74b1f79a7416b33fd7f6f9070271f24
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 <algorithm>
7 #include "cc/animation/keyframed_animation_curve.h"
8 #include "ui/gfx/animation/tween.h"
9 #include "ui/gfx/box_f.h"
11 namespace cc {
13 namespace {
15 template <class KeyframeType>
16 void InsertKeyframe(scoped_ptr<KeyframeType> keyframe,
17 ScopedPtrVector<KeyframeType>* keyframes) {
18 // Usually, the keyframes will be added in order, so this loop would be
19 // unnecessary and we should skip it if possible.
20 if (!keyframes->empty() && keyframe->Time() < keyframes->back()->Time()) {
21 for (size_t i = 0; i < keyframes->size(); ++i) {
22 if (keyframe->Time() < keyframes->at(i)->Time()) {
23 keyframes->insert(keyframes->begin() + i, keyframe.Pass());
24 return;
29 keyframes->push_back(keyframe.Pass());
32 template <typename KeyframeType>
33 double TransformedAnimationTime(
34 const ScopedPtrVector<KeyframeType>& keyframes,
35 const scoped_ptr<TimingFunction>& timing_function,
36 double time) {
37 if (timing_function) {
38 double start_time = keyframes.front()->Time();
39 double duration = keyframes.back()->Time() - start_time;
40 double progress = (time - start_time) / duration;
42 time = timing_function->GetValue(progress) * duration + start_time;
45 return time;
48 template <typename KeyframeType>
49 size_t GetActiveKeyframe(const ScopedPtrVector<KeyframeType>& keyframes,
50 double time) {
51 DCHECK_GE(keyframes.size(), 2ul);
52 size_t i = 0;
53 for (; i < keyframes.size() - 2; ++i) { // Last keyframe is never active.
54 if (time < keyframes[i + 1]->Time())
55 break;
58 return i;
61 template <typename KeyframeType>
62 double TransformedKeyframeProgress(
63 const ScopedPtrVector<KeyframeType>& keyframes,
64 double time,
65 size_t i) {
66 double progress = (time - keyframes[i]->Time()) /
67 (keyframes[i + 1]->Time() - keyframes[i]->Time());
69 if (keyframes[i]->timing_function()) {
70 progress = keyframes[i]->timing_function()->GetValue(progress);
73 return progress;
76 } // namespace
78 Keyframe::Keyframe(double time, scoped_ptr<TimingFunction> timing_function)
79 : time_(time),
80 timing_function_(timing_function.Pass()) {}
82 Keyframe::~Keyframe() {}
84 double Keyframe::Time() const {
85 return time_;
88 scoped_ptr<ColorKeyframe> ColorKeyframe::Create(
89 double time,
90 SkColor value,
91 scoped_ptr<TimingFunction> timing_function) {
92 return make_scoped_ptr(
93 new ColorKeyframe(time, value, timing_function.Pass()));
96 ColorKeyframe::ColorKeyframe(double time,
97 SkColor value,
98 scoped_ptr<TimingFunction> timing_function)
99 : Keyframe(time, timing_function.Pass()),
100 value_(value) {}
102 ColorKeyframe::~ColorKeyframe() {}
104 SkColor ColorKeyframe::Value() const { return value_; }
106 scoped_ptr<ColorKeyframe> ColorKeyframe::Clone() const {
107 scoped_ptr<TimingFunction> func;
108 if (timing_function())
109 func = timing_function()->Clone();
110 return ColorKeyframe::Create(Time(), Value(), func.Pass());
113 scoped_ptr<FloatKeyframe> FloatKeyframe::Create(
114 double time,
115 float value,
116 scoped_ptr<TimingFunction> timing_function) {
117 return make_scoped_ptr(
118 new FloatKeyframe(time, value, timing_function.Pass()));
121 FloatKeyframe::FloatKeyframe(double time,
122 float value,
123 scoped_ptr<TimingFunction> timing_function)
124 : Keyframe(time, timing_function.Pass()),
125 value_(value) {}
127 FloatKeyframe::~FloatKeyframe() {}
129 float FloatKeyframe::Value() const {
130 return value_;
133 scoped_ptr<FloatKeyframe> FloatKeyframe::Clone() const {
134 scoped_ptr<TimingFunction> func;
135 if (timing_function())
136 func = timing_function()->Clone();
137 return FloatKeyframe::Create(Time(), Value(), func.Pass());
140 scoped_ptr<TransformKeyframe> TransformKeyframe::Create(
141 double time,
142 const TransformOperations& value,
143 scoped_ptr<TimingFunction> timing_function) {
144 return make_scoped_ptr(
145 new TransformKeyframe(time, value, timing_function.Pass()));
148 TransformKeyframe::TransformKeyframe(double time,
149 const TransformOperations& value,
150 scoped_ptr<TimingFunction> timing_function)
151 : Keyframe(time, timing_function.Pass()),
152 value_(value) {}
154 TransformKeyframe::~TransformKeyframe() {}
156 const TransformOperations& TransformKeyframe::Value() const {
157 return value_;
160 scoped_ptr<TransformKeyframe> TransformKeyframe::Clone() const {
161 scoped_ptr<TimingFunction> func;
162 if (timing_function())
163 func = timing_function()->Clone();
164 return TransformKeyframe::Create(Time(), Value(), func.Pass());
167 scoped_ptr<FilterKeyframe> FilterKeyframe::Create(
168 double time,
169 const FilterOperations& value,
170 scoped_ptr<TimingFunction> timing_function) {
171 return make_scoped_ptr(
172 new FilterKeyframe(time, value, timing_function.Pass()));
175 FilterKeyframe::FilterKeyframe(double time,
176 const FilterOperations& value,
177 scoped_ptr<TimingFunction> timing_function)
178 : Keyframe(time, timing_function.Pass()),
179 value_(value) {}
181 FilterKeyframe::~FilterKeyframe() {}
183 const FilterOperations& FilterKeyframe::Value() const {
184 return value_;
187 scoped_ptr<FilterKeyframe> FilterKeyframe::Clone() const {
188 scoped_ptr<TimingFunction> func;
189 if (timing_function())
190 func = timing_function()->Clone();
191 return FilterKeyframe::Create(Time(), Value(), func.Pass());
194 scoped_ptr<KeyframedColorAnimationCurve> KeyframedColorAnimationCurve::
195 Create() {
196 return make_scoped_ptr(new KeyframedColorAnimationCurve);
199 KeyframedColorAnimationCurve::KeyframedColorAnimationCurve() {}
201 KeyframedColorAnimationCurve::~KeyframedColorAnimationCurve() {}
203 void KeyframedColorAnimationCurve::AddKeyframe(
204 scoped_ptr<ColorKeyframe> keyframe) {
205 InsertKeyframe(keyframe.Pass(), &keyframes_);
208 double KeyframedColorAnimationCurve::Duration() const {
209 return keyframes_.back()->Time() - keyframes_.front()->Time();
212 scoped_ptr<AnimationCurve> KeyframedColorAnimationCurve::Clone() const {
213 scoped_ptr<KeyframedColorAnimationCurve> to_return =
214 KeyframedColorAnimationCurve::Create();
215 for (size_t i = 0; i < keyframes_.size(); ++i)
216 to_return->AddKeyframe(keyframes_[i]->Clone());
218 if (timing_function_)
219 to_return->SetTimingFunction(timing_function_->Clone());
221 return to_return.Pass();
224 SkColor KeyframedColorAnimationCurve::GetValue(double t) const {
225 if (t <= keyframes_.front()->Time())
226 return keyframes_.front()->Value();
228 if (t >= keyframes_.back()->Time())
229 return keyframes_.back()->Value();
231 t = TransformedAnimationTime(keyframes_, timing_function_, t);
232 size_t i = GetActiveKeyframe(keyframes_, t);
233 double progress = TransformedKeyframeProgress(keyframes_, t, i);
235 return gfx::Tween::ColorValueBetween(
236 progress, keyframes_[i]->Value(), keyframes_[i + 1]->Value());
239 // KeyframedFloatAnimationCurve
241 scoped_ptr<KeyframedFloatAnimationCurve> KeyframedFloatAnimationCurve::
242 Create() {
243 return make_scoped_ptr(new KeyframedFloatAnimationCurve);
246 KeyframedFloatAnimationCurve::KeyframedFloatAnimationCurve() {}
248 KeyframedFloatAnimationCurve::~KeyframedFloatAnimationCurve() {}
250 void KeyframedFloatAnimationCurve::AddKeyframe(
251 scoped_ptr<FloatKeyframe> keyframe) {
252 InsertKeyframe(keyframe.Pass(), &keyframes_);
255 double KeyframedFloatAnimationCurve::Duration() const {
256 return keyframes_.back()->Time() - keyframes_.front()->Time();
259 scoped_ptr<AnimationCurve> KeyframedFloatAnimationCurve::Clone() const {
260 scoped_ptr<KeyframedFloatAnimationCurve> to_return =
261 KeyframedFloatAnimationCurve::Create();
262 for (size_t i = 0; i < keyframes_.size(); ++i)
263 to_return->AddKeyframe(keyframes_[i]->Clone());
265 if (timing_function_)
266 to_return->SetTimingFunction(timing_function_->Clone());
268 return to_return.Pass();
271 float KeyframedFloatAnimationCurve::GetValue(double t) const {
272 if (t <= keyframes_.front()->Time())
273 return keyframes_.front()->Value();
275 if (t >= keyframes_.back()->Time())
276 return keyframes_.back()->Value();
278 t = TransformedAnimationTime(keyframes_, timing_function_, t);
279 size_t i = GetActiveKeyframe(keyframes_, t);
280 double progress = TransformedKeyframeProgress(keyframes_, t, i);
282 return keyframes_[i]->Value() +
283 (keyframes_[i+1]->Value() - keyframes_[i]->Value()) * progress;
286 scoped_ptr<KeyframedTransformAnimationCurve> KeyframedTransformAnimationCurve::
287 Create() {
288 return make_scoped_ptr(new KeyframedTransformAnimationCurve);
291 KeyframedTransformAnimationCurve::KeyframedTransformAnimationCurve() {}
293 KeyframedTransformAnimationCurve::~KeyframedTransformAnimationCurve() {}
295 void KeyframedTransformAnimationCurve::AddKeyframe(
296 scoped_ptr<TransformKeyframe> keyframe) {
297 InsertKeyframe(keyframe.Pass(), &keyframes_);
300 double KeyframedTransformAnimationCurve::Duration() const {
301 return keyframes_.back()->Time() - keyframes_.front()->Time();
304 scoped_ptr<AnimationCurve> KeyframedTransformAnimationCurve::Clone() const {
305 scoped_ptr<KeyframedTransformAnimationCurve> to_return =
306 KeyframedTransformAnimationCurve::Create();
307 for (size_t i = 0; i < keyframes_.size(); ++i)
308 to_return->AddKeyframe(keyframes_[i]->Clone());
310 if (timing_function_)
311 to_return->SetTimingFunction(timing_function_->Clone());
313 return to_return.Pass();
316 gfx::Transform KeyframedTransformAnimationCurve::GetValue(double t) const {
317 if (t <= keyframes_.front()->Time())
318 return keyframes_.front()->Value().Apply();
320 if (t >= keyframes_.back()->Time())
321 return keyframes_.back()->Value().Apply();
323 t = TransformedAnimationTime(keyframes_, timing_function_, t);
324 size_t i = GetActiveKeyframe(keyframes_, t);
325 double progress = TransformedKeyframeProgress(keyframes_, t, i);
327 return keyframes_[i + 1]->Value().Blend(keyframes_[i]->Value(), progress);
330 bool KeyframedTransformAnimationCurve::AnimatedBoundsForBox(
331 const gfx::BoxF& box,
332 gfx::BoxF* bounds) const {
333 DCHECK_GE(keyframes_.size(), 2ul);
334 *bounds = gfx::BoxF();
335 for (size_t i = 0; i < keyframes_.size() - 1; ++i) {
336 gfx::BoxF bounds_for_step;
337 float min_progress = 0.0;
338 float max_progress = 1.0;
339 if (keyframes_[i]->timing_function())
340 keyframes_[i]->timing_function()->Range(&min_progress, &max_progress);
341 if (!keyframes_[i+1]->Value().BlendedBoundsForBox(box,
342 keyframes_[i]->Value(),
343 min_progress,
344 max_progress,
345 &bounds_for_step))
346 return false;
347 bounds->Union(bounds_for_step);
349 return true;
352 bool KeyframedTransformAnimationCurve::AffectsScale() const {
353 for (size_t i = 0; i < keyframes_.size(); ++i) {
354 if (keyframes_[i]->Value().AffectsScale())
355 return true;
357 return false;
360 bool KeyframedTransformAnimationCurve::IsTranslation() const {
361 for (size_t i = 0; i < keyframes_.size(); ++i) {
362 if (!keyframes_[i]->Value().IsTranslation() &&
363 !keyframes_[i]->Value().IsIdentity())
364 return false;
366 return true;
369 bool KeyframedTransformAnimationCurve::MaximumScale(float* max_scale) const {
370 DCHECK_GE(keyframes_.size(), 2ul);
371 *max_scale = 0.f;
372 for (size_t i = 1; i < keyframes_.size(); ++i) {
373 float min_progress = 0.f;
374 float max_progress = 1.f;
375 if (keyframes_[i - 1]->timing_function())
376 keyframes_[i - 1]->timing_function()->Range(&min_progress, &max_progress);
378 float max_scale_for_segment = 0.f;
379 if (!keyframes_[i]->Value().MaximumScale(keyframes_[i - 1]->Value(),
380 min_progress,
381 max_progress,
382 &max_scale_for_segment))
383 return false;
385 *max_scale = std::max(*max_scale, max_scale_for_segment);
387 return true;
390 scoped_ptr<KeyframedFilterAnimationCurve> KeyframedFilterAnimationCurve::
391 Create() {
392 return make_scoped_ptr(new KeyframedFilterAnimationCurve);
395 KeyframedFilterAnimationCurve::KeyframedFilterAnimationCurve() {}
397 KeyframedFilterAnimationCurve::~KeyframedFilterAnimationCurve() {}
399 void KeyframedFilterAnimationCurve::AddKeyframe(
400 scoped_ptr<FilterKeyframe> keyframe) {
401 InsertKeyframe(keyframe.Pass(), &keyframes_);
404 double KeyframedFilterAnimationCurve::Duration() const {
405 return keyframes_.back()->Time() - keyframes_.front()->Time();
408 scoped_ptr<AnimationCurve> KeyframedFilterAnimationCurve::Clone() const {
409 scoped_ptr<KeyframedFilterAnimationCurve> to_return =
410 KeyframedFilterAnimationCurve::Create();
411 for (size_t i = 0; i < keyframes_.size(); ++i)
412 to_return->AddKeyframe(keyframes_[i]->Clone());
414 if (timing_function_)
415 to_return->SetTimingFunction(timing_function_->Clone());
417 return to_return.Pass();
420 FilterOperations KeyframedFilterAnimationCurve::GetValue(double t) const {
421 if (t <= keyframes_.front()->Time())
422 return keyframes_.front()->Value();
424 if (t >= keyframes_.back()->Time())
425 return keyframes_.back()->Value();
427 t = TransformedAnimationTime(keyframes_, timing_function_, t);
428 size_t i = GetActiveKeyframe(keyframes_, t);
429 double progress = TransformedKeyframeProgress(keyframes_, t, i);
431 return keyframes_[i + 1]->Value().Blend(keyframes_[i]->Value(), progress);
434 bool KeyframedFilterAnimationCurve::HasFilterThatMovesPixels() const {
435 for (size_t i = 0; i < keyframes_.size(); ++i) {
436 if (keyframes_[i]->Value().HasFilterThatMovesPixels()) {
437 return true;
440 return false;
443 } // namespace cc