void CompositorAnimations::cancelIncompatibleAnimationsOnCompositor(const Element& targetElement, const Animation& animationToAdd, const EffectModel& effectToAdd)
{
    const bool affectsOpacity = effectToAdd.affects(PropertyHandle(CSSPropertyOpacity));
    const bool affectsTransform = effectToAdd.isTransformRelatedEffect();
    const bool affectsFilter = effectToAdd.affects(PropertyHandle(CSSPropertyWebkitFilter));
    const bool affectsBackdropFilter = effectToAdd.affects(PropertyHandle(CSSPropertyBackdropFilter));

    if (!targetElement.hasAnimations())
        return;

    ElementAnimations* elementAnimations = targetElement.elementAnimations();
    ASSERT(elementAnimations);

    for (const auto& entry : elementAnimations->animations()) {
        Animation* attachedAnimation = entry.key;
        if (!considerAnimationAsIncompatible(*attachedAnimation, animationToAdd))
            continue;

        if ((affectsOpacity && attachedAnimation->affects(targetElement, CSSPropertyOpacity))
            || (affectsTransform && isTransformRelatedAnimation(targetElement, attachedAnimation))
            || (affectsFilter && attachedAnimation->affects(targetElement, CSSPropertyWebkitFilter))
            || (affectsBackdropFilter && attachedAnimation->affects(targetElement, CSSPropertyBackdropFilter)))
            attachedAnimation->cancelAnimationOnCompositor();
    }
}
void CSSAnimations::calculateCompositorAnimationUpdate(CSSAnimationUpdate& update, const Element* animatingElement, Element& element, const ComputedStyle& style)
{
    ElementAnimations* elementAnimations = animatingElement ? animatingElement->elementAnimations() : nullptr;

    // We only update compositor animations in response to changes in the base style.
    if (!elementAnimations || elementAnimations->isAnimationStyleChange())
        return;

    if (!animatingElement->layoutObject() || !animatingElement->layoutObject()->style())
        return;

    const ComputedStyle& oldStyle = *animatingElement->layoutObject()->style();
    if (!oldStyle.shouldCompositeForCurrentAnimations())
        return;

    CSSAnimations& cssAnimations = elementAnimations->cssAnimations();
    for (auto& runningAnimation : cssAnimations.m_animations.values()) {
        Animation& animation = *runningAnimation->animation;
        if (animation.effect() && animation.effect()->isKeyframeEffect()) {
            EffectModel* model = toKeyframeEffect(animation.effect())->model();
            if (model && model->isKeyframeEffectModel()) {
                KeyframeEffectModelBase* keyframeEffect = toKeyframeEffectModelBase(model);
                if (keyframeEffect->hasSyntheticKeyframes() && keyframeEffect->snapshotNeutralCompositorKeyframes(element, oldStyle, style))
                    update.updateCompositorKeyframes(&animation);
            }
        }
    }

    if (oldStyle.hasCurrentTransformAnimation() && oldStyle.effectiveZoom() != style.effectiveZoom()) {
        for (auto& entry : elementAnimations->animations()) {
            Animation& animation = *entry.key;
            if (animation.effect() && animation.effect()->isKeyframeEffect()) {
                EffectModel* model = toKeyframeEffect(animation.effect())->model();
                if (model && model->isKeyframeEffectModel()) {
                    KeyframeEffectModelBase* keyframeEffect = toKeyframeEffectModelBase(model);
                    if (keyframeEffect->affects(PropertyHandle(CSSPropertyTransform)) && keyframeEffect->snapshotAllCompositorKeyframes(element, &style))
                        update.updateCompositorKeyframes(&animation);
                }
            }
        }
    }
}