Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(350)

Unified Diff: Source/core/animation/CompositorAnimations.cpp

Issue 881183003: Animation: Cancel same-property animations on compositor (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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);

Powered by Google App Engine
This is Rietveld 408576698