Chromium Code Reviews| Index: Source/core/animation/CompositorAnimations.cpp |
| diff --git a/Source/core/animation/CompositorAnimations.cpp b/Source/core/animation/CompositorAnimations.cpp |
| index 16aa2904cb069e1fd2b64a5d80eea28198202ed2..2e7a9010dc75595bf71c0d7eb77d98c616aa19be 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 player.sequenceNumber() > playerToAdd.sequenceNumber(); |
| + default: |
| + ASSERT_NOT_REACHED(); |
| + return true; |
| + } |
| + |
| + return true; |
| +} |
| + |
| +bool hasIncompatatibleAnimations(const Element& targetElement, const AnimationPlayer& playerToAdd, const AnimationEffect& effectToAdd) |
|
dstockwell
2015/01/30 02:39:23
Incompatatible -> Incompatible
loyso (OOO)
2015/01/30 02:53:11
Done.
|
| +{ |
| + const bool affectsOpacity = effectToAdd.affects(CSSPropertyOpacity); |
| + const bool affectsTransform = effectToAdd.affects(CSSPropertyTransform); |
| + const bool affectsFilter = effectToAdd.affects(CSSPropertyWebkitFilter); |
| + |
| + if (targetElement.hasActiveAnimations()) { |
| + 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,14 @@ 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) |
| { |
| + if (playerToAdd && hasIncompatatibleAnimations(targetElement, *playerToAdd, effect)) |
|
dstockwell
2015/01/30 02:39:23
Perhaps we should move this check to the end -- ar
loyso (OOO)
2015/01/30 02:53:11
Done.
|
| + return false; |
| + |
| const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(effect); |
| PropertySet properties = keyframeEffect.properties(); |
| - |
| if (properties.isEmpty()) |
| return false; |
| @@ -164,6 +213,7 @@ bool CompositorAnimations::isCandidateForAnimationOnCompositor(const Timing& tim |
| break; |
| } |
| default: |
| + // any other types are not allowed to run on compositor. |
| 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 propertyOpacityCancel = effectToAdd.affects(CSSPropertyOpacity); |
| + const bool propertyTransformCancel = effectToAdd.affects(CSSPropertyTransform); |
| + const bool propertyFilterCancel = 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 ((propertyOpacityCancel && attachedPlayer->affects(targetElement, CSSPropertyOpacity)) |
| + || (propertyTransformCancel && attachedPlayer->affects(targetElement, CSSPropertyTransform)) |
| + || (propertyFilterCancel && 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); |