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/keyframed_animation_curve.h"
6 
7 #include "cc/animation/transform_operations.h"
8 #include "cc/test/geometry_test_utils.h"
9 #include "testing/gmock/include/gmock/gmock.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "ui/gfx/animation/tween.h"
12 #include "ui/gfx/geometry/box_f.h"
13 #include "ui/gfx/test/gfx_util.h"
14 
15 namespace cc {
16 namespace {
17 
ExpectTranslateX(SkScalar translate_x,const TransformOperations & operations)18 void ExpectTranslateX(SkScalar translate_x,
19                       const TransformOperations& operations) {
20   EXPECT_FLOAT_EQ(translate_x, operations.Apply().matrix().get(0, 3));
21 }
22 
ExpectBrightness(double brightness,const FilterOperations & filter)23 void ExpectBrightness(double brightness, const FilterOperations& filter) {
24   EXPECT_EQ(1u, filter.size());
25   EXPECT_EQ(FilterOperation::BRIGHTNESS, filter.at(0).type());
26   EXPECT_FLOAT_EQ(brightness, filter.at(0).amount());
27 }
28 
29 // Tests that a color animation with one keyframe works as expected.
TEST(KeyframedAnimationCurveTest,OneColorKeyFrame)30 TEST(KeyframedAnimationCurveTest, OneColorKeyFrame) {
31   SkColor color = SkColorSetARGB(255, 255, 255, 255);
32   std::unique_ptr<KeyframedColorAnimationCurve> curve(
33       KeyframedColorAnimationCurve::Create());
34   curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta(), color, nullptr));
35 
36   EXPECT_SKCOLOR_EQ(color,
37                     curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
38   EXPECT_SKCOLOR_EQ(color, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
39   EXPECT_SKCOLOR_EQ(color,
40                     curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
41   EXPECT_SKCOLOR_EQ(color, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
42   EXPECT_SKCOLOR_EQ(color, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
43 }
44 
45 // Tests that a color animation with two keyframes works as expected.
TEST(KeyframedAnimationCurveTest,TwoColorKeyFrame)46 TEST(KeyframedAnimationCurveTest, TwoColorKeyFrame) {
47   SkColor color_a = SkColorSetARGB(255, 255, 0, 0);
48   SkColor color_b = SkColorSetARGB(255, 0, 255, 0);
49   SkColor color_midpoint = gfx::Tween::ColorValueBetween(0.5, color_a, color_b);
50   std::unique_ptr<KeyframedColorAnimationCurve> curve(
51       KeyframedColorAnimationCurve::Create());
52   curve->AddKeyframe(
53       ColorKeyframe::Create(base::TimeDelta(), color_a, nullptr));
54   curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
55                                            color_b, nullptr));
56 
57   EXPECT_SKCOLOR_EQ(color_a,
58                     curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
59   EXPECT_SKCOLOR_EQ(color_a,
60                     curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
61   EXPECT_SKCOLOR_EQ(color_midpoint,
62                     curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
63   EXPECT_SKCOLOR_EQ(color_b,
64                     curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
65   EXPECT_SKCOLOR_EQ(color_b,
66                     curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
67 }
68 
69 // Tests that a color animation with three keyframes works as expected.
TEST(KeyframedAnimationCurveTest,ThreeColorKeyFrame)70 TEST(KeyframedAnimationCurveTest, ThreeColorKeyFrame) {
71   SkColor color_a = SkColorSetARGB(255, 255, 0, 0);
72   SkColor color_b = SkColorSetARGB(255, 0, 255, 0);
73   SkColor color_c = SkColorSetARGB(255, 0, 0, 255);
74   SkColor color_midpoint1 =
75       gfx::Tween::ColorValueBetween(0.5, color_a, color_b);
76   SkColor color_midpoint2 =
77       gfx::Tween::ColorValueBetween(0.5, color_b, color_c);
78   std::unique_ptr<KeyframedColorAnimationCurve> curve(
79       KeyframedColorAnimationCurve::Create());
80   curve->AddKeyframe(
81       ColorKeyframe::Create(base::TimeDelta(), color_a, nullptr));
82   curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
83                                            color_b, nullptr));
84   curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta::FromSecondsD(2.0),
85                                            color_c, nullptr));
86 
87   EXPECT_SKCOLOR_EQ(color_a,
88                     curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
89   EXPECT_SKCOLOR_EQ(color_a,
90                     curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
91   EXPECT_SKCOLOR_EQ(color_midpoint1,
92                     curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
93   EXPECT_SKCOLOR_EQ(color_b,
94                     curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
95   EXPECT_SKCOLOR_EQ(color_midpoint2,
96                     curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
97   EXPECT_SKCOLOR_EQ(color_c,
98                     curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
99   EXPECT_SKCOLOR_EQ(color_c,
100                     curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
101 }
102 
103 // Tests that a color animation with multiple keys at a given time works sanely.
TEST(KeyframedAnimationCurveTest,RepeatedColorKeyFrame)104 TEST(KeyframedAnimationCurveTest, RepeatedColorKeyFrame) {
105   SkColor color_a = SkColorSetARGB(255, 64, 0, 0);
106   SkColor color_b = SkColorSetARGB(255, 192, 0, 0);
107 
108   std::unique_ptr<KeyframedColorAnimationCurve> curve(
109       KeyframedColorAnimationCurve::Create());
110   curve->AddKeyframe(
111       ColorKeyframe::Create(base::TimeDelta(), color_a, nullptr));
112   curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
113                                            color_a, nullptr));
114   curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
115                                            color_b, nullptr));
116   curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta::FromSecondsD(2.0),
117                                            color_b, nullptr));
118 
119   EXPECT_SKCOLOR_EQ(color_a,
120                     curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
121   EXPECT_SKCOLOR_EQ(color_a,
122                     curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
123   EXPECT_SKCOLOR_EQ(color_a,
124                     curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
125 
126   SkColor value = curve->GetValue(base::TimeDelta::FromSecondsD(1.0f));
127   EXPECT_EQ(255u, SkColorGetA(value));
128   int red_value = SkColorGetR(value);
129   EXPECT_LE(64, red_value);
130   EXPECT_GE(192, red_value);
131 
132   EXPECT_SKCOLOR_EQ(color_b,
133                     curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
134   EXPECT_SKCOLOR_EQ(color_b,
135                     curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
136   EXPECT_SKCOLOR_EQ(color_b,
137                     curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
138 }
139 
140 // Tests that a float animation with one keyframe works as expected.
TEST(KeyframedAnimationCurveTest,OneFloatKeyframe)141 TEST(KeyframedAnimationCurveTest, OneFloatKeyframe) {
142   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
143       KeyframedFloatAnimationCurve::Create());
144   curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 2.f, nullptr));
145   EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
146   EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
147   EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
148   EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
149   EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
150 }
151 
152 // Tests that a float animation with two keyframes works as expected.
TEST(KeyframedAnimationCurveTest,TwoFloatKeyframe)153 TEST(KeyframedAnimationCurveTest, TwoFloatKeyframe) {
154   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
155       KeyframedFloatAnimationCurve::Create());
156   curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 2.f, nullptr));
157   curve->AddKeyframe(
158       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 4.f, nullptr));
159   EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
160   EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
161   EXPECT_FLOAT_EQ(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
162   EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
163   EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
164 }
165 
166 // Tests that a float animation with three keyframes works as expected.
TEST(KeyframedAnimationCurveTest,ThreeFloatKeyframe)167 TEST(KeyframedAnimationCurveTest, ThreeFloatKeyframe) {
168   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
169       KeyframedFloatAnimationCurve::Create());
170   curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 2.f, nullptr));
171   curve->AddKeyframe(
172       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 4.f, nullptr));
173   curve->AddKeyframe(
174       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(2.0), 8.f, nullptr));
175   EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
176   EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
177   EXPECT_FLOAT_EQ(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
178   EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
179   EXPECT_FLOAT_EQ(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
180   EXPECT_FLOAT_EQ(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
181   EXPECT_FLOAT_EQ(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
182 }
183 
184 // Tests that a float animation with multiple keys at a given time works sanely.
TEST(KeyframedAnimationCurveTest,RepeatedFloatKeyTimes)185 TEST(KeyframedAnimationCurveTest, RepeatedFloatKeyTimes) {
186   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
187       KeyframedFloatAnimationCurve::Create());
188   curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 4.f, nullptr));
189   curve->AddKeyframe(
190       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 4.f, nullptr));
191   curve->AddKeyframe(
192       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 6.f, nullptr));
193   curve->AddKeyframe(
194       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(2.0), 6.f, nullptr));
195 
196   EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
197   EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
198   EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
199 
200   // There is a discontinuity at 1. Any value between 4 and 6 is valid.
201   float value = curve->GetValue(base::TimeDelta::FromSecondsD(1.f));
202   EXPECT_TRUE(value >= 4 && value <= 6);
203 
204   EXPECT_FLOAT_EQ(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
205   EXPECT_FLOAT_EQ(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
206   EXPECT_FLOAT_EQ(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
207 }
208 
209 // Tests that a transform animation with one keyframe works as expected.
TEST(KeyframedAnimationCurveTest,OneTransformKeyframe)210 TEST(KeyframedAnimationCurveTest, OneTransformKeyframe) {
211   std::unique_ptr<KeyframedTransformAnimationCurve> curve(
212       KeyframedTransformAnimationCurve::Create());
213   TransformOperations operations;
214   operations.AppendTranslate(2.f, 0.f, 0.f);
215   curve->AddKeyframe(
216       TransformKeyframe::Create(base::TimeDelta(), operations, nullptr));
217 
218   ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
219   ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
220   ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
221   ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
222   ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
223 }
224 
225 // Tests that a transform animation with two keyframes works as expected.
TEST(KeyframedAnimationCurveTest,TwoTransformKeyframe)226 TEST(KeyframedAnimationCurveTest, TwoTransformKeyframe) {
227   std::unique_ptr<KeyframedTransformAnimationCurve> curve(
228       KeyframedTransformAnimationCurve::Create());
229   TransformOperations operations1;
230   operations1.AppendTranslate(2.f, 0.f, 0.f);
231   TransformOperations operations2;
232   operations2.AppendTranslate(4.f, 0.f, 0.f);
233 
234   curve->AddKeyframe(
235       TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
236   curve->AddKeyframe(TransformKeyframe::Create(
237       base::TimeDelta::FromSecondsD(1.0), operations2, nullptr));
238   ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
239   ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
240   ExpectTranslateX(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
241   ExpectTranslateX(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
242   ExpectTranslateX(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
243 }
244 
245 // Tests that a transform animation with three keyframes works as expected.
TEST(KeyframedAnimationCurveTest,ThreeTransformKeyframe)246 TEST(KeyframedAnimationCurveTest, ThreeTransformKeyframe) {
247   std::unique_ptr<KeyframedTransformAnimationCurve> curve(
248       KeyframedTransformAnimationCurve::Create());
249   TransformOperations operations1;
250   operations1.AppendTranslate(2.f, 0.f, 0.f);
251   TransformOperations operations2;
252   operations2.AppendTranslate(4.f, 0.f, 0.f);
253   TransformOperations operations3;
254   operations3.AppendTranslate(8.f, 0.f, 0.f);
255   curve->AddKeyframe(
256       TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
257   curve->AddKeyframe(TransformKeyframe::Create(
258       base::TimeDelta::FromSecondsD(1.0), operations2, nullptr));
259   curve->AddKeyframe(TransformKeyframe::Create(
260       base::TimeDelta::FromSecondsD(2.0), operations3, nullptr));
261   ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
262   ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
263   ExpectTranslateX(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
264   ExpectTranslateX(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
265   ExpectTranslateX(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
266   ExpectTranslateX(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
267   ExpectTranslateX(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
268 }
269 
270 // Tests that a transform animation with multiple keys at a given time works
271 // sanely.
TEST(KeyframedAnimationCurveTest,RepeatedTransformKeyTimes)272 TEST(KeyframedAnimationCurveTest, RepeatedTransformKeyTimes) {
273   std::unique_ptr<KeyframedTransformAnimationCurve> curve(
274       KeyframedTransformAnimationCurve::Create());
275   // A step function.
276   TransformOperations operations1;
277   operations1.AppendTranslate(4.f, 0.f, 0.f);
278   TransformOperations operations2;
279   operations2.AppendTranslate(4.f, 0.f, 0.f);
280   TransformOperations operations3;
281   operations3.AppendTranslate(6.f, 0.f, 0.f);
282   TransformOperations operations4;
283   operations4.AppendTranslate(6.f, 0.f, 0.f);
284   curve->AddKeyframe(
285       TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
286   curve->AddKeyframe(TransformKeyframe::Create(
287       base::TimeDelta::FromSecondsD(1.0), operations2, nullptr));
288   curve->AddKeyframe(TransformKeyframe::Create(
289       base::TimeDelta::FromSecondsD(1.0), operations3, nullptr));
290   curve->AddKeyframe(TransformKeyframe::Create(
291       base::TimeDelta::FromSecondsD(2.0), operations4, nullptr));
292 
293   ExpectTranslateX(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
294   ExpectTranslateX(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
295   ExpectTranslateX(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
296 
297   // There is a discontinuity at 1. Any value between 4 and 6 is valid.
298   gfx::Transform value =
299       curve->GetValue(base::TimeDelta::FromSecondsD(1.f)).Apply();
300   EXPECT_GE(value.matrix().get(0, 3), 4.f);
301   EXPECT_LE(value.matrix().get(0, 3), 6.f);
302 
303   ExpectTranslateX(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
304   ExpectTranslateX(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
305   ExpectTranslateX(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
306 }
307 
308 // Tests that a discrete transform animation (e.g. where one or more keyframes
309 // is a non-invertible matrix) works as expected.
TEST(KeyframedAnimationCurveTest,DiscreteLinearTransformAnimation)310 TEST(KeyframedAnimationCurveTest, DiscreteLinearTransformAnimation) {
311   gfx::Transform non_invertible_matrix(0, 0, 0, 0, 0, 0);
312   gfx::Transform identity_matrix;
313 
314   std::unique_ptr<KeyframedTransformAnimationCurve> curve(
315       KeyframedTransformAnimationCurve::Create());
316   TransformOperations operations1;
317   operations1.AppendMatrix(non_invertible_matrix);
318   TransformOperations operations2;
319   operations2.AppendMatrix(identity_matrix);
320   TransformOperations operations3;
321   operations3.AppendMatrix(non_invertible_matrix);
322 
323   curve->AddKeyframe(
324       TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
325   curve->AddKeyframe(TransformKeyframe::Create(
326       base::TimeDelta::FromSecondsD(1.0), operations2, nullptr));
327   curve->AddKeyframe(TransformKeyframe::Create(
328       base::TimeDelta::FromSecondsD(2.0), operations3, nullptr));
329 
330   TransformOperations result;
331 
332   // Between 0 and 0.5 seconds, the first keyframe should be returned.
333   result = curve->GetValue(base::TimeDelta::FromSecondsD(0.01f));
334   EXPECT_TRANSFORMATION_MATRIX_EQ(non_invertible_matrix, result.Apply());
335 
336   result = curve->GetValue(base::TimeDelta::FromSecondsD(0.49f));
337   EXPECT_TRANSFORMATION_MATRIX_EQ(non_invertible_matrix, result.Apply());
338 
339   // Between 0.5 and 1.5 seconds, the middle keyframe should be returned.
340   result = curve->GetValue(base::TimeDelta::FromSecondsD(0.5f));
341   EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, result.Apply());
342 
343   result = curve->GetValue(base::TimeDelta::FromSecondsD(1.49f));
344   EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, result.Apply());
345 
346   // Between 1.5 and 2.0 seconds, the last keyframe should be returned.
347   result = curve->GetValue(base::TimeDelta::FromSecondsD(1.5f));
348   EXPECT_TRANSFORMATION_MATRIX_EQ(non_invertible_matrix, result.Apply());
349 
350   result = curve->GetValue(base::TimeDelta::FromSecondsD(2.0f));
351   EXPECT_TRANSFORMATION_MATRIX_EQ(non_invertible_matrix, result.Apply());
352 }
353 
TEST(KeyframedAnimationCurveTest,DiscreteCubicBezierTransformAnimation)354 TEST(KeyframedAnimationCurveTest, DiscreteCubicBezierTransformAnimation) {
355   gfx::Transform non_invertible_matrix(0, 0, 0, 0, 0, 0);
356   gfx::Transform identity_matrix;
357 
358   std::unique_ptr<KeyframedTransformAnimationCurve> curve(
359       KeyframedTransformAnimationCurve::Create());
360   TransformOperations operations1;
361   operations1.AppendMatrix(non_invertible_matrix);
362   TransformOperations operations2;
363   operations2.AppendMatrix(identity_matrix);
364   TransformOperations operations3;
365   operations3.AppendMatrix(non_invertible_matrix);
366 
367   // The cubic-bezier here is a nice fairly strong ease-in curve, where 50%
368   // progression is at approximately 85% of the time.
369   curve->AddKeyframe(TransformKeyframe::Create(
370       base::TimeDelta(), operations1,
371       CubicBezierTimingFunction::Create(0.75f, 0.25f, 0.9f, 0.4f)));
372   curve->AddKeyframe(TransformKeyframe::Create(
373       base::TimeDelta::FromSecondsD(1.0), operations2,
374       CubicBezierTimingFunction::Create(0.75f, 0.25f, 0.9f, 0.4f)));
375   curve->AddKeyframe(TransformKeyframe::Create(
376       base::TimeDelta::FromSecondsD(2.0), operations3,
377       CubicBezierTimingFunction::Create(0.75f, 0.25f, 0.9f, 0.4f)));
378 
379   TransformOperations result;
380 
381   // Due to the cubic-bezier, the first keyframe is returned almost all the way
382   // to 1 second.
383   result = curve->GetValue(base::TimeDelta::FromSecondsD(0.01f));
384   EXPECT_TRANSFORMATION_MATRIX_EQ(non_invertible_matrix, result.Apply());
385 
386   result = curve->GetValue(base::TimeDelta::FromSecondsD(0.8f));
387   EXPECT_TRANSFORMATION_MATRIX_EQ(non_invertible_matrix, result.Apply());
388 
389   // Between ~0.85 and ~1.85 seconds, the middle keyframe should be returned.
390   result = curve->GetValue(base::TimeDelta::FromSecondsD(0.85f));
391   EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, result.Apply());
392 
393   result = curve->GetValue(base::TimeDelta::FromSecondsD(1.8f));
394   EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, result.Apply());
395 
396   // Finally the last keyframe only takes effect after ~1.85 seconds.
397   result = curve->GetValue(base::TimeDelta::FromSecondsD(1.85f));
398   EXPECT_TRANSFORMATION_MATRIX_EQ(non_invertible_matrix, result.Apply());
399 
400   result = curve->GetValue(base::TimeDelta::FromSecondsD(2.0f));
401   EXPECT_TRANSFORMATION_MATRIX_EQ(non_invertible_matrix, result.Apply());
402 }
403 
404 // Tests that a filter animation with one keyframe works as expected.
TEST(KeyframedAnimationCurveTest,OneFilterKeyframe)405 TEST(KeyframedAnimationCurveTest, OneFilterKeyframe) {
406   std::unique_ptr<KeyframedFilterAnimationCurve> curve(
407       KeyframedFilterAnimationCurve::Create());
408   FilterOperations operations;
409   operations.Append(FilterOperation::CreateBrightnessFilter(2.f));
410   curve->AddKeyframe(
411       FilterKeyframe::Create(base::TimeDelta(), operations, nullptr));
412 
413   ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
414   ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
415   ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
416   ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
417   ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
418 }
419 
420 // Tests that a filter animation with two keyframes works as expected.
TEST(KeyframedAnimationCurveTest,TwoFilterKeyframe)421 TEST(KeyframedAnimationCurveTest, TwoFilterKeyframe) {
422   std::unique_ptr<KeyframedFilterAnimationCurve> curve(
423       KeyframedFilterAnimationCurve::Create());
424   FilterOperations operations1;
425   operations1.Append(FilterOperation::CreateBrightnessFilter(2.f));
426   FilterOperations operations2;
427   operations2.Append(FilterOperation::CreateBrightnessFilter(4.f));
428 
429   curve->AddKeyframe(
430       FilterKeyframe::Create(base::TimeDelta(), operations1, nullptr));
431   curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(1.f),
432                                             operations2, nullptr));
433   ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
434   ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
435   ExpectBrightness(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
436   ExpectBrightness(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
437   ExpectBrightness(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
438 }
439 
440 // Tests that a filter animation with three keyframes works as expected.
TEST(KeyframedAnimationCurveTest,ThreeFilterKeyframe)441 TEST(KeyframedAnimationCurveTest, ThreeFilterKeyframe) {
442   std::unique_ptr<KeyframedFilterAnimationCurve> curve(
443       KeyframedFilterAnimationCurve::Create());
444   FilterOperations operations1;
445   operations1.Append(FilterOperation::CreateBrightnessFilter(2.f));
446   FilterOperations operations2;
447   operations2.Append(FilterOperation::CreateBrightnessFilter(4.f));
448   FilterOperations operations3;
449   operations3.Append(FilterOperation::CreateBrightnessFilter(8.f));
450   curve->AddKeyframe(
451       FilterKeyframe::Create(base::TimeDelta(), operations1, nullptr));
452   curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(1.f),
453                                             operations2, nullptr));
454   curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(2.f),
455                                             operations3, nullptr));
456   ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
457   ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
458   ExpectBrightness(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
459   ExpectBrightness(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
460   ExpectBrightness(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
461   ExpectBrightness(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
462   ExpectBrightness(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
463 }
464 
465 // Tests that a filter animation with multiple keys at a given time works
466 // sanely.
TEST(KeyframedAnimationCurveTest,RepeatedFilterKeyTimes)467 TEST(KeyframedAnimationCurveTest, RepeatedFilterKeyTimes) {
468   std::unique_ptr<KeyframedFilterAnimationCurve> curve(
469       KeyframedFilterAnimationCurve::Create());
470   // A step function.
471   FilterOperations operations1;
472   operations1.Append(FilterOperation::CreateBrightnessFilter(4.f));
473   FilterOperations operations2;
474   operations2.Append(FilterOperation::CreateBrightnessFilter(4.f));
475   FilterOperations operations3;
476   operations3.Append(FilterOperation::CreateBrightnessFilter(6.f));
477   FilterOperations operations4;
478   operations4.Append(FilterOperation::CreateBrightnessFilter(6.f));
479   curve->AddKeyframe(
480       FilterKeyframe::Create(base::TimeDelta(), operations1, nullptr));
481   curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(1.f),
482                                             operations2, nullptr));
483   curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(1.f),
484                                             operations3, nullptr));
485   curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(2.f),
486                                             operations4, nullptr));
487 
488   ExpectBrightness(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
489   ExpectBrightness(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
490   ExpectBrightness(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
491 
492   // There is a discontinuity at 1. Any value between 4 and 6 is valid.
493   FilterOperations value = curve->GetValue(base::TimeDelta::FromSecondsD(1.f));
494   EXPECT_EQ(1u, value.size());
495   EXPECT_EQ(FilterOperation::BRIGHTNESS, value.at(0).type());
496   EXPECT_GE(value.at(0).amount(), 4);
497   EXPECT_LE(value.at(0).amount(), 6);
498 
499   ExpectBrightness(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
500   ExpectBrightness(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
501   ExpectBrightness(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
502 }
503 
504 // Tests that the keyframes may be added out of order.
TEST(KeyframedAnimationCurveTest,UnsortedKeyframes)505 TEST(KeyframedAnimationCurveTest, UnsortedKeyframes) {
506   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
507       KeyframedFloatAnimationCurve::Create());
508   curve->AddKeyframe(
509       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(2.f), 8.f, nullptr));
510   curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 2.f, nullptr));
511   curve->AddKeyframe(
512       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), 4.f, nullptr));
513   EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
514   EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
515   EXPECT_FLOAT_EQ(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
516   EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
517   EXPECT_FLOAT_EQ(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
518   EXPECT_FLOAT_EQ(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
519   EXPECT_FLOAT_EQ(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
520 }
521 
522 // Tests that a linear timing function works as expected.
TEST(KeyframedAnimationCurveTest,LinearTimingFunction)523 TEST(KeyframedAnimationCurveTest, LinearTimingFunction) {
524   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
525       KeyframedFloatAnimationCurve::Create());
526   curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f,
527                                            LinearTimingFunction::Create()));
528   curve->AddKeyframe(
529       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 1.f, nullptr));
530 
531   EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
532   EXPECT_FLOAT_EQ(0.75f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f)));
533 }
534 
535 // Tests that a cubic bezier timing function works as expected.
TEST(KeyframedAnimationCurveTest,CubicBezierTimingFunction)536 TEST(KeyframedAnimationCurveTest, CubicBezierTimingFunction) {
537   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
538       KeyframedFloatAnimationCurve::Create());
539   curve->AddKeyframe(FloatKeyframe::Create(
540       base::TimeDelta(), 0.f,
541       CubicBezierTimingFunction::Create(0.25f, 0.f, 0.75f, 1.f)));
542   curve->AddKeyframe(
543       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 1.f, nullptr));
544 
545   EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
546   EXPECT_LT(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.25f)));
547   EXPECT_GT(0.25f, curve->GetValue(base::TimeDelta::FromSecondsD(0.25f)));
548   EXPECT_NEAR(curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)), 0.5f,
549               0.00015f);
550   EXPECT_LT(0.75f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f)));
551   EXPECT_GT(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f)));
552   EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
553 }
554 
555 // Tests a step timing function if the change of values occur at the start.
TEST(KeyframedAnimationCurveTest,StepsTimingFunctionStepAtStart)556 TEST(KeyframedAnimationCurveTest, StepsTimingFunctionStepAtStart) {
557   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
558       KeyframedFloatAnimationCurve::Create());
559   const int num_steps = 36;
560   curve->AddKeyframe(FloatKeyframe::Create(
561       base::TimeDelta(), 0.f,
562       StepsTimingFunction::Create(num_steps,
563                                   StepsTimingFunction::StepPosition::START)));
564   curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
565                                            num_steps, nullptr));
566 
567   const float time_threshold = 0.0001f;
568 
569   for (float i = 0.f; i < num_steps; i += 1.f) {
570     const base::TimeDelta time1 =
571         base::TimeDelta::FromSecondsD(i / num_steps - time_threshold);
572     const base::TimeDelta time2 =
573         base::TimeDelta::FromSecondsD(i / num_steps + time_threshold);
574     EXPECT_FLOAT_EQ(std::ceil(i), curve->GetValue(time1));
575     EXPECT_FLOAT_EQ(std::ceil(i) + 1.f, curve->GetValue(time2));
576   }
577   EXPECT_FLOAT_EQ(num_steps,
578                   curve->GetValue(base::TimeDelta::FromSecondsD(1.0)));
579 
580   for (float i = 0.5f; i <= num_steps; i += 1.0f) {
581     const base::TimeDelta time = base::TimeDelta::FromSecondsD(i / num_steps);
582     EXPECT_FLOAT_EQ(std::ceil(i), curve->GetValue(time));
583   }
584 }
585 
586 // Tests a step timing function if the change of values occur at the end.
TEST(KeyframedAnimationCurveTest,StepsTimingFunctionStepAtEnd)587 TEST(KeyframedAnimationCurveTest, StepsTimingFunctionStepAtEnd) {
588   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
589       KeyframedFloatAnimationCurve::Create());
590   const int num_steps = 36;
591   curve->AddKeyframe(FloatKeyframe::Create(
592       base::TimeDelta(), 0.f,
593       StepsTimingFunction::Create(num_steps,
594                                   StepsTimingFunction::StepPosition::END)));
595   curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
596                                            num_steps, nullptr));
597 
598   const float time_threshold = 0.0001f;
599 
600   EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta()));
601   for (float i = 1.f; i <= num_steps; i += 1.f) {
602     const base::TimeDelta time1 =
603         base::TimeDelta::FromSecondsD(i / num_steps - time_threshold);
604     const base::TimeDelta time2 =
605         base::TimeDelta::FromSecondsD(i / num_steps + time_threshold);
606     EXPECT_FLOAT_EQ(std::floor(i) - 1.f, curve->GetValue(time1));
607     EXPECT_FLOAT_EQ(std::floor(i), curve->GetValue(time2));
608   }
609   EXPECT_FLOAT_EQ(num_steps,
610                   curve->GetValue(base::TimeDelta::FromSecondsD(1.0)));
611 
612   for (float i = 0.5f; i <= num_steps; i += 1.0f) {
613     const base::TimeDelta time = base::TimeDelta::FromSecondsD(i / num_steps);
614     EXPECT_FLOAT_EQ(std::floor(i), curve->GetValue(time));
615   }
616 }
617 
618 // Tests that animations that are translations are correctly identified.
TEST(KeyframedAnimationCurveTest,IsTranslation)619 TEST(KeyframedAnimationCurveTest, IsTranslation) {
620   std::unique_ptr<KeyframedTransformAnimationCurve> curve(
621       KeyframedTransformAnimationCurve::Create());
622 
623   TransformOperations operations1;
624   curve->AddKeyframe(
625       TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
626   operations1.AppendTranslate(2.0, 3.0, -1.0);
627   TransformOperations operations2;
628   operations2.AppendTranslate(4.0, 1.0, 2.0);
629   curve->AddKeyframe(TransformKeyframe::Create(
630       base::TimeDelta::FromSecondsD(1.f), operations2, nullptr));
631 
632   EXPECT_TRUE(curve->IsTranslation());
633 
634   TransformOperations operations3;
635   operations3.AppendScale(2.f, 2.f, 2.f);
636   curve->AddKeyframe(TransformKeyframe::Create(
637       base::TimeDelta::FromSecondsD(2.f), operations3, nullptr));
638 
639   EXPECT_FALSE(curve->IsTranslation());
640 
641   TransformOperations operations4;
642   operations3.AppendTranslate(2.f, 2.f, 2.f);
643   curve->AddKeyframe(TransformKeyframe::Create(
644       base::TimeDelta::FromSecondsD(3.f), operations4, nullptr));
645 
646   EXPECT_FALSE(curve->IsTranslation());
647 }
648 
649 // Tests that maximum target scale is computed as expected.
TEST(KeyframedAnimationCurveTest,MaximumTargetScale)650 TEST(KeyframedAnimationCurveTest, MaximumTargetScale) {
651   std::unique_ptr<KeyframedTransformAnimationCurve> curve(
652       KeyframedTransformAnimationCurve::Create());
653 
654   TransformOperations operations1;
655   curve->AddKeyframe(
656       TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
657   operations1.AppendScale(2.f, -3.f, 1.f);
658   curve->AddKeyframe(TransformKeyframe::Create(
659       base::TimeDelta::FromSecondsD(1.f), operations1,
660       CubicBezierTimingFunction::CreatePreset(
661           CubicBezierTimingFunction::EaseType::EASE)));
662 
663   float maximum_scale = 0.f;
664   EXPECT_TRUE(curve->MaximumTargetScale(true, &maximum_scale));
665   EXPECT_EQ(3.f, maximum_scale);
666 
667   TransformOperations operations2;
668   operations2.AppendScale(6.f, 3.f, 2.f);
669   curve->AddKeyframe(TransformKeyframe::Create(
670       base::TimeDelta::FromSecondsD(2.f), operations2,
671       CubicBezierTimingFunction::CreatePreset(
672           CubicBezierTimingFunction::EaseType::EASE)));
673 
674   EXPECT_TRUE(curve->MaximumTargetScale(true, &maximum_scale));
675   EXPECT_EQ(6.f, maximum_scale);
676 
677   TransformOperations operations3;
678   operations3.AppendRotate(1.f, 0.f, 0.f, 90.f);
679   curve->AddKeyframe(TransformKeyframe::Create(
680       base::TimeDelta::FromSecondsD(3.f), operations3,
681       CubicBezierTimingFunction::CreatePreset(
682           CubicBezierTimingFunction::EaseType::EASE)));
683 
684   EXPECT_TRUE(curve->MaximumTargetScale(true, &maximum_scale));
685   EXPECT_EQ(6.f, maximum_scale);
686 
687   TransformOperations operations4;
688   operations4.AppendPerspective(3.f);
689   curve->AddKeyframe(TransformKeyframe::Create(
690       base::TimeDelta::FromSecondsD(4.f), operations4,
691       CubicBezierTimingFunction::CreatePreset(
692           CubicBezierTimingFunction::EaseType::EASE)));
693 
694   EXPECT_FALSE(curve->MaximumTargetScale(true, &maximum_scale));
695 
696   // The original scale is not used in computing the max.
697   std::unique_ptr<KeyframedTransformAnimationCurve> curve2(
698       KeyframedTransformAnimationCurve::Create());
699 
700   TransformOperations operations5;
701   operations5.AppendScale(0.4f, 0.2f, 0.6f);
702   curve2->AddKeyframe(TransformKeyframe::Create(
703       base::TimeDelta(), operations5,
704       CubicBezierTimingFunction::CreatePreset(
705           CubicBezierTimingFunction::EaseType::EASE)));
706   TransformOperations operations6;
707   operations6.AppendScale(0.5f, 0.3f, -0.8f);
708   curve2->AddKeyframe(TransformKeyframe::Create(
709       base::TimeDelta::FromSecondsD(1.f), operations6,
710       CubicBezierTimingFunction::CreatePreset(
711           CubicBezierTimingFunction::EaseType::EASE)));
712 
713   EXPECT_TRUE(curve2->MaximumTargetScale(true, &maximum_scale));
714   EXPECT_EQ(0.8f, maximum_scale);
715 
716   EXPECT_TRUE(curve2->MaximumTargetScale(false, &maximum_scale));
717   EXPECT_EQ(0.6f, maximum_scale);
718 }
719 
720 // Tests that starting animation scale is computed as expected.
TEST(KeyframedAnimationCurveTest,AnimationStartScale)721 TEST(KeyframedAnimationCurveTest, AnimationStartScale) {
722   std::unique_ptr<KeyframedTransformAnimationCurve> curve(
723       KeyframedTransformAnimationCurve::Create());
724 
725   TransformOperations operations1;
726   curve->AddKeyframe(
727       TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
728   operations1.AppendScale(2.f, -3.f, 1.f);
729   curve->AddKeyframe(TransformKeyframe::Create(
730       base::TimeDelta::FromSecondsD(1.f), operations1,
731       CubicBezierTimingFunction::CreatePreset(
732           CubicBezierTimingFunction::EaseType::EASE)));
733 
734   float start_scale = 0.f;
735 
736   // Forward direction
737   EXPECT_TRUE(curve->AnimationStartScale(true, &start_scale));
738   EXPECT_EQ(1.f, start_scale);
739 
740   // Backward direction
741   EXPECT_TRUE(curve->AnimationStartScale(false, &start_scale));
742   EXPECT_EQ(3.f, start_scale);
743 
744   TransformOperations operations2;
745   operations2.AppendScale(6.f, 3.f, 2.f);
746   curve->AddKeyframe(TransformKeyframe::Create(
747       base::TimeDelta::FromSecondsD(2.f), operations2,
748       CubicBezierTimingFunction::CreatePreset(
749           CubicBezierTimingFunction::EaseType::EASE)));
750 
751   // Forward direction
752   EXPECT_TRUE(curve->AnimationStartScale(true, &start_scale));
753   EXPECT_EQ(1.f, start_scale);
754 
755   // Backward direction
756   EXPECT_TRUE(curve->AnimationStartScale(false, &start_scale));
757   EXPECT_EQ(6.f, start_scale);
758 
759   TransformOperations operations3;
760   operations3.AppendRotate(1.f, 0.f, 0.f, 90.f);
761   curve->AddKeyframe(TransformKeyframe::Create(
762       base::TimeDelta::FromSecondsD(3.f), operations3,
763       CubicBezierTimingFunction::CreatePreset(
764           CubicBezierTimingFunction::EaseType::EASE)));
765 
766   EXPECT_TRUE(curve->AnimationStartScale(false, &start_scale));
767   EXPECT_EQ(1.f, start_scale);
768 
769   TransformOperations operations4;
770   operations4.AppendPerspective(90.f);
771   curve->AddKeyframe(TransformKeyframe::Create(
772       base::TimeDelta::FromSecondsD(4.f), operations4,
773       CubicBezierTimingFunction::CreatePreset(
774           CubicBezierTimingFunction::EaseType::EASE)));
775 
776   EXPECT_FALSE(curve->AnimationStartScale(false, &start_scale));
777   EXPECT_EQ(0.f, start_scale);
778 }
779 
780 // Tests that an animation with a curve timing function works as expected.
TEST(KeyframedAnimationCurveTest,CurveTiming)781 TEST(KeyframedAnimationCurveTest, CurveTiming) {
782   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
783       KeyframedFloatAnimationCurve::Create());
784   curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f, nullptr));
785   curve->AddKeyframe(
786       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), 1.f, nullptr));
787   curve->SetTimingFunction(
788       CubicBezierTimingFunction::Create(0.75f, 0.f, 0.25f, 1.f));
789   EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
790   EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
791   EXPECT_NEAR(0.05f, curve->GetValue(base::TimeDelta::FromSecondsD(0.25f)),
792               0.005f);
793   EXPECT_FLOAT_EQ(0.5f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
794   EXPECT_NEAR(0.95f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f)),
795               0.005f);
796   EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
797   EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
798 }
799 
800 // Tests that an animation with a curve and keyframe timing function works as
801 // expected.
TEST(KeyframedAnimationCurveTest,CurveAndKeyframeTiming)802 TEST(KeyframedAnimationCurveTest, CurveAndKeyframeTiming) {
803   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
804       KeyframedFloatAnimationCurve::Create());
805   curve->AddKeyframe(FloatKeyframe::Create(
806       base::TimeDelta(), 0.f,
807       CubicBezierTimingFunction::Create(0.35f, 0.f, 0.65f, 1.f)));
808   curve->AddKeyframe(
809       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), 1.f, nullptr));
810   // Curve timing function producing outputs outside of range [0,1].
811   curve->SetTimingFunction(
812       CubicBezierTimingFunction::Create(0.5f, -0.5f, 0.5f, 1.5f));
813   EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
814   EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
815   EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(
816                            0.25f)));  // Clamped. c(.25) < 0
817   EXPECT_NEAR(0.17f, curve->GetValue(base::TimeDelta::FromSecondsD(0.42f)),
818               0.005f);  // c(.42)=.27, k(.27)=.17
819   EXPECT_FLOAT_EQ(0.5f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
820   EXPECT_NEAR(0.83f, curve->GetValue(base::TimeDelta::FromSecondsD(0.58f)),
821               0.005f);  // c(.58)=.73, k(.73)=.83
822   EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(
823                            0.75f)));  // Clamped. c(.75) > 1
824   EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
825   EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
826 }
827 
828 // Tests that a linear timing function works as expected for inputs outside of
829 // range [0,1]
TEST(KeyframedAnimationCurveTest,LinearTimingInputsOutsideZeroOneRange)830 TEST(KeyframedAnimationCurveTest, LinearTimingInputsOutsideZeroOneRange) {
831   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
832       KeyframedFloatAnimationCurve::Create());
833   curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f, nullptr));
834   curve->AddKeyframe(
835       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 2.f, nullptr));
836   // Curve timing function producing timing outputs outside of range [0,1].
837   curve->SetTimingFunction(
838       CubicBezierTimingFunction::Create(0.5f, -0.5f, 0.5f, 1.5f));
839 
840   EXPECT_NEAR(-0.076f, curve->GetValue(base::TimeDelta::FromSecondsD(0.25f)),
841               0.001f);
842   EXPECT_NEAR(2.076f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f)),
843               0.001f);
844 }
845 
846 // If a curve cubic-bezier timing function produces timing outputs outside
847 // the range [0, 1] then a keyframe cubic-bezier timing function
848 // should consume that input properly (using end-point gradients).
TEST(KeyframedAnimationCurveTest,CurveTimingInputsOutsideZeroOneRange)849 TEST(KeyframedAnimationCurveTest, CurveTimingInputsOutsideZeroOneRange) {
850   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
851       KeyframedFloatAnimationCurve::Create());
852   // Keyframe timing function with 0.5 gradients at each end.
853   curve->AddKeyframe(FloatKeyframe::Create(
854       base::TimeDelta(), 0.f,
855       CubicBezierTimingFunction::Create(0.5f, 0.25f, 0.5f, 0.75f)));
856   curve->AddKeyframe(
857       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), 1.f, nullptr));
858   // Curve timing function producing timing outputs outside of range [0,1].
859   curve->SetTimingFunction(
860       CubicBezierTimingFunction::Create(0.5f, -0.5f, 0.5f, 1.5f));
861 
862   EXPECT_NEAR(-0.02f, curve->GetValue(base::TimeDelta::FromSecondsD(0.25f)),
863               0.002f);  // c(.25)=-.04, -.04*0.5=-0.02
864   EXPECT_NEAR(0.33f, curve->GetValue(base::TimeDelta::FromSecondsD(0.46f)),
865               0.002f);  // c(.46)=.38, k(.38)=.33
866 
867   EXPECT_NEAR(0.67f, curve->GetValue(base::TimeDelta::FromSecondsD(0.54f)),
868               0.002f);  // c(.54)=.62, k(.62)=.67
869   EXPECT_NEAR(1.02f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f)),
870               0.002f);  // c(.75)=1.04 1+.04*0.5=1.02
871 }
872 
873 // Tests that a step timing function works as expected for inputs outside of
874 // range [0,1]
TEST(KeyframedAnimationCurveTest,StepsTimingStartInputsOutsideZeroOneRange)875 TEST(KeyframedAnimationCurveTest, StepsTimingStartInputsOutsideZeroOneRange) {
876   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
877       KeyframedFloatAnimationCurve::Create());
878   curve->AddKeyframe(
879       FloatKeyframe::Create(base::TimeDelta(), 0.f,
880                             StepsTimingFunction::Create(
881                                 4, StepsTimingFunction::StepPosition::START)));
882   curve->AddKeyframe(
883       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 2.f, nullptr));
884   // Curve timing function producing timing outputs outside of range [0,1].
885   curve->SetTimingFunction(
886       CubicBezierTimingFunction::Create(0.5f, -0.5f, 0.5f, 1.5f));
887 
888   EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.25f)));
889   EXPECT_FLOAT_EQ(2.5f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f)));
890 }
891 
TEST(KeyframedAnimationCurveTest,StepsTimingEndInputsOutsideZeroOneRange)892 TEST(KeyframedAnimationCurveTest, StepsTimingEndInputsOutsideZeroOneRange) {
893   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
894       KeyframedFloatAnimationCurve::Create());
895   curve->AddKeyframe(FloatKeyframe::Create(
896       base::TimeDelta(), 0.f,
897       StepsTimingFunction::Create(4, StepsTimingFunction::StepPosition::END)));
898   curve->AddKeyframe(
899       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 2.f, nullptr));
900   // Curve timing function producing timing outputs outside of range [0,1].
901   curve->SetTimingFunction(
902       CubicBezierTimingFunction::Create(0.5f, -0.5f, 0.5f, 1.5f));
903 
904   EXPECT_FLOAT_EQ(-0.5f, curve->GetValue(base::TimeDelta::FromSecondsD(0.25f)));
905   EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f)));
906 }
907 
908 // Tests that an animation with a curve timing function and multiple keyframes
909 // works as expected.
TEST(KeyframedAnimationCurveTest,CurveTimingMultipleKeyframes)910 TEST(KeyframedAnimationCurveTest, CurveTimingMultipleKeyframes) {
911   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
912       KeyframedFloatAnimationCurve::Create());
913   curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f, nullptr));
914   curve->AddKeyframe(
915       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), 1.f, nullptr));
916   curve->AddKeyframe(
917       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(2.f), 3.f, nullptr));
918   curve->AddKeyframe(
919       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(3.f), 6.f, nullptr));
920   curve->AddKeyframe(
921       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(4.f), 9.f, nullptr));
922   curve->SetTimingFunction(
923       CubicBezierTimingFunction::Create(0.5f, 0.f, 0.5f, 1.f));
924   EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
925   EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
926   EXPECT_NEAR(0.42f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)),
927               0.005f);
928   EXPECT_NEAR(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.455f)),
929               0.005f);
930   EXPECT_FLOAT_EQ(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
931   EXPECT_NEAR(8.72f, curve->GetValue(base::TimeDelta::FromSecondsD(3.5f)),
932               0.01f);
933   EXPECT_FLOAT_EQ(9.f, curve->GetValue(base::TimeDelta::FromSecondsD(4.f)));
934   EXPECT_FLOAT_EQ(9.f, curve->GetValue(base::TimeDelta::FromSecondsD(5.f)));
935 }
936 
937 // Tests that an animation with a curve timing function that overshoots works as
938 // expected.
TEST(KeyframedAnimationCurveTest,CurveTimingOvershootMultipeKeyframes)939 TEST(KeyframedAnimationCurveTest, CurveTimingOvershootMultipeKeyframes) {
940   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
941       KeyframedFloatAnimationCurve::Create());
942   curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f, nullptr));
943   curve->AddKeyframe(
944       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 1.f, nullptr));
945   curve->AddKeyframe(
946       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(2.0), 3.f, nullptr));
947   curve->AddKeyframe(
948       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(3.0), 6.f, nullptr));
949   curve->AddKeyframe(
950       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(4.0), 9.f, nullptr));
951   // Curve timing function producing outputs outside of range [0,1].
952   curve->SetTimingFunction(
953       CubicBezierTimingFunction::Create(0.5f, -0.5f, 0.5f, 1.5f));
954   EXPECT_LE(curve->GetValue(base::TimeDelta::FromSecondsD(1.f)),
955             0.f);  // c(.25) < 0
956   EXPECT_GE(curve->GetValue(base::TimeDelta::FromSecondsD(3.f)),
957             9.f);  // c(.75) > 1
958 }
959 
960 // Tests that a float animation with multiple keys works with scaled duration.
TEST(KeyframedAnimationCurveTest,ScaledDuration)961 TEST(KeyframedAnimationCurveTest, ScaledDuration) {
962   std::unique_ptr<KeyframedFloatAnimationCurve> curve(
963       KeyframedFloatAnimationCurve::Create());
964   curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f, nullptr));
965   curve->AddKeyframe(
966       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), 1.f, nullptr));
967   curve->AddKeyframe(
968       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(2.f), 3.f, nullptr));
969   curve->AddKeyframe(
970       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(3.f), 6.f, nullptr));
971   curve->AddKeyframe(
972       FloatKeyframe::Create(base::TimeDelta::FromSecondsD(4.f), 9.f, nullptr));
973   curve->SetTimingFunction(
974       CubicBezierTimingFunction::Create(0.5f, 0.f, 0.5f, 1.f));
975 
976   const double scale = 1000.0;
977   curve->set_scaled_duration(scale);
978 
979   EXPECT_DOUBLE_EQ(scale * 4, curve->Duration().InSecondsF());
980 
981   EXPECT_FLOAT_EQ(0.f,
982                   curve->GetValue(base::TimeDelta::FromSecondsD(scale * -1.f)));
983   EXPECT_FLOAT_EQ(0.f,
984                   curve->GetValue(base::TimeDelta::FromSecondsD(scale * 0.f)));
985   EXPECT_NEAR(0.42f,
986               curve->GetValue(base::TimeDelta::FromSecondsD(scale * 1.f)),
987               0.005f);
988   EXPECT_NEAR(1.f,
989               curve->GetValue(base::TimeDelta::FromSecondsD(scale * 1.455f)),
990               0.005f);
991   EXPECT_FLOAT_EQ(3.f,
992                   curve->GetValue(base::TimeDelta::FromSecondsD(scale * 2.f)));
993   EXPECT_NEAR(8.72f,
994               curve->GetValue(base::TimeDelta::FromSecondsD(scale * 3.5f)),
995               0.01f);
996   EXPECT_FLOAT_EQ(9.f,
997                   curve->GetValue(base::TimeDelta::FromSecondsD(scale * 4.f)));
998   EXPECT_FLOAT_EQ(9.f,
999                   curve->GetValue(base::TimeDelta::FromSecondsD(scale * 5.f)));
1000 }
1001 
1002 // Tests that a size animation with one keyframe works as expected.
TEST(KeyframedAnimationCurveTest,OneSizeKeyFrame)1003 TEST(KeyframedAnimationCurveTest, OneSizeKeyFrame) {
1004   gfx::SizeF size = gfx::SizeF(100, 100);
1005   std::unique_ptr<KeyframedSizeAnimationCurve> curve(
1006       KeyframedSizeAnimationCurve::Create());
1007   curve->AddKeyframe(SizeKeyframe::Create(base::TimeDelta(), size, nullptr));
1008 
1009   EXPECT_SIZEF_EQ(size, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
1010   EXPECT_SIZEF_EQ(size, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
1011   EXPECT_SIZEF_EQ(size, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
1012   EXPECT_SIZEF_EQ(size, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
1013   EXPECT_SIZEF_EQ(size, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
1014 }
1015 
1016 // Tests that a size animation with two keyframes works as expected.
TEST(KeyframedAnimationCurveTest,TwoSizeKeyFrame)1017 TEST(KeyframedAnimationCurveTest, TwoSizeKeyFrame) {
1018   gfx::SizeF size_a = gfx::SizeF(100, 100);
1019   gfx::SizeF size_b = gfx::SizeF(100, 0);
1020   gfx::SizeF size_midpoint = gfx::Tween::SizeFValueBetween(0.5, size_a, size_b);
1021   std::unique_ptr<KeyframedSizeAnimationCurve> curve(
1022       KeyframedSizeAnimationCurve::Create());
1023   curve->AddKeyframe(SizeKeyframe::Create(base::TimeDelta(), size_a, nullptr));
1024   curve->AddKeyframe(SizeKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
1025                                           size_b, nullptr));
1026 
1027   EXPECT_SIZEF_EQ(size_a, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
1028   EXPECT_SIZEF_EQ(size_a, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
1029   EXPECT_SIZEF_EQ(size_midpoint,
1030                   curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
1031   EXPECT_SIZEF_EQ(size_b, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
1032   EXPECT_SIZEF_EQ(size_b, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
1033 }
1034 
1035 // Tests that a size animation with three keyframes works as expected.
TEST(KeyframedAnimationCurveTest,ThreeSizeKeyFrame)1036 TEST(KeyframedAnimationCurveTest, ThreeSizeKeyFrame) {
1037   gfx::SizeF size_a = gfx::SizeF(100, 100);
1038   gfx::SizeF size_b = gfx::SizeF(100, 0);
1039   gfx::SizeF size_c = gfx::SizeF(200, 0);
1040   gfx::SizeF size_midpoint1 =
1041       gfx::Tween::SizeFValueBetween(0.5, size_a, size_b);
1042   gfx::SizeF size_midpoint2 =
1043       gfx::Tween::SizeFValueBetween(0.5, size_b, size_c);
1044   std::unique_ptr<KeyframedSizeAnimationCurve> curve(
1045       KeyframedSizeAnimationCurve::Create());
1046   curve->AddKeyframe(SizeKeyframe::Create(base::TimeDelta(), size_a, nullptr));
1047   curve->AddKeyframe(SizeKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
1048                                           size_b, nullptr));
1049   curve->AddKeyframe(SizeKeyframe::Create(base::TimeDelta::FromSecondsD(2.0),
1050                                           size_c, nullptr));
1051 
1052   EXPECT_SIZEF_EQ(size_a, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
1053   EXPECT_SIZEF_EQ(size_a, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
1054   EXPECT_SIZEF_EQ(size_midpoint1,
1055                   curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
1056   EXPECT_SIZEF_EQ(size_b, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
1057   EXPECT_SIZEF_EQ(size_midpoint2,
1058                   curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
1059   EXPECT_SIZEF_EQ(size_c, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
1060   EXPECT_SIZEF_EQ(size_c, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
1061 }
1062 
1063 // Tests that a size animation with multiple keys at a given time works sanely.
TEST(KeyframedAnimationCurveTest,RepeatedSizeKeyFrame)1064 TEST(KeyframedAnimationCurveTest, RepeatedSizeKeyFrame) {
1065   gfx::SizeF size_a = gfx::SizeF(100, 64);
1066   gfx::SizeF size_b = gfx::SizeF(100, 192);
1067 
1068   std::unique_ptr<KeyframedSizeAnimationCurve> curve(
1069       KeyframedSizeAnimationCurve::Create());
1070   curve->AddKeyframe(SizeKeyframe::Create(base::TimeDelta(), size_a, nullptr));
1071   curve->AddKeyframe(SizeKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
1072                                           size_a, nullptr));
1073   curve->AddKeyframe(SizeKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
1074                                           size_b, nullptr));
1075   curve->AddKeyframe(SizeKeyframe::Create(base::TimeDelta::FromSecondsD(2.0),
1076                                           size_b, nullptr));
1077 
1078   EXPECT_SIZEF_EQ(size_a, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
1079   EXPECT_SIZEF_EQ(size_a, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
1080   EXPECT_SIZEF_EQ(size_a, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
1081 
1082   gfx::SizeF value = curve->GetValue(base::TimeDelta::FromSecondsD(1.0f));
1083   EXPECT_FLOAT_EQ(100.0f, value.width());
1084   EXPECT_LE(64.0f, value.height());
1085   EXPECT_GE(192.0f, value.height());
1086 
1087   EXPECT_SIZEF_EQ(size_b, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
1088   EXPECT_SIZEF_EQ(size_b, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
1089   EXPECT_SIZEF_EQ(size_b, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
1090 }
1091 
1092 }  // namespace
1093 }  // namespace cc
1094