| Index: Source/core/animation/CompositorAnimations.cpp | 
| diff --git a/Source/core/animation/CompositorAnimations.cpp b/Source/core/animation/CompositorAnimations.cpp | 
| index 16aa2904cb069e1fd2b64a5d80eea28198202ed2..537523571ffaed27f2db839f8f3a207abee5a396 100644 | 
| --- a/Source/core/animation/CompositorAnimations.cpp | 
| +++ b/Source/core/animation/CompositorAnimations.cpp | 
| @@ -31,6 +31,7 @@ | 
| #include "config.h" | 
| #include "core/animation/CompositorAnimations.h" | 
|  | 
| +#include "core/animation/ActiveAnimations.h" | 
| #include "core/animation/AnimationNode.h" | 
| #include "core/animation/AnimationTranslationUtil.h" | 
| #include "core/animation/CompositorAnimationsImpl.h" | 
| @@ -70,6 +71,52 @@ void getKeyframeValuesForProperty(const KeyframeEffectModelBase* effect, CSSProp | 
| } | 
| } | 
|  | 
| +bool considerPlayerAsIncompatible(const AnimationPlayer& player, const AnimationPlayer& playerToAdd) | 
| +{ | 
| +    if (&player == &playerToAdd) | 
| +        return false; | 
| + | 
| +    switch (player.playStateInternal()) { | 
| +    case AnimationPlayer::Idle: | 
| +        return false; | 
| +    case AnimationPlayer::Pending: | 
| +    case AnimationPlayer::Running: | 
| +        return true; | 
| +    case AnimationPlayer::Paused: | 
| +    case AnimationPlayer::Finished: | 
| +        return AnimationPlayer::hasLowerPriority(&playerToAdd, &player); | 
| +    default: | 
| +        ASSERT_NOT_REACHED(); | 
| +        return true; | 
| +    } | 
| +} | 
| + | 
| +bool hasIncompatibleAnimations(const Element& targetElement, const AnimationPlayer& playerToAdd, const AnimationEffect& effectToAdd) | 
| +{ | 
| +    const bool affectsOpacity = effectToAdd.affects(CSSPropertyOpacity); | 
| +    const bool affectsTransform = effectToAdd.affects(CSSPropertyTransform); | 
| +    const bool affectsFilter = effectToAdd.affects(CSSPropertyWebkitFilter); | 
| + | 
| +    if (!targetElement.hasActiveAnimations()) | 
| +        return false; | 
| + | 
| +    ActiveAnimations* activeAnimations = targetElement.activeAnimations(); | 
| +    ASSERT(activeAnimations); | 
| + | 
| +    for (const auto& entry : activeAnimations->players()) { | 
| +        const AnimationPlayer* attachedPlayer = entry.key; | 
| +        if (!considerPlayerAsIncompatible(*attachedPlayer, playerToAdd)) | 
| +            continue; | 
| + | 
| +        if ((affectsOpacity && attachedPlayer->affects(targetElement, CSSPropertyOpacity)) | 
| +            || (affectsTransform && attachedPlayer->affects(targetElement, CSSPropertyTransform)) | 
| +            || (affectsFilter && attachedPlayer->affects(targetElement, CSSPropertyWebkitFilter))) | 
| +            return true; | 
| +    } | 
| + | 
| +    return false; | 
| +} | 
| + | 
| } | 
|  | 
| bool CompositorAnimations::getAnimatedBoundingBox(FloatBox& box, const AnimationEffect& effect, double minValue, double maxValue) const | 
| @@ -133,12 +180,11 @@ bool CompositorAnimations::getAnimatedBoundingBox(FloatBox& box, const Animation | 
| // CompositorAnimations public API | 
| // ----------------------------------------------------------------------- | 
|  | 
| -bool CompositorAnimations::isCandidateForAnimationOnCompositor(const Timing& timing, const AnimationEffect& effect, double playerPlaybackRate) | 
| +bool CompositorAnimations::isCandidateForAnimationOnCompositor(const Timing& timing, const Element& targetElement, const AnimationPlayer* playerToAdd, const AnimationEffect& effect, double playerPlaybackRate) | 
| { | 
| const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(effect); | 
|  | 
| PropertySet properties = keyframeEffect.properties(); | 
| - | 
| if (properties.isEmpty()) | 
| return false; | 
|  | 
| @@ -164,11 +210,15 @@ bool CompositorAnimations::isCandidateForAnimationOnCompositor(const Timing& tim | 
| break; | 
| } | 
| default: | 
| +                // any other types are not allowed to run on compositor. | 
| return false; | 
| } | 
| } | 
| } | 
|  | 
| +    if (playerToAdd && hasIncompatibleAnimations(targetElement, *playerToAdd, effect)) | 
| +        return false; | 
| + | 
| CompositorAnimationsImpl::CompositorTiming out; | 
| if (!CompositorAnimationsImpl::convertTimingForCompositor(timing, 0, out, playerPlaybackRate)) | 
| return false; | 
| @@ -176,15 +226,39 @@ bool CompositorAnimations::isCandidateForAnimationOnCompositor(const Timing& tim | 
| return true; | 
| } | 
|  | 
| +void CompositorAnimations::cancelIncompatibleAnimationsOnCompositor(const Element& targetElement, const AnimationPlayer& playerToAdd, const AnimationEffect& effectToAdd) | 
| +{ | 
| +    const bool affectsOpacity = effectToAdd.affects(CSSPropertyOpacity); | 
| +    const bool affectsTransform = effectToAdd.affects(CSSPropertyTransform); | 
| +    const bool affectsFilter = effectToAdd.affects(CSSPropertyWebkitFilter); | 
| + | 
| +    if (!targetElement.hasActiveAnimations()) | 
| +        return; | 
| + | 
| +    ActiveAnimations* activeAnimations = targetElement.activeAnimations(); | 
| +    ASSERT(activeAnimations); | 
| + | 
| +    for (const auto& entry : activeAnimations->players()) { | 
| +        AnimationPlayer* attachedPlayer = entry.key; | 
| +        if (!considerPlayerAsIncompatible(*attachedPlayer, playerToAdd)) | 
| +            continue; | 
| + | 
| +        if ((affectsOpacity && attachedPlayer->affects(targetElement, CSSPropertyOpacity)) | 
| +            || (affectsTransform && attachedPlayer->affects(targetElement, CSSPropertyTransform)) | 
| +            || (affectsFilter && attachedPlayer->affects(targetElement, CSSPropertyWebkitFilter))) | 
| +            attachedPlayer->cancelAnimationOnCompositor(); | 
| +    } | 
| +} | 
| + | 
| bool CompositorAnimations::canStartAnimationOnCompositor(const Element& element) | 
| { | 
| return element.renderer() && element.renderer()->compositingState() == PaintsIntoOwnBacking; | 
| } | 
|  | 
| -bool CompositorAnimations::startAnimationOnCompositor(const Element& element, int group, double startTime, double timeOffset, const Timing& timing, 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, effect, playerPlaybackRate)); | 
| +    ASSERT(isCandidateForAnimationOnCompositor(timing, element, player, effect, playerPlaybackRate)); | 
| ASSERT(canStartAnimationOnCompositor(element)); | 
|  | 
| const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(effect); | 
|  |