1 /* 2 * Copyright (c) 2013, Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "config.h" 32 33 #include "core/animation/CompositorAnimations.h" 34 35 #include "core/animation/AnimatableDouble.h" 36 #include "core/animation/AnimatableFilterOperations.h" 37 #include "core/animation/AnimatableTransform.h" 38 #include "core/animation/AnimatableValueTestHelper.h" 39 #include "core/animation/CompositorAnimationsImpl.h" 40 #include "core/animation/CompositorAnimationsTestHelper.h" 41 #include "core/platform/animation/TimingFunctionTestHelper.h" 42 #include "platform/geometry/IntSize.h" 43 #include "platform/graphics/filters/FilterOperations.h" 44 #include "platform/transforms/TransformOperations.h" 45 #include "platform/transforms/TranslateTransformOperation.h" 46 #include "public/platform/WebAnimation.h" 47 #include "wtf/HashFunctions.h" 48 #include "wtf/OwnPtr.h" 49 #include "wtf/PassOwnPtr.h" 50 #include "wtf/PassRefPtr.h" 51 #include "wtf/RefPtr.h" 52 53 #include <gmock/gmock.h> 54 #include <gtest/gtest.h> 55 56 namespace WebCore { 57 58 using ::testing::CloneToPassOwnPtr; 59 using ::testing::ExpectationSet; 60 using ::testing::Ref; 61 using ::testing::Return; 62 using ::testing::_; 63 64 class AnimationCompositorAnimationsTest : public AnimationCompositorAnimationsTestBase { 65 66 protected: 67 RefPtr<TimingFunction> m_linearTimingFunction; 68 RefPtr<TimingFunction> m_cubicEaseTimingFunction; 69 RefPtr<TimingFunction> m_cubicCustomTimingFunction; 70 RefPtr<TimingFunction> m_stepTimingFunction; 71 72 Timing m_timing; 73 CompositorAnimationsImpl::CompositorTiming m_compositorTiming; 74 KeyframeAnimationEffect::KeyframeVector m_keyframeVector2; 75 RefPtr<KeyframeAnimationEffect> m_keyframeAnimationEffect2; 76 KeyframeAnimationEffect::KeyframeVector m_keyframeVector5; 77 RefPtr<KeyframeAnimationEffect> m_keyframeAnimationEffect5; 78 79 virtual void SetUp() 80 { 81 AnimationCompositorAnimationsTestBase::SetUp(); 82 83 m_linearTimingFunction = LinearTimingFunction::create(); 84 m_cubicEaseTimingFunction = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease); 85 m_cubicCustomTimingFunction = CubicBezierTimingFunction::create(1, 2, 3, 4); 86 m_stepTimingFunction = StepsTimingFunction::create(1, false); 87 88 m_timing = createCompositableTiming(); 89 m_compositorTiming = CompositorAnimationsImpl::CompositorTiming(); 90 // Make sure the CompositableTiming is really compositable, otherwise 91 // most other tests will fail. 92 ASSERT(convertTimingForCompositor(m_timing, m_compositorTiming)); 93 94 m_keyframeVector2 = createCompositableFloatKeyframeVector(2); 95 m_keyframeAnimationEffect2 = KeyframeAnimationEffect::create(m_keyframeVector2); 96 97 m_keyframeVector5 = createCompositableFloatKeyframeVector(5); 98 m_keyframeAnimationEffect5 = KeyframeAnimationEffect::create(m_keyframeVector5); 99 } 100 101 public: 102 103 bool convertTimingForCompositor(const Timing& t, CompositorAnimationsImpl::CompositorTiming& out) 104 { 105 return CompositorAnimationsImpl::convertTimingForCompositor(t, out); 106 } 107 bool isCandidateForAnimationOnCompositor(const Timing& timing, const AnimationEffect& effect) 108 { 109 return CompositorAnimations::instance()->isCandidateForAnimationOnCompositor(timing, effect); 110 } 111 void getAnimationOnCompositor(Timing& timing, KeyframeAnimationEffect& effect, Vector<OwnPtr<blink::WebAnimation> >& animations) 112 { 113 return CompositorAnimationsImpl::getAnimationOnCompositor(timing, effect, animations); 114 } 115 116 bool isCandidateHelperForSingleKeyframe(Keyframe* frame) 117 { 118 EXPECT_EQ(frame->offset(), 0); 119 KeyframeAnimationEffect::KeyframeVector frames; 120 frames.append(frame); 121 EXPECT_EQ(m_keyframeVector2[1]->offset(), 1.0); 122 frames.append(m_keyframeVector2[1]); 123 return isCandidateForAnimationOnCompositor(m_timing, *KeyframeAnimationEffect::create(frames).get()); 124 } 125 126 // ------------------------------------------------------------------- 127 128 Timing createCompositableTiming() 129 { 130 Timing timing; 131 timing.startDelay = 0; 132 timing.fillMode = Timing::FillModeNone; 133 timing.iterationStart = 0; 134 timing.iterationCount = 1; 135 timing.hasIterationDuration = true; 136 timing.iterationDuration = 1.0; 137 timing.playbackRate = 1.0; 138 timing.direction = Timing::PlaybackDirectionNormal; 139 ASSERT(m_linearTimingFunction); 140 timing.timingFunction = m_linearTimingFunction; 141 return timing; 142 } 143 144 PassRefPtr<Keyframe> createReplaceOpKeyframe(CSSPropertyID id, AnimatableValue* value, double offset = 0) 145 { 146 RefPtr<Keyframe> keyframe = Keyframe::create(); 147 keyframe->setPropertyValue(id, value); 148 keyframe->setComposite(AnimationEffect::CompositeReplace); 149 keyframe->setOffset(offset); 150 return keyframe; 151 } 152 153 PassRefPtr<Keyframe> createDefaultKeyframe(CSSPropertyID id, AnimationEffect::CompositeOperation op, double offset = 0) 154 { 155 RefPtr<AnimatableValue> value; 156 if (id == CSSPropertyWebkitTransform) 157 value = AnimatableTransform::create(TransformOperations()); 158 else 159 value = AnimatableDouble::create(10.0); 160 161 RefPtr<Keyframe> keyframe = createReplaceOpKeyframe(id, value.get(), offset); 162 keyframe->setComposite(op); 163 return keyframe; 164 } 165 166 KeyframeAnimationEffect::KeyframeVector createCompositableFloatKeyframeVector(size_t n) 167 { 168 Vector<double> values; 169 for (size_t i = 0; i < n; i++) { 170 values.append(static_cast<double>(i)); 171 } 172 return createCompositableFloatKeyframeVector(values); 173 } 174 175 KeyframeAnimationEffect::KeyframeVector createCompositableFloatKeyframeVector(Vector<double>& values) 176 { 177 KeyframeAnimationEffect::KeyframeVector frames; 178 for (size_t i = 0; i < values.size(); i++) { 179 double offset = 1.0 / (values.size() - 1) * i; 180 RefPtr<AnimatableDouble> value = AnimatableDouble::create(values[i]); 181 frames.append(createReplaceOpKeyframe(CSSPropertyOpacity, value.get(), offset).get()); 182 } 183 return frames; 184 } 185 186 PassRefPtr<KeyframeAnimationEffect> createKeyframeAnimationEffect(PassRefPtr<Keyframe> prpFrom, PassRefPtr<Keyframe> prpTo, PassRefPtr<Keyframe> prpC = 0, PassRefPtr<Keyframe> prpD = 0) 187 { 188 RefPtr<Keyframe> from = prpFrom; 189 RefPtr<Keyframe> to = prpTo; 190 RefPtr<Keyframe> c = prpC; 191 RefPtr<Keyframe> d = prpD; 192 193 EXPECT_EQ(from->offset(), 0); 194 KeyframeAnimationEffect::KeyframeVector frames; 195 frames.append(from); 196 EXPECT_LE(from->offset(), to->offset()); 197 frames.append(to); 198 if (c) { 199 EXPECT_LE(to->offset(), c->offset()); 200 frames.append(c); 201 } 202 if (d) { 203 frames.append(d); 204 EXPECT_LE(c->offset(), d->offset()); 205 EXPECT_EQ(d->offset(), 1.0); 206 } else { 207 EXPECT_EQ(to->offset(), 1.0); 208 } 209 if (!HasFatalFailure()) { 210 return KeyframeAnimationEffect::create(frames); 211 } 212 return PassRefPtr<KeyframeAnimationEffect>(); 213 } 214 215 }; 216 217 class CustomFilterOperationMock : public FilterOperation { 218 public: 219 virtual bool operator==(const FilterOperation&) const OVERRIDE FINAL { 220 ASSERT_NOT_REACHED(); 221 return false; 222 } 223 224 MOCK_CONST_METHOD2(blend, PassRefPtr<FilterOperation>(const FilterOperation*, double)); 225 226 static PassRefPtr<CustomFilterOperationMock> create() 227 { 228 return adoptRef(new CustomFilterOperationMock()); 229 } 230 231 CustomFilterOperationMock() 232 : FilterOperation(FilterOperation::CUSTOM) 233 { 234 } 235 }; 236 237 // ----------------------------------------------------------------------- 238 // ----------------------------------------------------------------------- 239 240 TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorKeyframeMultipleCSSProperties) 241 { 242 RefPtr<Keyframe> keyframeGoodMultiple = createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace); 243 keyframeGoodMultiple->setPropertyValue(CSSPropertyWebkitTransform, AnimatableTransform::create(TransformOperations()).get()); 244 EXPECT_TRUE(isCandidateHelperForSingleKeyframe(keyframeGoodMultiple.get())); 245 246 RefPtr<Keyframe> keyframeBadMultipleOp = createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeAdd); 247 keyframeBadMultipleOp->setPropertyValue(CSSPropertyWebkitTransform, AnimatableDouble::create(10.0).get()); 248 EXPECT_FALSE(isCandidateHelperForSingleKeyframe(keyframeBadMultipleOp.get())); 249 250 // Check both an unsupported property which hashes before and after the 251 // supported property. 252 typedef DefaultHash<CSSPropertyID>::Hash HashFunctions; 253 254 RefPtr<Keyframe> keyframeBadMultiple1ID = createDefaultKeyframe(CSSPropertyColor, AnimationEffect::CompositeReplace); 255 keyframeBadMultiple1ID->setPropertyValue(CSSPropertyOpacity, AnimatableDouble::create(10.0).get()); 256 EXPECT_FALSE(isCandidateHelperForSingleKeyframe(keyframeBadMultiple1ID.get())); 257 EXPECT_LT(HashFunctions::hash(CSSPropertyColor), HashFunctions::hash(CSSPropertyOpacity)); 258 259 RefPtr<Keyframe> keyframeBadMultiple2ID = createDefaultKeyframe(CSSPropertyWebkitTransform, AnimationEffect::CompositeReplace); 260 keyframeBadMultiple2ID->setPropertyValue(CSSPropertyWidth, AnimatableDouble::create(10.0).get()); 261 EXPECT_FALSE(isCandidateHelperForSingleKeyframe(keyframeBadMultiple2ID.get())); 262 EXPECT_GT(HashFunctions::hash(CSSPropertyWebkitTransform), HashFunctions::hash(CSSPropertyWidth)); 263 } 264 265 TEST_F(AnimationCompositorAnimationsTest, isNotCandidateForCompositorAnimationTransformDependsOnBoxSize) 266 { 267 TransformOperations ops; 268 ops.operations().append(TranslateTransformOperation::create(Length(2, WebCore::Fixed), Length(2, WebCore::Fixed), TransformOperation::TranslateX)); 269 RefPtr<Keyframe> goodKeyframe = createReplaceOpKeyframe(CSSPropertyWebkitTransform, AnimatableTransform::create(ops).get()); 270 EXPECT_TRUE(isCandidateHelperForSingleKeyframe(goodKeyframe.get())); 271 272 ops.operations().append(TranslateTransformOperation::create(Length(50, WebCore::Percent), Length(2, WebCore::Fixed), TransformOperation::TranslateX)); 273 RefPtr<Keyframe> badKeyframe = createReplaceOpKeyframe(CSSPropertyWebkitTransform, AnimatableTransform::create(ops).get()); 274 EXPECT_FALSE(isCandidateHelperForSingleKeyframe(badKeyframe.get())); 275 276 TransformOperations ops2; 277 Length calcLength = Length(100, WebCore::Percent).blend(Length(100, WebCore::Fixed), 0.5, WebCore::ValueRangeAll); 278 ops2.operations().append(TranslateTransformOperation::create(calcLength, Length(0, WebCore::Fixed), TransformOperation::TranslateX)); 279 RefPtr<Keyframe> badKeyframe2 = createReplaceOpKeyframe(CSSPropertyWebkitTransform, AnimatableTransform::create(ops2).get()); 280 EXPECT_FALSE(isCandidateHelperForSingleKeyframe(badKeyframe2.get())); 281 } 282 283 TEST_F(AnimationCompositorAnimationsTest, isNotCandidateForCompositorAnimationCustomFilter) 284 { 285 FilterOperations ops; 286 ops.operations().append(BasicColorMatrixFilterOperation::create(0.5, FilterOperation::SATURATE)); 287 RefPtr<Keyframe> goodKeyframe = createReplaceOpKeyframe(CSSPropertyWebkitFilter, AnimatableFilterOperations::create(ops).get()); 288 EXPECT_TRUE(isCandidateHelperForSingleKeyframe(goodKeyframe.get())); 289 290 ops.operations().append(CustomFilterOperationMock::create()); 291 RefPtr<Keyframe> badKeyframe = createReplaceOpKeyframe(CSSPropertyFilter, AnimatableFilterOperations::create(ops).get()); 292 EXPECT_FALSE(isCandidateHelperForSingleKeyframe(badKeyframe.get())); 293 } 294 295 TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorKeyframeEffectMultipleFramesOkay) 296 { 297 KeyframeAnimationEffect::KeyframeVector framesSame; 298 framesSame.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 0.0).get()); 299 framesSame.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 1.0).get()); 300 EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *KeyframeAnimationEffect::create(framesSame).get())); 301 302 KeyframeAnimationEffect::KeyframeVector framesMixed; 303 framesMixed.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 0.0).get()); 304 framesMixed.append(createDefaultKeyframe(CSSPropertyWebkitTransform, AnimationEffect::CompositeReplace, 1.0).get()); 305 EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *KeyframeAnimationEffect::create(framesMixed).get())); 306 } 307 308 TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorKeyframeEffectMultipleFramesNotOkay) 309 { 310 KeyframeAnimationEffect::KeyframeVector framesSame; 311 framesSame.append(createDefaultKeyframe(CSSPropertyColor, AnimationEffect::CompositeReplace, 0.0).get()); 312 framesSame.append(createDefaultKeyframe(CSSPropertyColor, AnimationEffect::CompositeReplace, 1.0).get()); 313 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *KeyframeAnimationEffect::create(framesSame).get())); 314 315 KeyframeAnimationEffect::KeyframeVector framesMixedProperties; 316 framesMixedProperties.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 0.0).get()); 317 framesMixedProperties.append(createDefaultKeyframe(CSSPropertyColor, AnimationEffect::CompositeReplace, 1.0).get()); 318 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *KeyframeAnimationEffect::create(framesMixedProperties).get())); 319 320 KeyframeAnimationEffect::KeyframeVector framesMixedOps; 321 framesMixedOps.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 0.0).get()); 322 framesMixedOps.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeAdd, 1.0).get()); 323 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *KeyframeAnimationEffect::create(framesMixedOps).get())); 324 } 325 326 TEST_F(AnimationCompositorAnimationsTest, ConvertTimingForCompositorStartDelay) 327 { 328 m_timing.iterationDuration = 20.0; 329 330 m_timing.startDelay = 2.0; 331 EXPECT_TRUE(convertTimingForCompositor(m_timing, m_compositorTiming)); 332 EXPECT_DOUBLE_EQ(-2.0, m_compositorTiming.scaledTimeOffset); 333 334 m_timing.startDelay = -2.0; 335 EXPECT_TRUE(convertTimingForCompositor(m_timing, m_compositorTiming)); 336 EXPECT_DOUBLE_EQ(2.0, m_compositorTiming.scaledTimeOffset); 337 } 338 339 TEST_F(AnimationCompositorAnimationsTest, ConvertTimingForCompositorIterationStart) 340 { 341 m_timing.iterationStart = 2.2; 342 EXPECT_FALSE(convertTimingForCompositor(m_timing, m_compositorTiming)); 343 } 344 345 TEST_F(AnimationCompositorAnimationsTest, ConvertTimingForCompositorIterationCount) 346 { 347 m_timing.iterationCount = 5.0; 348 EXPECT_TRUE(convertTimingForCompositor(m_timing, m_compositorTiming)); 349 EXPECT_EQ(5, m_compositorTiming.adjustedIterationCount); 350 351 m_timing.iterationCount = 5.5; 352 EXPECT_FALSE(convertTimingForCompositor(m_timing, m_compositorTiming)); 353 354 // Asserts will only trigger on DEBUG build. 355 // EXPECT_DEATH tests are flaky on Android. 356 #if !defined(NDEBUG) && !OS(ANDROID) 357 m_timing.iterationCount = -1; 358 EXPECT_DEATH(convertTimingForCompositor(m_timing, m_compositorTiming), ""); 359 #endif 360 361 m_timing.iterationCount = std::numeric_limits<double>::infinity(); 362 EXPECT_TRUE(convertTimingForCompositor(m_timing, m_compositorTiming)); 363 EXPECT_EQ(-1, m_compositorTiming.adjustedIterationCount); 364 365 m_timing.iterationCount = std::numeric_limits<double>::infinity(); 366 m_timing.iterationDuration = 5.0; 367 m_timing.startDelay = -6.0; 368 EXPECT_TRUE(convertTimingForCompositor(m_timing, m_compositorTiming)); 369 EXPECT_DOUBLE_EQ(6.0, m_compositorTiming.scaledTimeOffset); 370 EXPECT_EQ(-1, m_compositorTiming.adjustedIterationCount); 371 } 372 373 TEST_F(AnimationCompositorAnimationsTest, ConvertTimingForCompositorIterationsAndStartDelay) 374 { 375 m_timing.iterationCount = 4.0; 376 m_timing.iterationDuration = 5.0; 377 378 m_timing.startDelay = 6.0; 379 EXPECT_TRUE(convertTimingForCompositor(m_timing, m_compositorTiming)); 380 EXPECT_DOUBLE_EQ(-6.0, m_compositorTiming.scaledTimeOffset); 381 EXPECT_DOUBLE_EQ(4.0, m_compositorTiming.adjustedIterationCount); 382 383 m_timing.startDelay = -6.0; 384 EXPECT_TRUE(convertTimingForCompositor(m_timing, m_compositorTiming)); 385 EXPECT_DOUBLE_EQ(6.0, m_compositorTiming.scaledTimeOffset); 386 EXPECT_DOUBLE_EQ(4.0, m_compositorTiming.adjustedIterationCount); 387 388 m_timing.startDelay = 21.0; 389 EXPECT_FALSE(convertTimingForCompositor(m_timing, m_compositorTiming)); 390 } 391 392 TEST_F(AnimationCompositorAnimationsTest, ConvertTimingForCompositorPlaybackRate) 393 { 394 m_timing.playbackRate = 2.0; 395 EXPECT_FALSE(convertTimingForCompositor(m_timing, m_compositorTiming)); 396 397 m_timing.playbackRate = 0.0; 398 EXPECT_FALSE(convertTimingForCompositor(m_timing, m_compositorTiming)); 399 400 m_timing.playbackRate = -2.0; 401 EXPECT_FALSE(convertTimingForCompositor(m_timing, m_compositorTiming)); 402 } 403 404 TEST_F(AnimationCompositorAnimationsTest, ConvertTimingForCompositorDirection) 405 { 406 m_timing.direction = Timing::PlaybackDirectionAlternate; 407 EXPECT_TRUE(convertTimingForCompositor(m_timing, m_compositorTiming)); 408 EXPECT_TRUE(m_compositorTiming.alternate); 409 EXPECT_FALSE(m_compositorTiming.reverse); 410 411 m_timing.direction = Timing::PlaybackDirectionAlternateReverse; 412 EXPECT_TRUE(convertTimingForCompositor(m_timing, m_compositorTiming)); 413 EXPECT_TRUE(m_compositorTiming.alternate); 414 EXPECT_TRUE(m_compositorTiming.reverse); 415 416 m_timing.direction = Timing::PlaybackDirectionReverse; 417 EXPECT_TRUE(convertTimingForCompositor(m_timing, m_compositorTiming)); 418 EXPECT_FALSE(m_compositorTiming.alternate); 419 EXPECT_TRUE(m_compositorTiming.reverse); 420 } 421 422 TEST_F(AnimationCompositorAnimationsTest, ConvertTimingForCompositorDirectionIterationsAndStartDelay) 423 { 424 m_timing.direction = Timing::PlaybackDirectionAlternate; 425 m_timing.iterationCount = 4.0; 426 m_timing.iterationDuration = 5.0; 427 m_timing.startDelay = -6.0; 428 EXPECT_TRUE(convertTimingForCompositor(m_timing, m_compositorTiming)); 429 EXPECT_DOUBLE_EQ(6.0, m_compositorTiming.scaledTimeOffset); 430 EXPECT_EQ(4, m_compositorTiming.adjustedIterationCount); 431 EXPECT_TRUE(m_compositorTiming.alternate); 432 EXPECT_FALSE(m_compositorTiming.reverse); 433 434 m_timing.direction = Timing::PlaybackDirectionAlternate; 435 m_timing.iterationCount = 4.0; 436 m_timing.iterationDuration = 5.0; 437 m_timing.startDelay = -11.0; 438 EXPECT_TRUE(convertTimingForCompositor(m_timing, m_compositorTiming)); 439 EXPECT_DOUBLE_EQ(11.0, m_compositorTiming.scaledTimeOffset); 440 EXPECT_EQ(4, m_compositorTiming.adjustedIterationCount); 441 EXPECT_TRUE(m_compositorTiming.alternate); 442 EXPECT_FALSE(m_compositorTiming.reverse); 443 444 m_timing.direction = Timing::PlaybackDirectionAlternateReverse; 445 m_timing.iterationCount = 4.0; 446 m_timing.iterationDuration = 5.0; 447 m_timing.startDelay = -6.0; 448 EXPECT_TRUE(convertTimingForCompositor(m_timing, m_compositorTiming)); 449 EXPECT_DOUBLE_EQ(6.0, m_compositorTiming.scaledTimeOffset); 450 EXPECT_EQ(4, m_compositorTiming.adjustedIterationCount); 451 EXPECT_TRUE(m_compositorTiming.alternate); 452 EXPECT_TRUE(m_compositorTiming.reverse); 453 454 m_timing.direction = Timing::PlaybackDirectionAlternateReverse; 455 m_timing.iterationCount = 4.0; 456 m_timing.iterationDuration = 5.0; 457 m_timing.startDelay = -11.0; 458 EXPECT_TRUE(convertTimingForCompositor(m_timing, m_compositorTiming)); 459 EXPECT_DOUBLE_EQ(11.0, m_compositorTiming.scaledTimeOffset); 460 EXPECT_EQ(4, m_compositorTiming.adjustedIterationCount); 461 EXPECT_TRUE(m_compositorTiming.alternate); 462 EXPECT_TRUE(m_compositorTiming.reverse); 463 } 464 465 TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingTimingFunctionPassThru) 466 { 467 m_timing.timingFunction = m_stepTimingFunction; 468 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get())); 469 } 470 471 TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionLinear) 472 { 473 m_timing.timingFunction = m_linearTimingFunction; 474 EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get())); 475 EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get())); 476 } 477 478 TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionCubic) 479 { 480 // Cubic bezier are okay if we only have two keyframes 481 m_timing.timingFunction = m_cubicEaseTimingFunction; 482 EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get())); 483 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get())); 484 485 m_timing.timingFunction = m_cubicCustomTimingFunction; 486 EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get())); 487 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get())); 488 } 489 490 TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionSteps) 491 { 492 m_timing.timingFunction = m_stepTimingFunction; 493 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get())); 494 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get())); 495 } 496 497 TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionChainedEmpty) 498 { 499 RefPtr<ChainedTimingFunction> chainedEmpty = ChainedTimingFunction::create(); 500 m_timing.timingFunction = chainedEmpty; 501 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get())); 502 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get())); 503 } 504 505 TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionChainedLinear) 506 { 507 RefPtr<ChainedTimingFunction> chainedLinearSingle = ChainedTimingFunction::create(); 508 chainedLinearSingle->appendSegment(1.0, m_linearTimingFunction.get()); 509 m_timing.timingFunction = chainedLinearSingle; 510 EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get())); 511 512 RefPtr<ChainedTimingFunction> chainedLinearMultiple = ChainedTimingFunction::create(); 513 chainedLinearMultiple->appendSegment(0.25, m_linearTimingFunction.get()); 514 chainedLinearMultiple->appendSegment(0.5, m_linearTimingFunction.get()); 515 chainedLinearMultiple->appendSegment(0.75, m_linearTimingFunction.get()); 516 chainedLinearMultiple->appendSegment(1.0, m_linearTimingFunction.get()); 517 m_timing.timingFunction = chainedLinearMultiple; 518 EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get())); 519 520 // FIXME: Technically a chained timing function of linear functions don't 521 // have to be aligned to keyframes. We don't support that currently as 522 // nothing generates that yet. 523 } 524 525 TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionChainedCubicMatchingOffsets) 526 { 527 RefPtr<ChainedTimingFunction> chainedSingleAGood = ChainedTimingFunction::create(); 528 chainedSingleAGood->appendSegment(1.0, m_cubicEaseTimingFunction.get()); 529 m_timing.timingFunction = chainedSingleAGood; 530 EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get())); 531 532 RefPtr<ChainedTimingFunction> chainedSingleBGood = ChainedTimingFunction::create(); 533 chainedSingleBGood->appendSegment(1.0, m_cubicCustomTimingFunction.get()); 534 m_timing.timingFunction = chainedSingleBGood; 535 EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get())); 536 537 RefPtr<ChainedTimingFunction> chainedMultipleGood = ChainedTimingFunction::create(); 538 chainedMultipleGood->appendSegment(0.25, m_cubicEaseTimingFunction.get()); 539 chainedMultipleGood->appendSegment(0.5, m_cubicCustomTimingFunction.get()); 540 chainedMultipleGood->appendSegment(0.75, m_cubicCustomTimingFunction.get()); 541 chainedMultipleGood->appendSegment(1.0, m_cubicCustomTimingFunction.get()); 542 m_timing.timingFunction = chainedMultipleGood; 543 EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get())); 544 } 545 546 TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionChainedCubicNonMatchingOffsets) 547 { 548 RefPtr<ChainedTimingFunction> chained0 = ChainedTimingFunction::create(); 549 chained0->appendSegment(0.5, m_cubicEaseTimingFunction.get()); 550 m_timing.timingFunction = chained0; 551 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get())); 552 553 RefPtr<ChainedTimingFunction> chained1 = ChainedTimingFunction::create(); 554 chained1->appendSegment(0.24, m_cubicEaseTimingFunction.get()); 555 chained1->appendSegment(0.5, m_cubicEaseTimingFunction.get()); 556 chained1->appendSegment(0.75, m_cubicEaseTimingFunction.get()); 557 chained1->appendSegment(1.0, m_cubicEaseTimingFunction.get()); 558 m_timing.timingFunction = chained1; 559 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get())); 560 561 RefPtr<ChainedTimingFunction> chained2 = ChainedTimingFunction::create(); 562 chained2->appendSegment(0.25, m_cubicEaseTimingFunction.get()); 563 chained2->appendSegment(0.51, m_cubicEaseTimingFunction.get()); 564 chained2->appendSegment(0.75, m_cubicEaseTimingFunction.get()); 565 chained2->appendSegment(1.0, m_cubicEaseTimingFunction.get()); 566 m_timing.timingFunction = chained2; 567 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get())); 568 569 RefPtr<ChainedTimingFunction> chained3 = ChainedTimingFunction::create(); 570 chained3->appendSegment(0.25, m_cubicEaseTimingFunction.get()); 571 chained3->appendSegment(0.5, m_cubicEaseTimingFunction.get()); 572 chained3->appendSegment(0.75, m_cubicEaseTimingFunction.get()); 573 chained3->appendSegment(0.8, m_cubicEaseTimingFunction.get()); 574 m_timing.timingFunction = chained3; 575 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get())); 576 577 RefPtr<ChainedTimingFunction> chained4 = ChainedTimingFunction::create(); 578 chained4->appendSegment(0.25, m_cubicEaseTimingFunction.get()); 579 chained4->appendSegment(0.5, m_cubicEaseTimingFunction.get()); 580 chained4->appendSegment(0.75, m_cubicEaseTimingFunction.get()); 581 chained4->appendSegment(1.1, m_cubicEaseTimingFunction.get()); 582 m_timing.timingFunction = chained4; 583 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get())); 584 } 585 586 TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionMissingFrames) 587 { 588 // Missing first 589 RefPtr<ChainedTimingFunction> chained1 = ChainedTimingFunction::create(); 590 chained1->appendSegment(0.5, m_cubicEaseTimingFunction.get()); 591 chained1->appendSegment(0.75, m_cubicEaseTimingFunction.get()); 592 chained1->appendSegment(1.0, m_cubicEaseTimingFunction.get()); 593 m_timing.timingFunction = chained1; 594 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get())); 595 596 // Missing middle 597 RefPtr<ChainedTimingFunction> chained2 = ChainedTimingFunction::create(); 598 chained2->appendSegment(0.25, m_cubicEaseTimingFunction.get()); 599 chained2->appendSegment(0.75, m_cubicEaseTimingFunction.get()); 600 chained2->appendSegment(1.0, m_cubicEaseTimingFunction.get()); 601 m_timing.timingFunction = chained2; 602 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get())); 603 604 // Missing last 605 RefPtr<ChainedTimingFunction> chained3 = ChainedTimingFunction::create(); 606 chained3->appendSegment(0.25, m_cubicEaseTimingFunction.get()); 607 chained3->appendSegment(0.5, m_cubicEaseTimingFunction.get()); 608 chained3->appendSegment(0.75, m_cubicEaseTimingFunction.get()); 609 m_timing.timingFunction = chained3; 610 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get())); 611 } 612 613 TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionToManyFrames) 614 { 615 RefPtr<ChainedTimingFunction> chained1 = ChainedTimingFunction::create(); 616 chained1->appendSegment(0.1, m_cubicEaseTimingFunction.get()); 617 chained1->appendSegment(0.5, m_cubicEaseTimingFunction.get()); 618 m_timing.timingFunction = chained1; 619 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get())); 620 621 RefPtr<ChainedTimingFunction> chained2 = ChainedTimingFunction::create(); 622 chained2->appendSegment(0.1, m_cubicEaseTimingFunction.get()); 623 chained2->appendSegment(0.25, m_cubicEaseTimingFunction.get()); 624 chained2->appendSegment(0.5, m_cubicEaseTimingFunction.get()); 625 chained2->appendSegment(0.75, m_cubicEaseTimingFunction.get()); 626 chained2->appendSegment(1.0, m_cubicEaseTimingFunction.get()); 627 m_timing.timingFunction = chained2; 628 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get())); 629 } 630 631 TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionMixedGood) 632 { 633 RefPtr<ChainedTimingFunction> chainedMixed = ChainedTimingFunction::create(); 634 chainedMixed->appendSegment(0.25, m_linearTimingFunction.get()); 635 chainedMixed->appendSegment(0.5, m_cubicEaseTimingFunction.get()); 636 chainedMixed->appendSegment(0.75, m_cubicEaseTimingFunction.get()); 637 chainedMixed->appendSegment(1.0, m_linearTimingFunction.get()); 638 m_timing.timingFunction = chainedMixed; 639 EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get())); 640 } 641 642 TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionWithStepNotOkay) 643 { 644 RefPtr<ChainedTimingFunction> chainedStepSingle = ChainedTimingFunction::create(); 645 chainedStepSingle->appendSegment(1.0, m_stepTimingFunction.get()); 646 m_timing.timingFunction = chainedStepSingle; 647 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get())); 648 649 RefPtr<ChainedTimingFunction> chainedStepMixedA = ChainedTimingFunction::create(); 650 chainedStepMixedA->appendSegment(0.25, m_stepTimingFunction.get()); 651 chainedStepMixedA->appendSegment(0.5, m_linearTimingFunction.get()); 652 chainedStepMixedA->appendSegment(1.0, m_cubicEaseTimingFunction.get()); 653 m_timing.timingFunction = chainedStepMixedA; 654 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get())); 655 656 RefPtr<ChainedTimingFunction> chainedStepMixedB = ChainedTimingFunction::create(); 657 chainedStepMixedB->appendSegment(0.25, m_linearTimingFunction.get()); 658 chainedStepMixedB->appendSegment(0.5, m_stepTimingFunction.get()); 659 chainedStepMixedB->appendSegment(1.0, m_cubicEaseTimingFunction.get()); 660 m_timing.timingFunction = chainedStepMixedB; 661 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get())); 662 663 RefPtr<ChainedTimingFunction> chainedStepMixedC = ChainedTimingFunction::create(); 664 chainedStepMixedC->appendSegment(0.25, m_linearTimingFunction.get()); 665 chainedStepMixedC->appendSegment(0.5, m_cubicEaseTimingFunction.get()); 666 chainedStepMixedC->appendSegment(1.0, m_stepTimingFunction.get()); 667 m_timing.timingFunction = chainedStepMixedC; 668 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get())); 669 } 670 671 TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionNestedNotOkay) 672 { 673 RefPtr<ChainedTimingFunction> chainedChild = ChainedTimingFunction::create(); 674 chainedChild->appendSegment(1.0, m_linearTimingFunction.get()); 675 676 RefPtr<ChainedTimingFunction> chainedParent = ChainedTimingFunction::create(); 677 chainedParent->appendSegment(0.25, m_linearTimingFunction.get()); 678 chainedParent->appendSegment(0.5, chainedChild.get()); 679 chainedParent->appendSegment(0.75, m_linearTimingFunction.get()); 680 chainedParent->appendSegment(1.0, m_linearTimingFunction.get()); 681 m_timing.timingFunction = chainedParent; 682 EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get())); 683 } 684 685 TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositor) 686 { 687 Timing linearTiming(createCompositableTiming()); 688 689 RefPtr<TimingFunction> cubicTimingFunc = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn); 690 Timing cubicTiming(createCompositableTiming()); 691 cubicTiming.timingFunction = cubicTimingFunc; 692 693 RefPtr<ChainedTimingFunction> chainedTimingFunc = ChainedTimingFunction::create(); 694 chainedTimingFunc->appendSegment(0.5, m_linearTimingFunction.get()); 695 chainedTimingFunc->appendSegment(1.0, cubicTimingFunc.get()); 696 Timing chainedTiming(createCompositableTiming()); 697 chainedTiming.timingFunction = chainedTimingFunc; 698 699 KeyframeAnimationEffect::KeyframeVector basicFramesVector; 700 basicFramesVector.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 0.0).get()); 701 basicFramesVector.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 1.0).get()); 702 RefPtr<KeyframeAnimationEffect> basicFrames = KeyframeAnimationEffect::create(basicFramesVector).get(); 703 704 EXPECT_TRUE(isCandidateForAnimationOnCompositor(linearTiming, *basicFrames.get())); 705 EXPECT_TRUE(isCandidateForAnimationOnCompositor(cubicTiming, *basicFrames.get())); 706 // number of timing function and keyframes don't match 707 EXPECT_FALSE(isCandidateForAnimationOnCompositor(chainedTiming, *basicFrames.get())); 708 709 KeyframeAnimationEffect::KeyframeVector nonBasicFramesVector; 710 nonBasicFramesVector.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 0.0).get()); 711 nonBasicFramesVector.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 0.5).get()); 712 nonBasicFramesVector.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 1.0).get()); 713 RefPtr<KeyframeAnimationEffect> nonBasicFrames = KeyframeAnimationEffect::create(nonBasicFramesVector).get(); 714 715 EXPECT_TRUE(CompositorAnimations::instance()->isCandidateForAnimationOnCompositor(linearTiming, *nonBasicFrames.get())); 716 EXPECT_FALSE(CompositorAnimations::instance()->isCandidateForAnimationOnCompositor(cubicTiming, *nonBasicFrames.get())); 717 EXPECT_TRUE(CompositorAnimations::instance()->isCandidateForAnimationOnCompositor(chainedTiming, *nonBasicFrames.get())); 718 } 719 720 // ----------------------------------------------------------------------- 721 // ----------------------------------------------------------------------- 722 723 TEST_F(AnimationCompositorAnimationsTest, createSimpleOpacityAnimation) 724 { 725 // Animation to convert 726 RefPtr<KeyframeAnimationEffect> effect = createKeyframeAnimationEffect( 727 createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0), 728 createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(5.0).get(), 1.0)); 729 // -- 730 731 WebCompositorSupportMock mockCompositor; 732 733 // Curve is created 734 blink::WebFloatAnimationCurveMock* mockCurvePtr = new blink::WebFloatAnimationCurveMock; 735 ExpectationSet usesMockCurve; 736 EXPECT_CALL(mockCompositor, createFloatAnimationCurve()) 737 .WillOnce(Return(mockCurvePtr)); 738 739 usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(0.0, 2.0), blink::WebAnimationCurve::TimingFunctionTypeLinear)); 740 usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(1.0, 5.0))); 741 742 // Create animation 743 blink::WebAnimationMock* mockAnimationPtr = new blink::WebAnimationMock(blink::WebAnimation::TargetPropertyOpacity); 744 ExpectationSet usesMockAnimation; 745 746 usesMockCurve += EXPECT_CALL(mockCompositor, createAnimation(Ref(*mockCurvePtr), blink::WebAnimation::TargetPropertyOpacity, _)) 747 .WillOnce(Return(mockAnimationPtr)); 748 749 usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(1)); 750 usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(0.0)); 751 usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setAlternatesDirection(false)); 752 753 EXPECT_CALL(*mockAnimationPtr, delete_()) 754 .Times(1) 755 .After(usesMockAnimation); 756 EXPECT_CALL(*mockCurvePtr, delete_()) 757 .Times(1) 758 .After(usesMockCurve); 759 760 // Go! 761 setCompositorForTesting(mockCompositor); 762 Vector<OwnPtr<blink::WebAnimation> > result; 763 getAnimationOnCompositor(m_timing, *effect.get(), result); 764 EXPECT_EQ(1U, result.size()); 765 result[0].clear(); 766 } 767 768 TEST_F(AnimationCompositorAnimationsTest, createSimpleOpacityAnimationDuration) 769 { 770 // Animation to convert 771 RefPtr<KeyframeAnimationEffect> effect = createKeyframeAnimationEffect( 772 createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0), 773 createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(5.0).get(), 1.0)); 774 775 m_timing.iterationDuration = 10.0; 776 // -- 777 778 WebCompositorSupportMock mockCompositor; 779 780 // Curve is created 781 blink::WebFloatAnimationCurveMock* mockCurvePtr = new blink::WebFloatAnimationCurveMock; 782 ExpectationSet usesMockCurve; 783 EXPECT_CALL(mockCompositor, createFloatAnimationCurve()) 784 .WillOnce(Return(mockCurvePtr)); 785 786 usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(0.0, 2.0), blink::WebAnimationCurve::TimingFunctionTypeLinear)); 787 usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(10.0, 5.0))); 788 789 // Create animation 790 blink::WebAnimationMock* mockAnimationPtr = new blink::WebAnimationMock(blink::WebAnimation::TargetPropertyOpacity); 791 ExpectationSet usesMockAnimation; 792 793 usesMockCurve += EXPECT_CALL(mockCompositor, createAnimation(Ref(*mockCurvePtr), blink::WebAnimation::TargetPropertyOpacity, _)) 794 .WillOnce(Return(mockAnimationPtr)); 795 796 usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(1)); 797 usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(0.0)); 798 usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setAlternatesDirection(false)); 799 800 EXPECT_CALL(*mockAnimationPtr, delete_()) 801 .Times(1) 802 .After(usesMockAnimation); 803 EXPECT_CALL(*mockCurvePtr, delete_()) 804 .Times(1) 805 .After(usesMockCurve); 806 807 // Go! 808 setCompositorForTesting(mockCompositor); 809 Vector<OwnPtr<blink::WebAnimation> > result; 810 getAnimationOnCompositor(m_timing, *effect.get(), result); 811 EXPECT_EQ(1U, result.size()); 812 result[0].clear(); 813 } 814 815 TEST_F(AnimationCompositorAnimationsTest, createMultipleKeyframeOpacityAnimationLinear) 816 { 817 // Animation to convert 818 RefPtr<KeyframeAnimationEffect> effect = createKeyframeAnimationEffect( 819 createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0), 820 createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(-1.0).get(), 0.25), 821 createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(20.0).get(), 0.5), 822 createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(5.0).get(), 1.0)); 823 824 m_timing.iterationCount = 5; 825 m_timing.direction = Timing::PlaybackDirectionAlternate; 826 // -- 827 828 WebCompositorSupportMock mockCompositor; 829 830 // Curve is created 831 blink::WebFloatAnimationCurveMock* mockCurvePtr = new blink::WebFloatAnimationCurveMock(); 832 ExpectationSet usesMockCurve; 833 834 EXPECT_CALL(mockCompositor, createFloatAnimationCurve()) 835 .WillOnce(Return(mockCurvePtr)); 836 837 usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(0.0, 2.0), blink::WebAnimationCurve::TimingFunctionTypeLinear)); 838 usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(0.25, -1.0), blink::WebAnimationCurve::TimingFunctionTypeLinear)); 839 usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(0.5, 20.0), blink::WebAnimationCurve::TimingFunctionTypeLinear)); 840 usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(1.0, 5.0))); 841 842 // Animation is created 843 blink::WebAnimationMock* mockAnimationPtr = new blink::WebAnimationMock(blink::WebAnimation::TargetPropertyOpacity); 844 ExpectationSet usesMockAnimation; 845 846 usesMockCurve += EXPECT_CALL(mockCompositor, createAnimation(Ref(*mockCurvePtr), blink::WebAnimation::TargetPropertyOpacity, _)) 847 .WillOnce(Return(mockAnimationPtr)); 848 849 usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(5)); 850 usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(0.0)); 851 usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setAlternatesDirection(true)); 852 853 EXPECT_CALL(*mockAnimationPtr, delete_()) 854 .Times(1) 855 .After(usesMockAnimation); 856 EXPECT_CALL(*mockCurvePtr, delete_()) 857 .Times(1) 858 .After(usesMockCurve); 859 860 // Go! 861 setCompositorForTesting(mockCompositor); 862 Vector<OwnPtr<blink::WebAnimation> > result; 863 getAnimationOnCompositor(m_timing, *effect.get(), result); 864 EXPECT_EQ(1U, result.size()); 865 result[0].clear(); 866 } 867 868 TEST_F(AnimationCompositorAnimationsTest, createSimpleOpacityAnimationStartDelay) 869 { 870 // Animation to convert 871 RefPtr<KeyframeAnimationEffect> effect = createKeyframeAnimationEffect( 872 createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0), 873 createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(5.0).get(), 1.0)); 874 875 m_timing.iterationCount = 5.0; 876 m_timing.iterationDuration = 1.75; 877 m_timing.startDelay = 3.25; 878 // -- 879 880 WebCompositorSupportMock mockCompositor; 881 882 // Curve is created 883 blink::WebFloatAnimationCurveMock* mockCurvePtr = new blink::WebFloatAnimationCurveMock; 884 ExpectationSet usesMockCurve; 885 EXPECT_CALL(mockCompositor, createFloatAnimationCurve()) 886 .WillOnce(Return(mockCurvePtr)); 887 888 usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(0.0, 2.0), blink::WebAnimationCurve::TimingFunctionTypeLinear)); 889 usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(1.75, 5.0))); 890 891 // Create animation 892 blink::WebAnimationMock* mockAnimationPtr = new blink::WebAnimationMock(blink::WebAnimation::TargetPropertyOpacity); 893 ExpectationSet usesMockAnimation; 894 895 usesMockCurve += EXPECT_CALL(mockCompositor, createAnimation(Ref(*mockCurvePtr), blink::WebAnimation::TargetPropertyOpacity, _)) 896 .WillOnce(Return(mockAnimationPtr)); 897 898 usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(5)); 899 usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(-3.25)); 900 usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setAlternatesDirection(false)); 901 902 EXPECT_CALL(*mockAnimationPtr, delete_()) 903 .Times(1) 904 .After(usesMockAnimation); 905 EXPECT_CALL(*mockCurvePtr, delete_()) 906 .Times(1) 907 .After(usesMockCurve); 908 909 // Go! 910 setCompositorForTesting(mockCompositor); 911 Vector<OwnPtr<blink::WebAnimation> > result; 912 getAnimationOnCompositor(m_timing, *effect.get(), result); 913 EXPECT_EQ(1U, result.size()); 914 result[0].clear(); 915 } 916 917 TEST_F(AnimationCompositorAnimationsTest, createMultipleKeyframeOpacityAnimationChained) 918 { 919 // Animation to convert 920 RefPtr<KeyframeAnimationEffect> effect = createKeyframeAnimationEffect( 921 createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0), 922 createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(-1.0).get(), 0.25), 923 createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(20.0).get(), 0.5), 924 createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(5.0).get(), 1.0)); 925 926 RefPtr<ChainedTimingFunction> chainedTimingFunction = ChainedTimingFunction::create(); 927 chainedTimingFunction->appendSegment(0.25, m_cubicEaseTimingFunction.get()); 928 chainedTimingFunction->appendSegment(0.5, m_linearTimingFunction.get()); 929 chainedTimingFunction->appendSegment(1.0, m_cubicCustomTimingFunction.get()); 930 931 m_timing.timingFunction = chainedTimingFunction; 932 m_timing.iterationDuration = 2.0; 933 m_timing.iterationCount = 10; 934 m_timing.direction = Timing::PlaybackDirectionAlternate; 935 // -- 936 937 WebCompositorSupportMock mockCompositor; 938 939 // Curve is created 940 blink::WebFloatAnimationCurveMock* mockCurvePtr = new blink::WebFloatAnimationCurveMock(); 941 ExpectationSet usesMockCurve; 942 943 EXPECT_CALL(mockCompositor, createFloatAnimationCurve()) 944 .WillOnce(Return(mockCurvePtr)); 945 946 usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(0.0, 2.0), blink::WebAnimationCurve::TimingFunctionTypeEase)); 947 usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(0.5, -1.0), blink::WebAnimationCurve::TimingFunctionTypeLinear)); 948 usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(1.0, 20.0), 1.0, 2.0, 3.0, 4.0)); 949 usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(2.0, 5.0))); 950 951 // Animation is created 952 blink::WebAnimationMock* mockAnimationPtr = new blink::WebAnimationMock(blink::WebAnimation::TargetPropertyOpacity); 953 ExpectationSet usesMockAnimation; 954 955 usesMockCurve += EXPECT_CALL(mockCompositor, createAnimation(Ref(*mockCurvePtr), blink::WebAnimation::TargetPropertyOpacity, _)) 956 .WillOnce(Return(mockAnimationPtr)); 957 958 usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(10)); 959 usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(0.0)); 960 usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setAlternatesDirection(true)); 961 962 EXPECT_CALL(*mockAnimationPtr, delete_()) 963 .Times(1) 964 .After(usesMockAnimation); 965 EXPECT_CALL(*mockCurvePtr, delete_()) 966 .Times(1) 967 .After(usesMockCurve); 968 969 // Go! 970 setCompositorForTesting(mockCompositor); 971 Vector<OwnPtr<blink::WebAnimation> > result; 972 getAnimationOnCompositor(m_timing, *effect.get(), result); 973 EXPECT_EQ(1U, result.size()); 974 result[0].clear(); 975 } 976 977 TEST_F(AnimationCompositorAnimationsTest, createReversedOpacityAnimation) 978 { 979 // Animation to convert 980 RefPtr<KeyframeAnimationEffect> effect = createKeyframeAnimationEffect( 981 createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0), 982 createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(-1.0).get(), 0.25), 983 createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(20.0).get(), 0.5), 984 createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(5.0).get(), 1.0)); 985 986 RefPtr<TimingFunction> cubicEasyFlipTimingFunction = CubicBezierTimingFunction::create(0.0, 0.0, 0.0, 1.0); 987 RefPtr<ChainedTimingFunction> chainedTimingFunction = ChainedTimingFunction::create(); 988 chainedTimingFunction->appendSegment(0.25, CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn)); 989 chainedTimingFunction->appendSegment(0.5, m_linearTimingFunction.get()); 990 chainedTimingFunction->appendSegment(1.0, cubicEasyFlipTimingFunction.get()); 991 992 m_timing.timingFunction = chainedTimingFunction; 993 m_timing.iterationCount = 10; 994 m_timing.direction = Timing::PlaybackDirectionAlternateReverse; 995 // -- 996 997 WebCompositorSupportMock mockCompositor; 998 999 // Curve is created 1000 blink::WebFloatAnimationCurveMock* mockCurvePtr = new blink::WebFloatAnimationCurveMock(); 1001 ExpectationSet usesMockCurve; 1002 1003 EXPECT_CALL(mockCompositor, createFloatAnimationCurve()) 1004 .WillOnce(Return(mockCurvePtr)); 1005 1006 usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(0.0, 5.0), 1.0, 0.0, 1.0, 1.0)); 1007 usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(0.5, 20.0), blink::WebAnimationCurve::TimingFunctionTypeLinear)); 1008 usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(0.75, -1.0), blink::WebAnimationCurve::TimingFunctionTypeEaseOut)); 1009 usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(1.0, 2.0))); 1010 1011 // Create the animation 1012 blink::WebAnimationMock* mockAnimationPtr = new blink::WebAnimationMock(blink::WebAnimation::TargetPropertyOpacity); 1013 ExpectationSet usesMockAnimation; 1014 1015 usesMockCurve += EXPECT_CALL(mockCompositor, createAnimation(Ref(*mockCurvePtr), blink::WebAnimation::TargetPropertyOpacity, _)) 1016 .WillOnce(Return(mockAnimationPtr)); 1017 1018 usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(10)); 1019 usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(0.0)); 1020 usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setAlternatesDirection(true)); 1021 1022 EXPECT_CALL(*mockAnimationPtr, delete_()) 1023 .Times(1) 1024 .After(usesMockAnimation); 1025 EXPECT_CALL(*mockCurvePtr, delete_()) 1026 .Times(1) 1027 .After(usesMockCurve); 1028 1029 // Go! 1030 setCompositorForTesting(mockCompositor); 1031 Vector<OwnPtr<blink::WebAnimation> > result; 1032 getAnimationOnCompositor(m_timing, *effect.get(), result); 1033 EXPECT_EQ(1U, result.size()); 1034 result[0].clear(); 1035 } 1036 1037 TEST_F(AnimationCompositorAnimationsTest, createReversedOpacityAnimationNegativeStartDelay) 1038 { 1039 // Animation to convert 1040 RefPtr<KeyframeAnimationEffect> effect = createKeyframeAnimationEffect( 1041 createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0), 1042 createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(5.0).get(), 1.0)); 1043 1044 m_timing.iterationCount = 5.0; 1045 m_timing.iterationDuration = 1.5; 1046 m_timing.startDelay = -3; 1047 m_timing.direction = Timing::PlaybackDirectionAlternateReverse; 1048 // -- 1049 1050 WebCompositorSupportMock mockCompositor; 1051 1052 // Curve is created 1053 blink::WebFloatAnimationCurveMock* mockCurvePtr = new blink::WebFloatAnimationCurveMock; 1054 ExpectationSet usesMockCurve; 1055 EXPECT_CALL(mockCompositor, createFloatAnimationCurve()) 1056 .WillOnce(Return(mockCurvePtr)); 1057 1058 usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(0.0, 5.0), blink::WebAnimationCurve::TimingFunctionTypeLinear)); 1059 usesMockCurve += EXPECT_CALL(*mockCurvePtr, add(blink::WebFloatKeyframe(1.5, 2.0))); 1060 1061 // Create animation 1062 blink::WebAnimationMock* mockAnimationPtr = new blink::WebAnimationMock(blink::WebAnimation::TargetPropertyOpacity); 1063 ExpectationSet usesMockAnimation; 1064 1065 usesMockCurve += EXPECT_CALL(mockCompositor, createAnimation(Ref(*mockCurvePtr), blink::WebAnimation::TargetPropertyOpacity, _)) 1066 .WillOnce(Return(mockAnimationPtr)); 1067 1068 usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setIterations(5)); 1069 usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setTimeOffset(3.0)); 1070 usesMockAnimation += EXPECT_CALL(*mockAnimationPtr, setAlternatesDirection(true)); 1071 1072 EXPECT_CALL(*mockAnimationPtr, delete_()) 1073 .Times(1) 1074 .After(usesMockAnimation); 1075 EXPECT_CALL(*mockCurvePtr, delete_()) 1076 .Times(1) 1077 .After(usesMockCurve); 1078 1079 // Go! 1080 setCompositorForTesting(mockCompositor); 1081 Vector<OwnPtr<blink::WebAnimation> > result; 1082 getAnimationOnCompositor(m_timing, *effect.get(), result); 1083 EXPECT_EQ(1U, result.size()); 1084 result[0].clear(); 1085 } 1086 1087 1088 } // namespace WebCore 1089