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 "testing/gmock/include/gmock/gmock.h" 9 #include "testing/gtest/include/gtest/gtest.h" 10 11 namespace cc { 12 namespace { 13 14 void ExpectTranslateX(double translate_x, const gfx::Transform& transform) { 15 EXPECT_FLOAT_EQ(translate_x, transform.matrix().getDouble(0, 3)); 16 } 17 18 void ExpectBrightness(double brightness, const FilterOperations& filter) { 19 EXPECT_EQ(1u, filter.size()); 20 EXPECT_EQ(FilterOperation::BRIGHTNESS, filter.at(0).type()); 21 EXPECT_FLOAT_EQ(brightness, filter.at(0).amount()); 22 } 23 24 // Tests that a float animation with one keyframe works as expected. 25 TEST(KeyframedAnimationCurveTest, OneFloatKeyframe) { 26 scoped_ptr<KeyframedFloatAnimationCurve> curve( 27 KeyframedFloatAnimationCurve::Create()); 28 curve->AddKeyframe( 29 FloatKeyframe::Create(0.0, 2.f, scoped_ptr<TimingFunction>())); 30 EXPECT_FLOAT_EQ(2.f, curve->GetValue(-1.f)); 31 EXPECT_FLOAT_EQ(2.f, curve->GetValue(0.f)); 32 EXPECT_FLOAT_EQ(2.f, curve->GetValue(0.5f)); 33 EXPECT_FLOAT_EQ(2.f, curve->GetValue(1.f)); 34 EXPECT_FLOAT_EQ(2.f, curve->GetValue(2.f)); 35 } 36 37 // Tests that a float animation with two keyframes works as expected. 38 TEST(KeyframedAnimationCurveTest, TwoFloatKeyframe) { 39 scoped_ptr<KeyframedFloatAnimationCurve> curve( 40 KeyframedFloatAnimationCurve::Create()); 41 curve->AddKeyframe( 42 FloatKeyframe::Create(0.0, 2.f, scoped_ptr<TimingFunction>())); 43 curve->AddKeyframe( 44 FloatKeyframe::Create(1.0, 4.f, scoped_ptr<TimingFunction>())); 45 EXPECT_FLOAT_EQ(2.f, curve->GetValue(-1.f)); 46 EXPECT_FLOAT_EQ(2.f, curve->GetValue(0.f)); 47 EXPECT_FLOAT_EQ(3.f, curve->GetValue(0.5f)); 48 EXPECT_FLOAT_EQ(4.f, curve->GetValue(1.f)); 49 EXPECT_FLOAT_EQ(4.f, curve->GetValue(2.f)); 50 } 51 52 // Tests that a float animation with three keyframes works as expected. 53 TEST(KeyframedAnimationCurveTest, ThreeFloatKeyframe) { 54 scoped_ptr<KeyframedFloatAnimationCurve> curve( 55 KeyframedFloatAnimationCurve::Create()); 56 curve->AddKeyframe( 57 FloatKeyframe::Create(0.0, 2.f, scoped_ptr<TimingFunction>())); 58 curve->AddKeyframe( 59 FloatKeyframe::Create(1.0, 4.f, scoped_ptr<TimingFunction>())); 60 curve->AddKeyframe( 61 FloatKeyframe::Create(2.0, 8.f, scoped_ptr<TimingFunction>())); 62 EXPECT_FLOAT_EQ(2.f, curve->GetValue(-1.f)); 63 EXPECT_FLOAT_EQ(2.f, curve->GetValue(0.f)); 64 EXPECT_FLOAT_EQ(3.f, curve->GetValue(0.5f)); 65 EXPECT_FLOAT_EQ(4.f, curve->GetValue(1.f)); 66 EXPECT_FLOAT_EQ(6.f, curve->GetValue(1.5f)); 67 EXPECT_FLOAT_EQ(8.f, curve->GetValue(2.f)); 68 EXPECT_FLOAT_EQ(8.f, curve->GetValue(3.f)); 69 } 70 71 // Tests that a float animation with multiple keys at a given time works sanely. 72 TEST(KeyframedAnimationCurveTest, RepeatedFloatKeyTimes) { 73 scoped_ptr<KeyframedFloatAnimationCurve> curve( 74 KeyframedFloatAnimationCurve::Create()); 75 curve->AddKeyframe( 76 FloatKeyframe::Create(0.0, 4.f, scoped_ptr<TimingFunction>())); 77 curve->AddKeyframe( 78 FloatKeyframe::Create(1.0, 4.f, scoped_ptr<TimingFunction>())); 79 curve->AddKeyframe( 80 FloatKeyframe::Create(1.0, 6.f, scoped_ptr<TimingFunction>())); 81 curve->AddKeyframe( 82 FloatKeyframe::Create(2.0, 6.f, scoped_ptr<TimingFunction>())); 83 84 EXPECT_FLOAT_EQ(4.f, curve->GetValue(-1.f)); 85 EXPECT_FLOAT_EQ(4.f, curve->GetValue(0.f)); 86 EXPECT_FLOAT_EQ(4.f, curve->GetValue(0.5f)); 87 88 // There is a discontinuity at 1. Any value between 4 and 6 is valid. 89 float value = curve->GetValue(1.f); 90 EXPECT_TRUE(value >= 4 && value <= 6); 91 92 EXPECT_FLOAT_EQ(6.f, curve->GetValue(1.5f)); 93 EXPECT_FLOAT_EQ(6.f, curve->GetValue(2.f)); 94 EXPECT_FLOAT_EQ(6.f, curve->GetValue(3.f)); 95 } 96 97 // Tests that a transform animation with one keyframe works as expected. 98 TEST(KeyframedAnimationCurveTest, OneTransformKeyframe) { 99 scoped_ptr<KeyframedTransformAnimationCurve> curve( 100 KeyframedTransformAnimationCurve::Create()); 101 TransformOperations operations; 102 operations.AppendTranslate(2.f, 0.f, 0.f); 103 curve->AddKeyframe( 104 TransformKeyframe::Create(0.f, operations, scoped_ptr<TimingFunction>())); 105 106 ExpectTranslateX(2.f, curve->GetValue(-1.f)); 107 ExpectTranslateX(2.f, curve->GetValue(0.f)); 108 ExpectTranslateX(2.f, curve->GetValue(0.5f)); 109 ExpectTranslateX(2.f, curve->GetValue(1.f)); 110 ExpectTranslateX(2.f, curve->GetValue(2.f)); 111 } 112 113 // Tests that a transform animation with two keyframes works as expected. 114 TEST(KeyframedAnimationCurveTest, TwoTransformKeyframe) { 115 scoped_ptr<KeyframedTransformAnimationCurve> curve( 116 KeyframedTransformAnimationCurve::Create()); 117 TransformOperations operations1; 118 operations1.AppendTranslate(2.f, 0.f, 0.f); 119 TransformOperations operations2; 120 operations2.AppendTranslate(4.f, 0.f, 0.f); 121 122 curve->AddKeyframe(TransformKeyframe::Create( 123 0.f, operations1, scoped_ptr<TimingFunction>())); 124 curve->AddKeyframe(TransformKeyframe::Create( 125 1.f, operations2, scoped_ptr<TimingFunction>())); 126 ExpectTranslateX(2.f, curve->GetValue(-1.f)); 127 ExpectTranslateX(2.f, curve->GetValue(0.f)); 128 ExpectTranslateX(3.f, curve->GetValue(0.5f)); 129 ExpectTranslateX(4.f, curve->GetValue(1.f)); 130 ExpectTranslateX(4.f, curve->GetValue(2.f)); 131 } 132 133 // Tests that a transform animation with three keyframes works as expected. 134 TEST(KeyframedAnimationCurveTest, ThreeTransformKeyframe) { 135 scoped_ptr<KeyframedTransformAnimationCurve> curve( 136 KeyframedTransformAnimationCurve::Create()); 137 TransformOperations operations1; 138 operations1.AppendTranslate(2.f, 0.f, 0.f); 139 TransformOperations operations2; 140 operations2.AppendTranslate(4.f, 0.f, 0.f); 141 TransformOperations operations3; 142 operations3.AppendTranslate(8.f, 0.f, 0.f); 143 curve->AddKeyframe(TransformKeyframe::Create( 144 0.f, operations1, scoped_ptr<TimingFunction>())); 145 curve->AddKeyframe(TransformKeyframe::Create( 146 1.f, operations2, scoped_ptr<TimingFunction>())); 147 curve->AddKeyframe(TransformKeyframe::Create( 148 2.f, operations3, scoped_ptr<TimingFunction>())); 149 ExpectTranslateX(2.f, curve->GetValue(-1.f)); 150 ExpectTranslateX(2.f, curve->GetValue(0.f)); 151 ExpectTranslateX(3.f, curve->GetValue(0.5f)); 152 ExpectTranslateX(4.f, curve->GetValue(1.f)); 153 ExpectTranslateX(6.f, curve->GetValue(1.5f)); 154 ExpectTranslateX(8.f, curve->GetValue(2.f)); 155 ExpectTranslateX(8.f, curve->GetValue(3.f)); 156 } 157 158 // Tests that a transform animation with multiple keys at a given time works 159 // sanely. 160 TEST(KeyframedAnimationCurveTest, RepeatedTransformKeyTimes) { 161 scoped_ptr<KeyframedTransformAnimationCurve> curve( 162 KeyframedTransformAnimationCurve::Create()); 163 // A step function. 164 TransformOperations operations1; 165 operations1.AppendTranslate(4.f, 0.f, 0.f); 166 TransformOperations operations2; 167 operations2.AppendTranslate(4.f, 0.f, 0.f); 168 TransformOperations operations3; 169 operations3.AppendTranslate(6.f, 0.f, 0.f); 170 TransformOperations operations4; 171 operations4.AppendTranslate(6.f, 0.f, 0.f); 172 curve->AddKeyframe(TransformKeyframe::Create( 173 0.f, operations1, scoped_ptr<TimingFunction>())); 174 curve->AddKeyframe(TransformKeyframe::Create( 175 1.f, operations2, scoped_ptr<TimingFunction>())); 176 curve->AddKeyframe(TransformKeyframe::Create( 177 1.f, operations3, scoped_ptr<TimingFunction>())); 178 curve->AddKeyframe(TransformKeyframe::Create( 179 2.f, operations4, scoped_ptr<TimingFunction>())); 180 181 ExpectTranslateX(4.f, curve->GetValue(-1.f)); 182 ExpectTranslateX(4.f, curve->GetValue(0.f)); 183 ExpectTranslateX(4.f, curve->GetValue(0.5f)); 184 185 // There is a discontinuity at 1. Any value between 4 and 6 is valid. 186 gfx::Transform value = curve->GetValue(1.f); 187 EXPECT_GE(value.matrix().getDouble(0.f, 3.f), 4); 188 EXPECT_LE(value.matrix().getDouble(0.f, 3.f), 6); 189 190 ExpectTranslateX(6.f, curve->GetValue(1.5f)); 191 ExpectTranslateX(6.f, curve->GetValue(2.f)); 192 ExpectTranslateX(6.f, curve->GetValue(3.f)); 193 } 194 195 // Tests that a filter animation with one keyframe works as expected. 196 TEST(KeyframedAnimationCurveTest, OneFilterKeyframe) { 197 scoped_ptr<KeyframedFilterAnimationCurve> curve( 198 KeyframedFilterAnimationCurve::Create()); 199 FilterOperations operations; 200 operations.Append(FilterOperation::CreateBrightnessFilter(2.f)); 201 curve->AddKeyframe( 202 FilterKeyframe::Create(0.f, operations, scoped_ptr<TimingFunction>())); 203 204 ExpectBrightness(2.f, curve->GetValue(-1.f)); 205 ExpectBrightness(2.f, curve->GetValue(0.f)); 206 ExpectBrightness(2.f, curve->GetValue(0.5f)); 207 ExpectBrightness(2.f, curve->GetValue(1.f)); 208 ExpectBrightness(2.f, curve->GetValue(2.f)); 209 } 210 211 // Tests that a filter animation with two keyframes works as expected. 212 TEST(KeyframedAnimationCurveTest, TwoFilterKeyframe) { 213 scoped_ptr<KeyframedFilterAnimationCurve> curve( 214 KeyframedFilterAnimationCurve::Create()); 215 FilterOperations operations1; 216 operations1.Append(FilterOperation::CreateBrightnessFilter(2.f)); 217 FilterOperations operations2; 218 operations2.Append(FilterOperation::CreateBrightnessFilter(4.f)); 219 220 curve->AddKeyframe(FilterKeyframe::Create( 221 0.f, operations1, scoped_ptr<TimingFunction>())); 222 curve->AddKeyframe(FilterKeyframe::Create( 223 1.f, operations2, scoped_ptr<TimingFunction>())); 224 ExpectBrightness(2.f, curve->GetValue(-1.f)); 225 ExpectBrightness(2.f, curve->GetValue(0.f)); 226 ExpectBrightness(3.f, curve->GetValue(0.5f)); 227 ExpectBrightness(4.f, curve->GetValue(1.f)); 228 ExpectBrightness(4.f, curve->GetValue(2.f)); 229 } 230 231 // Tests that a filter animation with three keyframes works as expected. 232 TEST(KeyframedAnimationCurveTest, ThreeFilterKeyframe) { 233 scoped_ptr<KeyframedFilterAnimationCurve> curve( 234 KeyframedFilterAnimationCurve::Create()); 235 FilterOperations operations1; 236 operations1.Append(FilterOperation::CreateBrightnessFilter(2.f)); 237 FilterOperations operations2; 238 operations2.Append(FilterOperation::CreateBrightnessFilter(4.f)); 239 FilterOperations operations3; 240 operations3.Append(FilterOperation::CreateBrightnessFilter(8.f)); 241 curve->AddKeyframe(FilterKeyframe::Create( 242 0.f, operations1, scoped_ptr<TimingFunction>())); 243 curve->AddKeyframe(FilterKeyframe::Create( 244 1.f, operations2, scoped_ptr<TimingFunction>())); 245 curve->AddKeyframe(FilterKeyframe::Create( 246 2.f, operations3, scoped_ptr<TimingFunction>())); 247 ExpectBrightness(2.f, curve->GetValue(-1.f)); 248 ExpectBrightness(2.f, curve->GetValue(0.f)); 249 ExpectBrightness(3.f, curve->GetValue(0.5f)); 250 ExpectBrightness(4.f, curve->GetValue(1.f)); 251 ExpectBrightness(6.f, curve->GetValue(1.5f)); 252 ExpectBrightness(8.f, curve->GetValue(2.f)); 253 ExpectBrightness(8.f, curve->GetValue(3.f)); 254 } 255 256 // Tests that a filter animation with multiple keys at a given time works 257 // sanely. 258 TEST(KeyframedAnimationCurveTest, RepeatedFilterKeyTimes) { 259 scoped_ptr<KeyframedFilterAnimationCurve> curve( 260 KeyframedFilterAnimationCurve::Create()); 261 // A step function. 262 FilterOperations operations1; 263 operations1.Append(FilterOperation::CreateBrightnessFilter(4.f)); 264 FilterOperations operations2; 265 operations2.Append(FilterOperation::CreateBrightnessFilter(4.f)); 266 FilterOperations operations3; 267 operations3.Append(FilterOperation::CreateBrightnessFilter(6.f)); 268 FilterOperations operations4; 269 operations4.Append(FilterOperation::CreateBrightnessFilter(6.f)); 270 curve->AddKeyframe(FilterKeyframe::Create( 271 0.f, operations1, scoped_ptr<TimingFunction>())); 272 curve->AddKeyframe(FilterKeyframe::Create( 273 1.f, operations2, scoped_ptr<TimingFunction>())); 274 curve->AddKeyframe(FilterKeyframe::Create( 275 1.f, operations3, scoped_ptr<TimingFunction>())); 276 curve->AddKeyframe(FilterKeyframe::Create( 277 2.f, operations4, scoped_ptr<TimingFunction>())); 278 279 ExpectBrightness(4.f, curve->GetValue(-1.f)); 280 ExpectBrightness(4.f, curve->GetValue(0.f)); 281 ExpectBrightness(4.f, curve->GetValue(0.5f)); 282 283 // There is a discontinuity at 1. Any value between 4 and 6 is valid. 284 FilterOperations value = curve->GetValue(1.f); 285 EXPECT_EQ(1u, value.size()); 286 EXPECT_EQ(FilterOperation::BRIGHTNESS, value.at(0).type()); 287 EXPECT_GE(value.at(0).amount(), 4); 288 EXPECT_LE(value.at(0).amount(), 6); 289 290 ExpectBrightness(6.f, curve->GetValue(1.5f)); 291 ExpectBrightness(6.f, curve->GetValue(2.f)); 292 ExpectBrightness(6.f, curve->GetValue(3.f)); 293 } 294 295 // Tests that the keyframes may be added out of order. 296 TEST(KeyframedAnimationCurveTest, UnsortedKeyframes) { 297 scoped_ptr<KeyframedFloatAnimationCurve> curve( 298 KeyframedFloatAnimationCurve::Create()); 299 curve->AddKeyframe( 300 FloatKeyframe::Create(2.0, 8.f, scoped_ptr<TimingFunction>())); 301 curve->AddKeyframe( 302 FloatKeyframe::Create(0.0, 2.f, scoped_ptr<TimingFunction>())); 303 curve->AddKeyframe( 304 FloatKeyframe::Create(1.0, 4.f, scoped_ptr<TimingFunction>())); 305 EXPECT_FLOAT_EQ(2.f, curve->GetValue(-1.f)); 306 EXPECT_FLOAT_EQ(2.f, curve->GetValue(0.f)); 307 EXPECT_FLOAT_EQ(3.f, curve->GetValue(0.5f)); 308 EXPECT_FLOAT_EQ(4.f, curve->GetValue(1.f)); 309 EXPECT_FLOAT_EQ(6.f, curve->GetValue(1.5f)); 310 EXPECT_FLOAT_EQ(8.f, curve->GetValue(2.f)); 311 EXPECT_FLOAT_EQ(8.f, curve->GetValue(3.f)); 312 } 313 314 // Tests that a cubic bezier timing function works as expected. 315 TEST(KeyframedAnimationCurveTest, CubicBezierTimingFunction) { 316 scoped_ptr<KeyframedFloatAnimationCurve> curve( 317 KeyframedFloatAnimationCurve::Create()); 318 curve->AddKeyframe(FloatKeyframe::Create( 319 0.0, 320 0.f, 321 CubicBezierTimingFunction::Create(0.25f, 0.f, 0.75f, 1.f) 322 .PassAs<TimingFunction>())); 323 curve->AddKeyframe( 324 FloatKeyframe::Create(1.0, 1.f, scoped_ptr<TimingFunction>())); 325 326 EXPECT_FLOAT_EQ(0.f, curve->GetValue(0.f)); 327 EXPECT_LT(0.f, curve->GetValue(0.25f)); 328 EXPECT_GT(0.25f, curve->GetValue(0.25f)); 329 EXPECT_NEAR(curve->GetValue(0.5f), 0.5f, 0.00015f); 330 EXPECT_LT(0.75f, curve->GetValue(0.75f)); 331 EXPECT_GT(1.f, curve->GetValue(0.75f)); 332 EXPECT_FLOAT_EQ(1.f, curve->GetValue(1.f)); 333 } 334 335 } // namespace 336 } // namespace cc 337