| Index: third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp
|
| diff --git a/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp b/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp
|
| index 8e99446dee9e8ad1b9c2214f17fc9ed79f334952..876af2617177ad9d74a69e597814cd2b4b90b662 100644
|
| --- a/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp
|
| +++ b/third_party/WebKit/Source/core/animation/CompositorAnimationsTest.cpp
|
| @@ -42,11 +42,16 @@
|
| #include "core/animation/animatable/AnimatableTransform.h"
|
| #include "core/animation/animatable/AnimatableValueTestHelper.h"
|
| #include "core/dom/Document.h"
|
| +#include "core/layout/LayoutBox.h"
|
| #include "core/layout/LayoutObject.h"
|
| +#include "core/loader/EmptyClients.h"
|
| +#include "core/paint/PaintLayer.h"
|
| #include "core/testing/DummyPageHolder.h"
|
| #include "platform/geometry/FloatBox.h"
|
| #include "platform/geometry/IntSize.h"
|
| #include "platform/graphics/filters/FilterOperations.h"
|
| +#include "platform/graphics/paint/PaintArtifact.h"
|
| +#include "platform/graphics/test/FakeGraphicsLayerFactory.h"
|
| #include "platform/transforms/TransformOperations.h"
|
| #include "platform/transforms/TranslateTransformOperation.h"
|
| #include "public/platform/WebCompositorAnimation.h"
|
| @@ -65,6 +70,64 @@ using ::testing::Ref;
|
| using ::testing::Return;
|
| using ::testing::_;
|
|
|
| +class MockChromeClient : public EmptyChromeClient {
|
| +public:
|
| + MockChromeClient() {}
|
| + GraphicsLayerFactory* graphicsLayerFactory() const override
|
| + {
|
| + return FakeGraphicsLayerFactory::instance();
|
| + }
|
| +};
|
| +
|
| +
|
| +class LayoutObjectProxy : public LayoutBox {
|
| +public:
|
| + static LayoutObjectProxy* create(ContainerNode* node)
|
| + {
|
| + return new LayoutObjectProxy(node);
|
| + }
|
| +
|
| + static void dispose(LayoutObjectProxy* proxy)
|
| + {
|
| + proxy->destroy();
|
| + }
|
| +
|
| + const char* name() const override { return nullptr; }
|
| +
|
| + void createCompositedLayer(WebCompositorSupportMock& compositorSupport)
|
| + {
|
| + RefPtr<ComputedStyle> computedStyle = ComputedStyle::create();
|
| + styleWillChange(StyleDifference(), *computedStyle.get());
|
| + setStyle(computedStyle);
|
| + styleDidChange(StyleDifference(), nullptr);
|
| +
|
| + m_contentLayer = new WebContentLayerMock();
|
| + EXPECT_CALL(compositorSupport, createContentLayer(_)).WillOnce(Return(m_contentLayer));
|
| +
|
| + DisableCompositingQueryAsserts disabler;
|
| + layer()->ensureCompositedLayerMapping();
|
| + }
|
| +
|
| + WebContentLayerMock* contentLayer() const
|
| + {
|
| + return m_contentLayer;
|
| + }
|
| +
|
| +private:
|
| + explicit LayoutObjectProxy(ContainerNode* node)
|
| + : LayoutBox(node)
|
| + {
|
| + }
|
| +
|
| + PaintLayerType layerTypeRequired() const override
|
| + {
|
| + return NormalPaintLayer;
|
| + }
|
| +
|
| + WebContentLayerMock* m_contentLayer;
|
| +};
|
| +
|
| +
|
| class AnimationCompositorAnimationsTest : public AnimationCompositorAnimationsTestBase {
|
| protected:
|
| RefPtr<TimingFunction> m_linearTimingFunction;
|
| @@ -82,11 +145,14 @@ protected:
|
| RefPtrWillBePersistent<Document> m_document;
|
| RefPtrWillBePersistent<Element> m_element;
|
| Persistent<AnimationTimeline> m_timeline;
|
| + OwnPtrWillBePersistent<MockChromeClient> m_chromeClient;
|
| OwnPtr<DummyPageHolder> m_pageHolder;
|
| WebCompositorSupportMock m_mockCompositor;
|
|
|
| virtual void SetUp()
|
| {
|
| + m_chromeClient = adoptPtrWillBeNoop(new MockChromeClient);
|
| +
|
| AnimationCompositorAnimationsTestBase::SetUp();
|
| setCompositorForTesting(m_mockCompositor);
|
|
|
| @@ -111,7 +177,12 @@ protected:
|
| EXPECT_CALL(m_mockCompositor, createAnimationTimeline())
|
| .WillOnce(Return(new WebCompositorAnimationTimelineMock()));
|
| }
|
| - m_pageHolder = DummyPageHolder::create();
|
| +
|
| + Page::PageClients clients;
|
| + fillWithEmptyClients(clients);
|
| + clients.chromeClient = m_chromeClient.get();
|
| + m_pageHolder = DummyPageHolder::create(IntSize(), &clients);
|
| +
|
| m_document = &m_pageHolder->document();
|
| m_document->animationClock().resetTimeForTesting();
|
|
|
| @@ -264,27 +335,38 @@ public:
|
| m_document->compositorPendingAnimations().update(false);
|
| m_timeline->serviceAnimations(TimingUpdateForAnimationFrame);
|
| }
|
| -};
|
|
|
| -class LayoutObjectProxy : public LayoutObject {
|
| -public:
|
| - static LayoutObjectProxy* create(Node* node)
|
| + PassOwnPtr<WebCompositorAnimationMock> preCommit(LayoutObjectProxy* layoutObject, Animation* animation)
|
| {
|
| - return new LayoutObjectProxy(node);
|
| - }
|
| + WebFloatAnimationCurveMock* mockCurvePtr = new WebFloatAnimationCurveMock;
|
| + ExpectationSet usesMockCurve;
|
| + EXPECT_CALL(m_mockCompositor, createFloatAnimationCurve())
|
| + .WillOnce(Return(mockCurvePtr));
|
|
|
| - static void dispose(LayoutObjectProxy* proxy)
|
| - {
|
| - proxy->destroy();
|
| - }
|
| + OwnPtr<WebCompositorAnimationMock> mockAnimationPtr = adoptPtr(new WebCompositorAnimationMock(WebCompositorAnimation::TargetPropertyOpacity));
|
| + EXPECT_CALL(m_mockCompositor, createAnimation(Ref(*mockCurvePtr), WebCompositorAnimation::TargetPropertyOpacity, _, _))
|
| + .WillOnce(Return(mockAnimationPtr.get()));
|
|
|
| - const char* name() const override { return nullptr; }
|
| - void layout() override { }
|
| + const int animationId = 1;
|
| + EXPECT_CALL(*mockAnimationPtr.get(), id()).WillRepeatedly(Return(animationId));
|
|
|
| -private:
|
| - explicit LayoutObjectProxy(Node* node)
|
| - : LayoutObject(node)
|
| - {
|
| + if (RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled()) {
|
| + EXPECT_TRUE(m_timeline->compositorTimeline());
|
| + EXPECT_CALL(m_mockCompositor, createAnimationPlayer())
|
| + .WillOnce(Return(new WebCompositorAnimationPlayerMock()));
|
| + } else {
|
| + EXPECT_CALL(layoutObject->contentLayer()->layerMock(), addAnimation(_)).WillRepeatedly(Return(true));
|
| + }
|
| +
|
| + const int compositorGroup = 1;
|
| + DisableCompositingQueryAsserts disabler;
|
| + EXPECT_TRUE(animation->preCommit(compositorGroup, true));
|
| +
|
| + if (RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled())
|
| + EXPECT_TRUE(animation->compositorPlayer());
|
| +
|
| + EXPECT_TRUE(animation->hasActiveAnimationsOnCompositor());
|
| + return mockAnimationPtr.release();
|
| }
|
| };
|
|
|
| @@ -1175,12 +1257,51 @@ TEST_F(AnimationCompositorAnimationsTest, createSimpleOpacityAnimationWithTiming
|
| result[0].clear();
|
| }
|
|
|
| +TEST_F(AnimationCompositorAnimationsTest, CancelCompositorAnimationIfAnimationDisposed)
|
| +{
|
| + RefPtrWillBePersistent<Element> element = m_document->createElement("shared", ASSERT_NO_EXCEPTION);
|
| +
|
| + LayoutObjectProxy* layoutObject = LayoutObjectProxy::create(element.get());
|
| + element->setLayoutObject(layoutObject);
|
| + layoutObject->createCompositedLayer(m_mockCompositor);
|
| +
|
| + AnimatableValueKeyframeVector keyFrames;
|
| + keyFrames.append(createDefaultKeyframe(CSSPropertyOpacity, EffectModel::CompositeReplace, 0.0).get());
|
| + keyFrames.append(createDefaultKeyframe(CSSPropertyOpacity, EffectModel::CompositeReplace, 1.0).get());
|
| + EffectModel* animationEffect = AnimatableValueKeyframeEffectModel::create(keyFrames);
|
| +
|
| + Timing timing;
|
| + timing.iterationDuration = 1.f;
|
| +
|
| + KeyframeEffect* keyframeEffect = KeyframeEffect::create(element.get(), animationEffect, timing);
|
| + Animation* animation = m_timeline->play(keyframeEffect);
|
| + EXPECT_TRUE(animation->isCandidateForAnimationOnCompositor());
|
| +
|
| + OwnPtr<WebCompositorAnimationMock> compositorAnimation = preCommit(layoutObject, animation);
|
| +
|
| + animation->dispose();
|
| + animation->cancelAnimationOnCompositor();
|
| +
|
| + EXPECT_FALSE(animation->hasActiveAnimationsOnCompositor());
|
| +
|
| + simulateFrame(0);
|
| + EXPECT_EQ(1U, element->elementAnimations()->animations().size());
|
| + simulateFrame(1.);
|
| +
|
| + element->setLayoutObject(nullptr);
|
| + LayoutObjectProxy::dispose(layoutObject);
|
| +
|
| + Heap::collectAllGarbage();
|
| + EXPECT_TRUE(element->elementAnimations()->animations().isEmpty());
|
| +}
|
| +
|
| TEST_F(AnimationCompositorAnimationsTest, CancelIncompatibleCompositorAnimations)
|
| {
|
| RefPtrWillBePersistent<Element> element = m_document->createElement("shared", ASSERT_NO_EXCEPTION);
|
|
|
| LayoutObjectProxy* layoutObject = LayoutObjectProxy::create(element.get());
|
| element->setLayoutObject(layoutObject);
|
| + layoutObject->createCompositedLayer(m_mockCompositor);
|
|
|
| AnimatableValueKeyframeVector keyFrames;
|
| keyFrames.append(createDefaultKeyframe(CSSPropertyOpacity, EffectModel::CompositeReplace, 0.0).get());
|
| @@ -1194,18 +1315,15 @@ TEST_F(AnimationCompositorAnimationsTest, CancelIncompatibleCompositorAnimations
|
| // The first animation for opacity is ok to run on compositor.
|
| KeyframeEffect* keyframeEffect1 = KeyframeEffect::create(element.get(), animationEffect1, timing);
|
| Animation* animation1 = m_timeline->play(keyframeEffect1);
|
| - EXPECT_TRUE(CompositorAnimations::instance()->isCandidateForAnimationOnCompositor(timing, *element.get(), animation1, *animationEffect1, 1));
|
| + EXPECT_TRUE(animation1->isCandidateForAnimationOnCompositor());
|
|
|
| - // simulate KeyframeEffect::maybeStartAnimationOnCompositor
|
| - Vector<int> compositorAnimationIds;
|
| - compositorAnimationIds.append(1);
|
| - keyframeEffect1->setCompositorAnimationIdsForTesting(compositorAnimationIds);
|
| - EXPECT_TRUE(animation1->hasActiveAnimationsOnCompositor());
|
| + OwnPtr<WebCompositorAnimationMock> compositorAnimation = preCommit(layoutObject, animation1);
|
|
|
| // The second animation for opacity is not ok to run on compositor.
|
| KeyframeEffect* keyframeEffect2 = KeyframeEffect::create(element.get(), animationEffect2, timing);
|
| Animation* animation2 = m_timeline->play(keyframeEffect2);
|
| EXPECT_FALSE(CompositorAnimations::instance()->isCandidateForAnimationOnCompositor(timing, *element.get(), animation2, *animationEffect2, 1));
|
| + EXPECT_FALSE(animation2->isCandidateForAnimationOnCompositor());
|
| EXPECT_FALSE(animation2->hasActiveAnimationsOnCompositor());
|
|
|
| // A fallback to blink implementation needed, so cancel all compositor-side opacity animations for this element.
|
|
|