| 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);
|
|
|