107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch// found in the LICENSE file. 407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch#include "config.h" 607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch#include "core/animation/AnimationStack.h" 707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch#include "core/animation/ActiveAnimations.h" 907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch#include "core/animation/AnimationClock.h" 10d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "core/animation/AnimationTimeline.h" 1107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch#include "core/animation/KeyframeEffectModel.h" 12c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/animation/LegacyStyleInterpolation.h" 13197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/animation/animatable/AnimatableDouble.h" 1407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch#include <gtest/gtest.h> 1507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 16c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 1707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 1807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochclass AnimationAnimationStackTest : public ::testing::Test { 1907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochprotected: 2007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch virtual void SetUp() 2107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch { 2207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch document = Document::create(); 2307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch document->animationClock().resetTimeForTesting(); 24d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) timeline = AnimationTimeline::create(document.get()); 2507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch element = document->createElement("foo", ASSERT_NO_EXCEPTION); 2607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 2707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 2807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch AnimationPlayer* play(Animation* animation, double startTime) 2907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch { 3007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch AnimationPlayer* player = timeline->createAnimationPlayer(animation); 3110f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch player->setStartTimeInternal(startTime); 32323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) player->update(TimingUpdateOnDemand); 3307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return player; 3407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 3507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 366f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch void updateTimeline(double time) 376f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch { 386f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch document->animationClock().updateTime(time); 39323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles) timeline->serviceAnimations(TimingUpdateForAnimationFrame); 406f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch } 416f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 42d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) const WillBeHeapVector<OwnPtrWillBeMember<SampledEffect> >& effects() 436f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch { 446f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch return element->ensureActiveAnimations().defaultStack().m_effects; 456f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch } 466f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 4707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch PassRefPtrWillBeRawPtr<AnimationEffect> makeAnimationEffect(CSSPropertyID id, PassRefPtrWillBeRawPtr<AnimatableValue> value) 4807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch { 49a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch AnimatableValueKeyframeVector keyframes(2); 50a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch keyframes[0] = AnimatableValueKeyframe::create(); 5107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch keyframes[0]->setOffset(0.0); 5207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch keyframes[0]->setPropertyValue(id, value.get()); 53a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch keyframes[1] = AnimatableValueKeyframe::create(); 5407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch keyframes[1]->setOffset(1.0); 5507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch keyframes[1]->setPropertyValue(id, value.get()); 56a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch return AnimatableValueKeyframeEffectModel::create(keyframes); 5707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 5807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 59d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) PassRefPtrWillBeRawPtr<InertAnimation> makeInertAnimation(PassRefPtrWillBeRawPtr<AnimationEffect> effect) 6007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch { 6107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch Timing timing; 6207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch timing.fillMode = Timing::FillModeBoth; 6307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch return InertAnimation::create(effect, timing, false); 6407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 6507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 66d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) PassRefPtrWillBeRawPtr<Animation> makeAnimation(PassRefPtrWillBeRawPtr<AnimationEffect> effect, double duration = 10) 6707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch { 6807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch Timing timing; 6907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch timing.fillMode = Timing::FillModeBoth; 706f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch timing.iterationDuration = duration; 716f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch return Animation::create(element.get(), effect, timing); 7207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 7307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 7407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch AnimatableValue* interpolationValue(Interpolation* interpolation) 7507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch { 76a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch return toLegacyStyleInterpolation(interpolation)->currentValue().get(); 7707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch } 7807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 79f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles) RefPtrWillBePersistent<Document> document; 80d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) RefPtrWillBePersistent<AnimationTimeline> timeline; 81d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) RefPtrWillBePersistent<Element> element; 8207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch}; 8307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 8407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben MurdochTEST_F(AnimationAnimationStackTest, ActiveAnimationsSorted) 8507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{ 8607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch play(makeAnimation(makeAnimationEffect(CSSPropertyFontSize, AnimatableDouble::create(1))).get(), 10); 8707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch play(makeAnimation(makeAnimationEffect(CSSPropertyFontSize, AnimatableDouble::create(2))).get(), 15); 8807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch play(makeAnimation(makeAnimationEffect(CSSPropertyFontSize, AnimatableDouble::create(3))).get(), 5); 8907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > result = AnimationStack::activeInterpolations(&element->activeAnimations()->defaultStack(), 0, 0, Animation::DefaultPriority, 0); 9007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch EXPECT_EQ(1u, result.size()); 91c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) EXPECT_TRUE(interpolationValue(result.get(CSSPropertyFontSize))->equals(AnimatableDouble::create(3).get())); 9207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch} 9307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 9407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben MurdochTEST_F(AnimationAnimationStackTest, NewAnimations) 9507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{ 9607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch play(makeAnimation(makeAnimationEffect(CSSPropertyFontSize, AnimatableDouble::create(1))).get(), 15); 9707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch play(makeAnimation(makeAnimationEffect(CSSPropertyZIndex, AnimatableDouble::create(2))).get(), 10); 98d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) WillBeHeapVector<RawPtrWillBeMember<InertAnimation> > newAnimations; 99d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) RefPtrWillBeRawPtr<InertAnimation> inert1 = makeInertAnimation(makeAnimationEffect(CSSPropertyFontSize, AnimatableDouble::create(3))); 100d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) RefPtrWillBeRawPtr<InertAnimation> inert2 = makeInertAnimation(makeAnimationEffect(CSSPropertyZIndex, AnimatableDouble::create(4))); 10107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch newAnimations.append(inert1.get()); 10207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch newAnimations.append(inert2.get()); 10307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > result = AnimationStack::activeInterpolations(&element->activeAnimations()->defaultStack(), &newAnimations, 0, Animation::DefaultPriority, 10); 10407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch EXPECT_EQ(2u, result.size()); 105c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) EXPECT_TRUE(interpolationValue(result.get(CSSPropertyFontSize))->equals(AnimatableDouble::create(3).get())); 10607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch EXPECT_TRUE(interpolationValue(result.get(CSSPropertyZIndex))->equals(AnimatableDouble::create(4).get())); 10707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch} 10807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 10907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben MurdochTEST_F(AnimationAnimationStackTest, CancelledAnimationPlayers) 11007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{ 111d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) WillBeHeapHashSet<RawPtrWillBeMember<const AnimationPlayer> > cancelledAnimationPlayers; 112d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) RefPtrWillBeRawPtr<AnimationPlayer> player = play(makeAnimation(makeAnimationEffect(CSSPropertyFontSize, AnimatableDouble::create(1))).get(), 0); 1136f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch cancelledAnimationPlayers.add(player.get()); 11407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch play(makeAnimation(makeAnimationEffect(CSSPropertyZIndex, AnimatableDouble::create(2))).get(), 0); 11507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > result = AnimationStack::activeInterpolations(&element->activeAnimations()->defaultStack(), 0, &cancelledAnimationPlayers, Animation::DefaultPriority, 0); 11607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch EXPECT_EQ(1u, result.size()); 11707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch EXPECT_TRUE(interpolationValue(result.get(CSSPropertyZIndex))->equals(AnimatableDouble::create(2).get())); 11807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch} 11907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 1206f543c786fc42989f552b4daa774ca5ff32fa697Ben MurdochTEST_F(AnimationAnimationStackTest, ForwardsFillDiscarding) 1216f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch{ 1226f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch play(makeAnimation(makeAnimationEffect(CSSPropertyFontSize, AnimatableDouble::create(1))).get(), 2); 1236f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch play(makeAnimation(makeAnimationEffect(CSSPropertyFontSize, AnimatableDouble::create(2))).get(), 6); 1246f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch play(makeAnimation(makeAnimationEffect(CSSPropertyFontSize, AnimatableDouble::create(3))).get(), 4); 1257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci document->compositorPendingAnimations().update(); 1266f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch WillBeHeapHashMap<CSSPropertyID, RefPtrWillBeMember<Interpolation> > interpolations; 1276f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 1286f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch updateTimeline(11); 129d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) Heap::collectAllGarbage(); 1306f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch interpolations = AnimationStack::activeInterpolations(&element->activeAnimations()->defaultStack(), 0, 0, Animation::DefaultPriority, 0); 131c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) EXPECT_TRUE(interpolationValue(interpolations.get(CSSPropertyFontSize))->equals(AnimatableDouble::create(3).get())); 1326f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch EXPECT_EQ(3u, effects().size()); 1336f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch EXPECT_EQ(1u, interpolations.size()); 1346f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 1356f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch updateTimeline(13); 136d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) Heap::collectAllGarbage(); 1376f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch interpolations = AnimationStack::activeInterpolations(&element->activeAnimations()->defaultStack(), 0, 0, Animation::DefaultPriority, 0); 138c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) EXPECT_TRUE(interpolationValue(interpolations.get(CSSPropertyFontSize))->equals(AnimatableDouble::create(3).get())); 1396f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch EXPECT_EQ(3u, effects().size()); 1406f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 1416f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch updateTimeline(15); 142d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) Heap::collectAllGarbage(); 1436f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch interpolations = AnimationStack::activeInterpolations(&element->activeAnimations()->defaultStack(), 0, 0, Animation::DefaultPriority, 0); 144c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) EXPECT_TRUE(interpolationValue(interpolations.get(CSSPropertyFontSize))->equals(AnimatableDouble::create(3).get())); 1456f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch EXPECT_EQ(2u, effects().size()); 1466f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 1476f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch updateTimeline(17); 148d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) Heap::collectAllGarbage(); 1496f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch interpolations = AnimationStack::activeInterpolations(&element->activeAnimations()->defaultStack(), 0, 0, Animation::DefaultPriority, 0); 150c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) EXPECT_TRUE(interpolationValue(interpolations.get(CSSPropertyFontSize))->equals(AnimatableDouble::create(3).get())); 1516f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch EXPECT_EQ(1u, effects().size()); 1526f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch} 1536f543c786fc42989f552b4daa774ca5ff32fa697Ben Murdoch 15407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch} 155