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