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());
}
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(canStartAnimationOnCompositor(element));

    const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(effect);

    DeprecatedPaintLayer* layer = toLayoutBoxModelObject(element.layoutObject())->layer();
    ASSERT(layer);

    Vector<OwnPtr<WebCompositorAnimation>> animations;
    CompositorAnimationsImpl::getAnimationOnCompositor(timing, group, startTime, timeOffset, keyframeEffect, animations, playerPlaybackRate);
    ASSERT(!animations.isEmpty());
    for (auto& animation : animations) {
        int id = animation->id();
        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, player, startedAnimationId);
            startedAnimationIds.clear();
            return false;
        }
        startedAnimationIds.append(id);
    }
    ASSERT(!startedAnimationIds.isEmpty());
    return true;
}
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;
}