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..66b4dfe3fbb6d073ac586e1f15ae977301d3abd7 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,37 @@ void getKeyframeValuesForProperty(const KeyframeEffectModelBase* effect, CSSProp |
| } |
| } |
| +bool alreadyActiveAnimationsBlockProperties(const Element& targetElement, const AnimationPlayer& playerToAdd, const AnimationEffect& effectToAdd) |
|
dstockwell
2015/01/28 05:44:05
I think this would be better written as:
bool aff
loyso (OOO)
2015/01/28 06:33:31
Good point. That's also will be more efficient.
|
| +{ |
| + bool propertyOpacityBlocked = false; |
| + bool propertyTransformBlocked = false; |
| + bool propertyFilterBlocked = false; |
| + |
| + if (targetElement.hasActiveAnimations()) { |
| + ActiveAnimations* activeAnimations = targetElement.activeAnimations(); |
| + ASSERT(activeAnimations); |
| + |
| + for (const auto& entry : activeAnimations->players()) { |
| + const AnimationPlayer* attachedPlayer = entry.key; |
|
dstockwell
2015/01/28 05:44:05
Is it possible to skip consideration of earlier pl
loyso (OOO)
2015/01/29 01:08:54
What do you mean? Players with fill=forwards will
dstockwell
2015/01/29 01:14:07
Yes. Hmm, also players which are idle or finished
loyso (OOO)
2015/01/29 04:35:59
Is that a problem? Should we address it?
|
| + if (attachedPlayer == &playerToAdd) |
| + continue; |
| + |
| + if (attachedPlayer->affects(CSSPropertyOpacity)) |
| + propertyOpacityBlocked = true; |
| + else if (attachedPlayer->affects(CSSPropertyTransform)) |
| + propertyTransformBlocked = true; |
| + else if (attachedPlayer->affects(CSSPropertyWebkitFilter)) |
| + propertyFilterBlocked = true; |
| + } |
| + } |
| + |
| + if ((propertyOpacityBlocked && effectToAdd.affects(CSSPropertyOpacity)) |
| + || (propertyTransformBlocked && effectToAdd.affects(CSSPropertyTransform)) |
| + || (propertyFilterBlocked && effectToAdd.affects(CSSPropertyWebkitFilter))) |
| + return true; |
| + |
| + return false; |
| +} |
| } |
| bool CompositorAnimations::getAnimatedBoundingBox(FloatBox& box, const AnimationEffect& effect, double minValue, double maxValue) const |
| @@ -133,12 +165,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) |
|
dstockwell
2015/01/28 05:44:05
When can targetElement be null?
loyso (OOO)
2015/01/28 06:33:31
Unit tests. I could setup a fake one there if we n
loyso (OOO)
2015/01/28 23:18:34
Do we need it?
dstockwell
2015/01/29 01:14:07
Unless it's non-trivial to create an Element in th
|
| { |
| + if (targetElement && playerToAdd && alreadyActiveAnimationsBlockProperties(*targetElement, *playerToAdd, effect)) |
| + return false; |
| + |
| const KeyframeEffectModelBase& keyframeEffect = toKeyframeEffectModelBase(effect); |
| PropertySet properties = keyframeEffect.properties(); |
| - |
| if (properties.isEmpty()) |
| return false; |
| @@ -164,6 +198,7 @@ bool CompositorAnimations::isCandidateForAnimationOnCompositor(const Timing& tim |
| break; |
| } |
| default: |
| + // any other types are not allowed to run on compositor. |
| return false; |
| } |
| } |
| @@ -176,15 +211,39 @@ bool CompositorAnimations::isCandidateForAnimationOnCompositor(const Timing& tim |
| return true; |
| } |
| +void CompositorAnimations::cancelAffectedAnimationsOnCompositor(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 (attachedPlayer == &playerToAdd) |
| + continue; |
| + |
| + if ((propertyOpacityCancel && attachedPlayer->affects(CSSPropertyOpacity)) |
| + || (propertyTransformCancel && attachedPlayer->affects(CSSPropertyTransform)) |
| + || (propertyFilterCancel && attachedPlayer->affects(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); |