| Index: Source/core/animation/CompositorAnimations.cpp | 
| diff --git a/Source/core/animation/CompositorAnimations.cpp b/Source/core/animation/CompositorAnimations.cpp | 
| index 34976b7ce2068945390d66300f65d0c073c87d99..a671df9ffe5ba94b60db1d5af70834ddfa28c858 100644 | 
| --- a/Source/core/animation/CompositorAnimations.cpp | 
| +++ b/Source/core/animation/CompositorAnimations.cpp | 
| @@ -43,9 +43,11 @@ | 
| #include "core/layout/LayoutObject.h" | 
| #include "core/layout/compositing/CompositedDeprecatedPaintLayerMapping.h" | 
| #include "core/paint/DeprecatedPaintLayer.h" | 
| +#include "platform/RuntimeEnabledFeatures.h" | 
| #include "platform/geometry/FloatBox.h" | 
| #include "public/platform/Platform.h" | 
| #include "public/platform/WebCompositorAnimation.h" | 
| +#include "public/platform/WebCompositorAnimationPlayer.h" | 
| #include "public/platform/WebCompositorSupport.h" | 
| #include "public/platform/WebFilterAnimationCurve.h" | 
| #include "public/platform/WebFilterKeyframe.h" | 
| @@ -263,10 +265,10 @@ bool CompositorAnimations::canStartAnimationOnCompositor(const Element& element) | 
| return element.layoutObject() && element.layoutObject()->compositingState() == PaintsIntoOwnBacking; | 
| } | 
|  | 
| -bool CompositorAnimations::startAnimationOnCompositor(const Element& element, int group, double startTime, double timeOffset, const Timing& timing, const AnimationPlayer* player, const AnimationEffect& effect, Vector<int>& startedAnimationIds, double playerPlaybackRate) | 
| +bool CompositorAnimations::startAnimationOnCompositor(const Element& element, int group, double startTime, double timeOffset, const Timing& timing, const AnimationPlayer& player, const AnimationEffect& effect, Vector<int>& startedAnimationIds, double playerPlaybackRate) | 
| { | 
| ASSERT(startedAnimationIds.isEmpty()); | 
| -    ASSERT(isCandidateForAnimationOnCompositor(timing, element, player, effect, playerPlaybackRate)); | 
| +    ASSERT(isCandidateForAnimationOnCompositor(timing, element, &player, effect, playerPlaybackRate)); | 
| ASSERT(canStartAnimationOnCompositor(element)); | 
|  | 
| const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(effect); | 
| @@ -279,10 +281,14 @@ bool CompositorAnimations::startAnimationOnCompositor(const Element& element, in | 
| ASSERT(!animations.isEmpty()); | 
| for (auto& animation : animations) { | 
| int id = animation->id(); | 
| -        if (!layer->compositedDeprecatedPaintLayerMapping()->mainGraphicsLayer()->addAnimation(animation.release())) { | 
| +        if (RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled()) { | 
| +            WebCompositorAnimationPlayer* compositorPlayer = player.compositorPlayer(); | 
| +            ASSERT(compositorPlayer); | 
| +            compositorPlayer->addAnimation(animation.leakPtr()); | 
| +        } else if (!layer->compositedDeprecatedPaintLayerMapping()->mainGraphicsLayer()->addAnimation(animation.release())) { | 
| // FIXME: We should know ahead of time whether these animations can be started. | 
| for (int startedAnimationId : startedAnimationIds) | 
| -                cancelAnimationOnCompositor(element, startedAnimationId); | 
| +                cancelAnimationOnCompositor(element, player, startedAnimationId); | 
| startedAnimationIds.clear(); | 
| return false; | 
| } | 
| @@ -292,7 +298,7 @@ bool CompositorAnimations::startAnimationOnCompositor(const Element& element, in | 
| return true; | 
| } | 
|  | 
| -void CompositorAnimations::cancelAnimationOnCompositor(const Element& element, int id) | 
| +void CompositorAnimations::cancelAnimationOnCompositor(const Element& element, const AnimationPlayer& player, int id) | 
| { | 
| if (!canStartAnimationOnCompositor(element)) { | 
| // When an element is being detached, we cancel any associated | 
| @@ -302,10 +308,16 @@ void CompositorAnimations::cancelAnimationOnCompositor(const Element& element, i | 
| // compositing update. | 
| return; | 
| } | 
| -    toLayoutBoxModelObject(element.layoutObject())->layer()->compositedDeprecatedPaintLayerMapping()->mainGraphicsLayer()->removeAnimation(id); | 
| +    if (RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled()) { | 
| +        WebCompositorAnimationPlayer* compositorPlayer = player.compositorPlayer(); | 
| +        ASSERT(compositorPlayer); | 
| +        compositorPlayer->removeAnimation(id); | 
| +    } else { | 
| +        toLayoutBoxModelObject(element.layoutObject())->layer()->compositedDeprecatedPaintLayerMapping()->mainGraphicsLayer()->removeAnimation(id); | 
| +    } | 
| } | 
|  | 
| -void CompositorAnimations::pauseAnimationForTestingOnCompositor(const Element& element, int id, double pauseTime) | 
| +void CompositorAnimations::pauseAnimationForTestingOnCompositor(const Element& element, const AnimationPlayer& player, int id, double pauseTime) | 
| { | 
| // FIXME: canStartAnimationOnCompositor queries compositingState, which is not necessarily up to date. | 
| // https://code.google.com/p/chromium/issues/detail?id=339847 | 
| @@ -315,7 +327,51 @@ void CompositorAnimations::pauseAnimationForTestingOnCompositor(const Element& e | 
| ASSERT_NOT_REACHED(); | 
| return; | 
| } | 
| -    toLayoutBoxModelObject(element.layoutObject())->layer()->compositedDeprecatedPaintLayerMapping()->mainGraphicsLayer()->pauseAnimation(id, pauseTime); | 
| +    if (RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled()) { | 
| +        WebCompositorAnimationPlayer* compositorPlayer = player.compositorPlayer(); | 
| +        ASSERT(compositorPlayer); | 
| +        compositorPlayer->pauseAnimation(id, pauseTime); | 
| +    } else { | 
| +        toLayoutBoxModelObject(element.layoutObject())->layer()->compositedDeprecatedPaintLayerMapping()->mainGraphicsLayer()->pauseAnimation(id, pauseTime); | 
| +    } | 
| +} | 
| + | 
| +bool CompositorAnimations::canAttachCompositedLayers(const Element& element, const AnimationPlayer& player) | 
| +{ | 
| +    if (!RuntimeEnabledFeatures::compositorAnimationTimelinesEnabled()) | 
| +        return false; | 
| + | 
| +    if (!player.compositorPlayer()) | 
| +        return false; | 
| + | 
| +    if (!element.layoutObject() || !element.layoutObject()->isBoxModelObject()) | 
| +        return false; | 
| + | 
| +    DeprecatedPaintLayer* layer = toLayoutBoxModelObject(element.layoutObject())->layer(); | 
| + | 
| +    if (!layer || !layer->isAllowedToQueryCompositingState() | 
| +        || !layer->compositedDeprecatedPaintLayerMapping() | 
| +        || !layer->compositedDeprecatedPaintLayerMapping()->mainGraphicsLayer()) | 
| +        return false; | 
| + | 
| +    if (!layer->compositedDeprecatedPaintLayerMapping()->mainGraphicsLayer()->platformLayer()) | 
| +        return false; | 
| + | 
| +    return true; | 
| +} | 
| + | 
| +void CompositorAnimations::attachCompositedLayers(const Element& element, const AnimationPlayer& player) | 
| +{ | 
| +    ASSERT(element.layoutObject()); | 
| + | 
| +    DeprecatedPaintLayer* layer = toLayoutBoxModelObject(element.layoutObject())->layer(); | 
| +    ASSERT(layer); | 
| + | 
| +    WebCompositorAnimationPlayer* compositorPlayer = player.compositorPlayer(); | 
| +    ASSERT(compositorPlayer); | 
| + | 
| +    ASSERT(layer->compositedDeprecatedPaintLayerMapping()); | 
| +    compositorPlayer->attachLayer(layer->compositedDeprecatedPaintLayerMapping()->mainGraphicsLayer()->platformLayer()); | 
| } | 
|  | 
| // ----------------------------------------------------------------------- | 
|  |