Diff
Modified: trunk/Source/WebCore/ChangeLog (240011 => 240012)
--- trunk/Source/WebCore/ChangeLog 2019-01-15 22:57:27 UTC (rev 240011)
+++ trunk/Source/WebCore/ChangeLog 2019-01-15 23:06:11 UTC (rev 240012)
@@ -1,5 +1,44 @@
2019-01-15 Simon Fraser <[email protected]>
+ Animations should only trigger layer recomposite when necessary
+ https://bugs.webkit.org/show_bug.cgi?id=193450
+
+ Reviewed by Antoine Quint.
+
+ Animations only need to trigger compositing updates when their states change in a way
+ that affects compositing. RenderLayerCompositor::requiresCompositingForAnimation() checks for
+ running animations of properties that can be accelerated, so this patch fixes the legacy
+ animation logic to only set 'shouldRecompositeLayer' in TreeResolver::createAnimatedElementUpdate()
+ when the running state of such an animation changes.
+
+ ImplicitAnimation::animate() and KeyframeAnimation::animate() now return OptionSet<AnimateChange>.
+ This contains information about whether the running state changed, so CompositeAnimation::animate()
+ asks about whether the running state of an accelerated property changed, and returns this in
+ the AnimationUpdate result.
+
+ * page/animation/AnimationBase.h:
+ (WebCore::AnimationBase::isPausedState):
+ (WebCore::AnimationBase::isRunningState):
+ (WebCore::AnimationBase::inPausedState const):
+ (WebCore::AnimationBase::inRunningState const):
+ (WebCore::AnimationBase::isAnimatingProperty const):
+ * page/animation/CSSAnimationController.h:
+ * page/animation/CompositeAnimation.cpp:
+ (WebCore::CompositeAnimation::animate):
+ * page/animation/ImplicitAnimation.cpp:
+ (WebCore::ImplicitAnimation::animate):
+ (WebCore::ImplicitAnimation::affectsAcceleratedProperty const):
+ * page/animation/ImplicitAnimation.h:
+ * page/animation/KeyframeAnimation.cpp:
+ (WebCore::KeyframeAnimation::KeyframeAnimation):
+ (WebCore::KeyframeAnimation::animate):
+ (WebCore::KeyframeAnimation::computeStackingContextImpact): Deleted.
+ * page/animation/KeyframeAnimation.h:
+ * style/StyleTreeResolver.cpp:
+ (WebCore::Style::TreeResolver::createAnimatedElementUpdate):
+
+2019-01-15 Simon Fraser <[email protected]>
+
Clean up code related to the updating of Dashboard and touch event regions
https://bugs.webkit.org/show_bug.cgi?id=193460
Modified: trunk/Source/WebCore/page/animation/AnimationBase.h (240011 => 240012)
--- trunk/Source/WebCore/page/animation/AnimationBase.h 2019-01-15 22:57:27 UTC (rev 240011)
+++ trunk/Source/WebCore/page/animation/AnimationBase.h 2019-01-15 23:06:11 UTC (rev 240012)
@@ -44,6 +44,12 @@
class RenderStyle;
class TimingFunction;
+enum class AnimateChange {
+ StyleBlended = 1 << 0, // Style was changed.
+ StateChange = 1 << 1, // Animation state() changed.
+ RunningStateChange = 1 << 2, // Animation "running or paused" changed.
+};
+
class AnimationBase : public RefCounted<AnimationBase>
, public CSSPropertyBlendingClient {
friend class CompositeAnimation;
@@ -122,7 +128,13 @@
bool active() const { return !postActive() && !preActive(); }
bool running() const { return !isNew() && !postActive(); }
bool paused() const { return m_pauseTime || m_animationState == AnimationState::PausedNew; }
- bool inPausedState() const { return m_animationState >= AnimationState::PausedNew && m_animationState <= AnimationState::PausedRun; }
+
+ static bool isPausedState(AnimationState state) { return state >= AnimationState::PausedNew && state <= AnimationState::PausedRun; }
+ static bool isRunningState(AnimationState state) { return state >= AnimationState::StartWaitStyleAvailable && state < AnimationState::Done; }
+
+ bool inPausedState() const { return isPausedState(m_animationState); }
+ bool inRunningState() const { return isRunningState(m_animationState); }
+
bool isNew() const { return m_animationState == AnimationState::New || m_animationState == AnimationState::PausedNew; }
bool waitingForStartTime() const { return m_animationState == AnimationState::StartWaitResponse; }
bool waitingForStyleAvailable() const { return m_animationState == AnimationState::StartWaitStyleAvailable; }
@@ -163,13 +175,7 @@
if (!affectsProperty(property))
return false;
- if (inPausedState())
- return true;
-
- if (m_animationState >= AnimationState::StartWaitStyleAvailable && m_animationState < AnimationState::Done)
- return true;
-
- return false;
+ return inRunningState() || inPausedState();
}
bool transformFunctionListsMatch() const override { return m_transformFunctionListsMatch; }
Modified: trunk/Source/WebCore/page/animation/CSSAnimationController.h (240011 => 240012)
--- trunk/Source/WebCore/page/animation/CSSAnimationController.h 2019-01-15 22:57:27 UTC (rev 240011)
+++ trunk/Source/WebCore/page/animation/CSSAnimationController.h 2019-01-15 23:06:11 UTC (rev 240012)
@@ -44,7 +44,7 @@
struct AnimationUpdate {
std::unique_ptr<RenderStyle> style;
- bool stateChanged { false };
+ bool animationChangeRequiresRecomposite { false };
};
class CSSAnimationController {
Modified: trunk/Source/WebCore/page/animation/CompositeAnimation.cpp (240011 => 240012)
--- trunk/Source/WebCore/page/animation/CompositeAnimation.cpp 2019-01-15 22:57:27 UTC (rev 240011)
+++ trunk/Source/WebCore/page/animation/CompositeAnimation.cpp 2019-01-15 23:06:11 UTC (rev 240012)
@@ -286,7 +286,7 @@
updateKeyframeAnimations(element, currentStyle, targetStyle);
m_keyframeAnimations.checkConsistency();
- bool animationStateChanged = false;
+ bool animationChangeRequiresRecomposite = false;
bool forceStackingContext = false;
std::unique_ptr<RenderStyle> animatedStyle;
@@ -296,12 +296,11 @@
// to fill in a RenderStyle*& only if needed.
bool checkForStackingContext = false;
for (auto& transition : m_transitions.values()) {
- bool didBlendStyle = false;
- if (transition->animate(*this, targetStyle, animatedStyle, didBlendStyle))
- animationStateChanged = true;
+ auto changes = transition->animate(*this, targetStyle, animatedStyle);
+ if (changes.contains(AnimateChange::StyleBlended))
+ checkForStackingContext |= WillChangeData::propertyCreatesStackingContext(transition->animatingProperty());
- if (didBlendStyle)
- checkForStackingContext |= WillChangeData::propertyCreatesStackingContext(transition->animatingProperty());
+ animationChangeRequiresRecomposite = changes.contains(AnimateChange::RunningStateChange) && transition->affectsAcceleratedProperty();
}
if (animatedStyle && checkForStackingContext) {
@@ -326,11 +325,9 @@
for (auto& name : m_keyframeAnimationOrderMap) {
RefPtr<KeyframeAnimation> keyframeAnim = m_keyframeAnimations.get(name);
if (keyframeAnim) {
- bool didBlendStyle = false;
- if (keyframeAnim->animate(*this, targetStyle, animatedStyle, didBlendStyle))
- animationStateChanged = true;
-
- forceStackingContext |= didBlendStyle && keyframeAnim->triggersStackingContext();
+ auto changes = keyframeAnim->animate(*this, targetStyle, animatedStyle);
+ animationChangeRequiresRecomposite = changes.contains(AnimateChange::RunningStateChange) && keyframeAnim->affectsAcceleratedProperty();
+ forceStackingContext |= changes.contains(AnimateChange::StyleBlended) && keyframeAnim->triggersStackingContext();
m_hasAnimationThatDependsOnLayout |= keyframeAnim->dependsOnLayout();
}
}
@@ -344,7 +341,7 @@
animatedStyle->setZIndex(0);
}
- return { WTFMove(animatedStyle), animationStateChanged };
+ return { WTFMove(animatedStyle), animationChangeRequiresRecomposite };
}
std::unique_ptr<RenderStyle> CompositeAnimation::getAnimatedStyle() const
Modified: trunk/Source/WebCore/page/animation/ImplicitAnimation.cpp (240011 => 240012)
--- trunk/Source/WebCore/page/animation/ImplicitAnimation.cpp 2019-01-15 22:57:27 UTC (rev 240011)
+++ trunk/Source/WebCore/page/animation/ImplicitAnimation.cpp 2019-01-15 23:06:11 UTC (rev 240012)
@@ -61,12 +61,12 @@
return element()->document().hasListenerType(inListenerType);
}
-bool ImplicitAnimation::animate(CompositeAnimation& compositeAnimation, const RenderStyle& targetStyle, std::unique_ptr<RenderStyle>& animatedStyle, bool& didBlendStyle)
+OptionSet<AnimateChange> ImplicitAnimation::animate(CompositeAnimation& compositeAnimation, const RenderStyle& targetStyle, std::unique_ptr<RenderStyle>& animatedStyle)
{
// If we get this far and the animation is done, it means we are cleaning up a just finished animation.
// So just return. Everything is already all cleaned up.
if (postActive())
- return false;
+ return { };
AnimationState oldState = state();
@@ -85,9 +85,15 @@
// Fire the start timeout if needed
fireAnimationEventsIfNeeded();
-
- didBlendStyle = true;
- return state() != oldState;
+
+ OptionSet<AnimateChange> change(AnimateChange::StyleBlended);
+ if (state() != oldState)
+ change.add(AnimateChange::StateChange);
+
+ if ((isPausedState(oldState) || isRunningState(oldState)) != (isPausedState(state()) || isRunningState(state())))
+ change.add(AnimateChange::RunningStateChange);
+
+ return change;
}
void ImplicitAnimation::getAnimatedStyle(std::unique_ptr<RenderStyle>& animatedStyle)
@@ -131,6 +137,11 @@
return true;
}
+bool ImplicitAnimation::affectsAcceleratedProperty() const
+{
+ return CSSPropertyAnimation::animationOfPropertyIsAccelerated(m_animatingProperty);
+}
+
bool ImplicitAnimation::startAnimation(double timeOffset)
{
if (auto* renderer = compositedRenderer())
Modified: trunk/Source/WebCore/page/animation/ImplicitAnimation.h (240011 => 240012)
--- trunk/Source/WebCore/page/animation/ImplicitAnimation.h 2019-01-15 22:57:27 UTC (rev 240011)
+++ trunk/Source/WebCore/page/animation/ImplicitAnimation.h 2019-01-15 23:06:11 UTC (rev 240012)
@@ -53,12 +53,14 @@
void pauseAnimation(double timeOffset) override;
void endAnimation(bool fillingForwards = false) override;
- bool animate(CompositeAnimation&, const RenderStyle& targetStyle, std::unique_ptr<RenderStyle>& animatedStyle, bool& didBlendStyle);
+ OptionSet<AnimateChange> animate(CompositeAnimation&, const RenderStyle& targetStyle, std::unique_ptr<RenderStyle>& animatedStyle);
void getAnimatedStyle(std::unique_ptr<RenderStyle>& animatedStyle) override;
void reset(const RenderStyle& to, CompositeAnimation&);
bool computeExtentOfTransformAnimation(LayoutRect&) const override;
+ bool affectsAcceleratedProperty() const;
+
void setOverridden(bool);
bool overridden() const override { return m_overridden; }
Modified: trunk/Source/WebCore/page/animation/KeyframeAnimation.cpp (240011 => 240012)
--- trunk/Source/WebCore/page/animation/KeyframeAnimation.cpp 2019-01-15 22:57:27 UTC (rev 240011)
+++ trunk/Source/WebCore/page/animation/KeyframeAnimation.cpp 2019-01-15 23:06:11 UTC (rev 240012)
@@ -60,7 +60,17 @@
#endif
checkForMatchingColorFilterFunctionLists();
- computeStackingContextImpact();
+ for (auto propertyID : m_keyframes.properties()) {
+ if (WillChangeData::propertyCreatesStackingContext(propertyID))
+ m_triggersStackingContext = true;
+
+ if (CSSPropertyAnimation::animationOfPropertyIsAccelerated(propertyID))
+ m_hasAcceleratedProperty = true;
+
+ if (m_triggersStackingContext && m_hasAcceleratedProperty)
+ break;
+ }
+
computeLayoutDependency();
}
@@ -71,16 +81,6 @@
endAnimation();
}
-void KeyframeAnimation::computeStackingContextImpact()
-{
- for (auto propertyID : m_keyframes.properties()) {
- if (WillChangeData::propertyCreatesStackingContext(propertyID)) {
- m_triggersStackingContext = true;
- break;
- }
- }
-}
-
void KeyframeAnimation::computeLayoutDependency()
{
if (!m_keyframes.containsProperty(CSSPropertyTransform))
@@ -156,7 +156,7 @@
prog = progress(scale, offset, prevKeyframe.timingFunction());
}
-bool KeyframeAnimation::animate(CompositeAnimation& compositeAnimation, const RenderStyle& targetStyle, std::unique_ptr<RenderStyle>& animatedStyle, bool& didBlendStyle)
+OptionSet<AnimateChange> KeyframeAnimation::animate(CompositeAnimation& compositeAnimation, const RenderStyle& targetStyle, std::unique_ptr<RenderStyle>& animatedStyle)
{
AnimationState oldState = state();
@@ -171,12 +171,12 @@
updateStateMachine(AnimationStateInput::PlayStatePaused, -1);
}
- // If we get this far and the animation is done, it means we are cleaning up a just finished animation.
+ // If we get this far and the animation is done, it means we are cleaning up a just-finished animation.
// If so, we need to send back the targetStyle.
if (postActive()) {
if (!animatedStyle)
animatedStyle = RenderStyle::clonePtr(targetStyle);
- return false;
+ return { };
}
// If we are waiting for the start timer, we don't want to change the style yet.
@@ -185,12 +185,12 @@
// Special case 2 - if there is a backwards fill mode, then we want to continue
// through to the style blend so that we get the fromStyle.
if (waitingToStart() && m_animation->delay() > 0 && !m_animation->fillsBackwards())
- return false;
+ return { };
// If we have no keyframes, don't animate.
if (!m_keyframes.size()) {
updateStateMachine(AnimationStateInput::EndAnimation, -1);
- return false;
+ return { };
}
// Run a cycle of animation.
@@ -209,9 +209,15 @@
CSSPropertyAnimation::blendProperties(this, propertyID, animatedStyle.get(), fromStyle, toStyle, progress);
}
-
- didBlendStyle = true;
- return state() != oldState;
+
+ OptionSet<AnimateChange> change(AnimateChange::StyleBlended);
+ if (state() != oldState)
+ change.add(AnimateChange::StateChange);
+
+ if ((isPausedState(oldState) || isRunningState(oldState)) != (isPausedState(state()) || isRunningState(state())))
+ change.add(AnimateChange::RunningStateChange);
+
+ return change;
}
void KeyframeAnimation::getAnimatedStyle(std::unique_ptr<RenderStyle>& animatedStyle)
Modified: trunk/Source/WebCore/page/animation/KeyframeAnimation.h (240011 => 240012)
--- trunk/Source/WebCore/page/animation/KeyframeAnimation.h 2019-01-15 22:57:27 UTC (rev 240011)
+++ trunk/Source/WebCore/page/animation/KeyframeAnimation.h 2019-01-15 23:06:11 UTC (rev 240012)
@@ -44,8 +44,8 @@
{
return adoptRef(*new KeyframeAnimation(animation, element, compositeAnimation, unanimatedStyle));
}
-
- bool animate(CompositeAnimation&, const RenderStyle& targetStyle, std::unique_ptr<RenderStyle>& animatedStyle, bool& didBlendStyle);
+
+ OptionSet<AnimateChange> animate(CompositeAnimation&, const RenderStyle& targetStyle, std::unique_ptr<RenderStyle>& animatedStyle);
void getAnimatedStyle(std::unique_ptr<RenderStyle>&) override;
bool computeExtentOfTransformAnimation(LayoutRect&) const override;
@@ -58,6 +58,7 @@
bool triggersStackingContext() const { return m_triggersStackingContext; }
bool dependsOnLayout() const { return m_dependsOnLayout; }
+ bool affectsAcceleratedProperty() const { return m_hasAcceleratedProperty; }
void setUnanimatedStyle(std::unique_ptr<RenderStyle> style) { m_unanimatedStyle = WTFMove(style); }
const RenderStyle& unanimatedStyle() const override { return *m_unanimatedStyle; }
@@ -84,7 +85,6 @@
bool computeExtentOfAnimationForMatchingTransformLists(const FloatRect& rendererBox, LayoutRect&) const;
- void computeStackingContextImpact();
void computeLayoutDependency();
void resolveKeyframeStyles();
void validateTransformFunctionList();
@@ -107,6 +107,7 @@
bool m_startEventDispatched { false };
bool m_triggersStackingContext { false };
+ bool m_hasAcceleratedProperty { false };
bool m_dependsOnLayout { false };
};
Modified: trunk/Source/WebCore/style/StyleTreeResolver.cpp (240011 => 240012)
--- trunk/Source/WebCore/style/StyleTreeResolver.cpp 2019-01-15 22:57:27 UTC (rev 240011)
+++ trunk/Source/WebCore/style/StyleTreeResolver.cpp 2019-01-15 23:06:11 UTC (rev 240012)
@@ -306,7 +306,7 @@
auto& animationController = m_document.frame()->animation();
auto animationUpdate = animationController.updateAnimations(element, *newStyle, oldStyle);
- shouldRecompositeLayer = animationUpdate.stateChanged; // FIXME: constrain this to just property animations triggering acceleration.
+ shouldRecompositeLayer = animationUpdate.animationChangeRequiresRecomposite;
if (animationUpdate.style)
newStyle = WTFMove(animationUpdate.style);