Changeset 268932 in webkit
- Timestamp:
- Oct 23, 2020, 11:35:44 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r268927 r268932 1 2020-10-23 Antoine Quint <graouts@webkit.org> 2 3 REGRESSION(r268615): certain animations break when moving from one to display to another or resizing the window 4 https://bugs.webkit.org/show_bug.cgi?id=218080 5 <rdar://problem/70547132> 6 7 Reviewed by Dean Jackson. 8 9 Increase the fidelity of this test where the scale transform would sometimes yield some 0.01% ImageOnlyFailure results. 10 11 * webanimations/accelerated-translate-animation-additional-animation-added-in-flight-expected.html: 12 * webanimations/accelerated-translate-animation-additional-animation-added-in-flight.html: 13 1 14 2020-10-23 Hector Lopez <hector_i_lopez@apple.com> 2 15 -
trunk/LayoutTests/webanimations/accelerated-translate-animation-additional-animation-added-in-flight-expected.html
r268615 r268932 8 8 height: 100px; 9 9 background-color: black; 10 transform: translate X(100px) scale(0.5);10 transform: translate3d(50px, 50px, 0); 11 11 } 12 12 -
trunk/LayoutTests/webanimations/accelerated-translate-animation-additional-animation-added-in-flight.html
r268615 r268932 21 21 // Start an animation that lasts a day. 22 22 const duration = 24 * 60 * 60 * 1000; 23 const translateAnimation = document.getElementById("target").animate({ translate: " 200px" }, duration);23 const translateAnimation = document.getElementById("target").animate({ translate: "100px" }, duration); 24 24 translateAnimation.currentTime = duration / 2; 25 25 … … 29 29 30 30 // Add an extra animation. 31 const scaleAnimation = document.getElementById("target").animate({ scale: "0" }, duration);32 scaleAnimation.currentTime = duration / 2;31 const transformAnimation = document.getElementById("target").animate({ transform: "translateY(100px)" }, duration); 32 transformAnimation.currentTime = duration / 2; 33 33 34 34 // Wait until the new animation has been applied. 35 await scaleAnimation.ready;35 await transformAnimation.ready; 36 36 await UIHelper.ensureStablePresentationUpdate(); 37 37 -
trunk/Source/WebCore/ChangeLog
r268926 r268932 1 2020-10-23 Antoine Quint <graouts@webkit.org> 2 3 REGRESSION(r268615): certain animations break when moving from one to display to another or resizing the window 4 https://bugs.webkit.org/show_bug.cgi?id=218080 5 <rdar://problem/70547132> 6 7 Reviewed by Dean Jackson. 8 9 Since transform-related animations include non-interpolating animations meant to insert the static base value for a given 10 transform-related CSS property, we need to update animations on GraphicsLayerCA whenever one of the transform-related CSS 11 properties have a new value. 12 13 We used to rely on GraphicsLayerCA::setTransform() being called with a different transform than the current one to identify 14 such cases, but that is suboptimal because that method can be called with a compound interpolated value of transform-related 15 CSS properties when a rendering update occurs, such as during resizing or moving a window between displays. In those cases, 16 the static base value of the transform-related CSS properties hasn't actually changed. 17 18 Instead, we now provide the non-animated style from the last style change event to the function resolving keyframe effects 19 so that for a given element we can compare that style with the new, as-yet-non-animated style and see if any of the transform- 20 related CSS properties have been changed. If that is the case, we inform any KeyframeEffect that has a running accelerated 21 animation for any of those CSS properties so that the effect may enqueue an accelerated action that will then notify the 22 GraphicsLayer of such a change, and trigger an animation update. 23 24 Since we were changing the applyKeyframeEffects() method signature to add the extra RenderStyle needed to compare the current 25 and previous non-animated styles, we also moved that method from Element to KeyframeEffectStack since no Element private 26 API was required. 27 28 No new test since this was already tested by webanimations/accelerated-translate-animation-underlying-transform-changed-in-flight.html 29 and it's not clear how to test the live-resizing or display-change scenario. 30 31 * animation/KeyframeEffect.cpp: 32 (WebCore::KeyframeEffect::isRunningAcceleratedTransformRelatedAnimation const): New method called from KeyframeEffectStack::applyKeyframeEffects() 33 to indicate that a keyframe effect has a running accelerated animation targeting a transform-related property. 34 (WebCore::KeyframeEffect::addPendingAcceleratedAction): Ensure that the new AcceleratedAction::TransformChange accelerated action 35 recorded in transformRelatedPropertyDidChange() is not ever set as m_lastRecordedAcceleratedAction as we use this member to identify 36 whether we have a pending running, pause or stop action. 37 (WebCore::KeyframeEffect::transformRelatedPropertyDidChange): New method meant to be called for an effect that has a running 38 accelerated animation targeting a transform-related property to notify that one or more of the target element's transform-related 39 CSS property static values was changed. 40 (WebCore::KeyframeEffect::applyPendingAcceleratedActions): Call transformRelatedPropertyDidChange() on the composited renderer for 41 a AcceleratedAction::TransformChange action. 42 * animation/KeyframeEffect.h: 43 * animation/KeyframeEffectStack.cpp: 44 (WebCore::KeyframeEffectStack::applyKeyframeEffects): Move the method previously exposed on Element to KeyframeEffectStack. Additionally, 45 accept an extra RenderStyle parameter to provide the non-animated style from the last style change event so that we can compare that style 46 with the new, as-yet-non-animated style and see if any of the transform-related CSS properties have been changed and notify the effect 47 should it run an accelerated animation for one of those properties. 48 * animation/KeyframeEffectStack.h: 49 * dom/Element.cpp: 50 (WebCore::Element::applyKeyframeEffects): Deleted. Moved to KeyframeEffectStack. 51 * dom/Element.h: 52 * platform/graphics/GraphicsLayer.h: 53 (WebCore::GraphicsLayer::transformRelatedPropertyDidChange): 54 * platform/graphics/ca/GraphicsLayerCA.cpp: 55 (WebCore::GraphicsLayerCA::setTransform): Move the animation-update logic to transformRelatedPropertyDidChange() 56 (WebCore::GraphicsLayerCA::transformRelatedPropertyDidChange): 57 * platform/graphics/ca/GraphicsLayerCA.h: 58 * rendering/RenderElement.h: 59 (WebCore::RenderElement::transformRelatedPropertyDidChange): 60 * rendering/RenderLayerBacking.cpp: 61 (WebCore::RenderLayerBacking::transformRelatedPropertyDidChange): 62 * rendering/RenderLayerBacking.h: 63 * rendering/RenderLayerModelObject.cpp: 64 (WebCore::RenderLayerModelObject::transformRelatedPropertyDidChange): 65 * rendering/RenderLayerModelObject.h: 66 * style/StyleTreeResolver.cpp: 67 (WebCore::Style::TreeResolver::createAnimatedElementUpdate): Pass the non-animated style from the last style change event to 68 KeyframeEffectStack::applyKeyframeEffects() to determine whether this style change event includes a change to any of the 69 transform-related properties. 70 * style/Styleable.h: 71 (WebCore::Styleable::applyKeyframeEffects const): 72 1 73 2020-10-23 Chris Dumez <cdumez@apple.com> 2 74 -
trunk/Source/WebCore/animation/KeyframeEffect.cpp
r268730 r268932 1286 1286 } 1287 1287 1288 bool KeyframeEffect::isRunningAcceleratedTransformRelatedAnimation() const 1289 { 1290 if (!isRunningAccelerated()) 1291 return false; 1292 1293 return m_blendingKeyframes.properties().contains(CSSPropertyTranslate) 1294 || m_blendingKeyframes.properties().contains(CSSPropertyScale) 1295 || m_blendingKeyframes.properties().contains(CSSPropertyRotate) 1296 || m_blendingKeyframes.properties().contains(CSSPropertyTransform); 1297 } 1298 1288 1299 void KeyframeEffect::invalidate() 1289 1300 { … … 1593 1604 m_pendingAcceleratedActions.clear(); 1594 1605 m_pendingAcceleratedActions.append(action); 1595 if (action != AcceleratedAction::UpdateTiming )1606 if (action != AcceleratedAction::UpdateTiming && action != AcceleratedAction::TransformChange) 1596 1607 m_lastRecordedAcceleratedAction = action; 1597 1608 animation()->acceleratedStateDidChange(); … … 1618 1629 else if (canBeAccelerated()) 1619 1630 m_runningAccelerated = RunningAccelerated::NotStarted; 1631 } 1632 1633 void KeyframeEffect::transformRelatedPropertyDidChange() 1634 { 1635 ASSERT(isRunningAcceleratedTransformRelatedAnimation()); 1636 addPendingAcceleratedAction(AcceleratedAction::TransformChange); 1620 1637 } 1621 1638 … … 1709 1726 m_runningAccelerated = RunningAccelerated::NotStarted; 1710 1727 break; 1728 case AcceleratedAction::TransformChange: 1729 renderer->transformRelatedPropertyDidChange(); 1730 break; 1711 1731 } 1712 1732 } -
trunk/Source/WebCore/animation/KeyframeEffect.h
r267571 r268932 133 133 void animationTimelineDidChange(AnimationTimeline*) final; 134 134 void animationTimingDidChange(); 135 void transformRelatedPropertyDidChange(); 135 136 void applyPendingAcceleratedActions(); 136 137 … … 168 169 bool isCurrentlyAffectingProperty(CSSPropertyID, Accelerated = Accelerated::No) const; 169 170 bool isRunningAcceleratedAnimationForProperty(CSSPropertyID) const; 171 bool isRunningAcceleratedTransformRelatedAnimation() const; 170 172 171 173 bool requiresPseudoElement() const; … … 174 176 KeyframeEffect(Element*, PseudoId); 175 177 176 enum class AcceleratedAction : uint8_t { Play, Pause, UpdateTiming, Stop };178 enum class AcceleratedAction : uint8_t { Play, Pause, UpdateTiming, TransformChange, Stop }; 177 179 enum class BlendingKeyframesSource : uint8_t { CSSAnimation, CSSTransition, WebAnimation }; 178 180 enum class AcceleratedProperties : uint8_t { None, Some, All }; -
trunk/Source/WebCore/animation/KeyframeEffectStack.cpp
r267571 r268932 112 112 } 113 113 114 OptionSet<AnimationImpact> KeyframeEffectStack::applyKeyframeEffects(RenderStyle& targetStyle, const RenderStyle& previousLastStyleChangeEventStyle) 115 { 116 OptionSet<AnimationImpact> impact; 117 118 auto transformRelatedPropertyChanged = [&]() -> bool { 119 return !arePointingToEqualData(targetStyle.translate(), previousLastStyleChangeEventStyle.translate()) 120 || !arePointingToEqualData(targetStyle.scale(), previousLastStyleChangeEventStyle.scale()) 121 || !arePointingToEqualData(targetStyle.rotate(), previousLastStyleChangeEventStyle.rotate()) 122 || targetStyle.transform() != previousLastStyleChangeEventStyle.transform(); 123 }(); 124 125 for (const auto& effect : sortedEffects()) { 126 ASSERT(effect->animation()); 127 effect->animation()->resolve(targetStyle); 128 129 if (effect->isRunningAccelerated() || effect->isAboutToRunAccelerated()) 130 impact.add(AnimationImpact::RequiresRecomposite); 131 132 if (effect->triggersStackingContext()) 133 impact.add(AnimationImpact::ForcesStackingContext); 134 135 if (transformRelatedPropertyChanged && effect->isRunningAcceleratedTransformRelatedAnimation()) 136 effect->transformRelatedPropertyDidChange(); 137 } 138 139 return impact; 140 } 141 114 142 } // namespace WebCore -
trunk/Source/WebCore/animation/KeyframeEffectStack.h
r260139 r268932 28 28 #include "AnimationList.h" 29 29 #include "CSSPropertyNames.h" 30 #include "WebAnimationTypes.h" 30 31 #include <wtf/Vector.h> 31 32 #include <wtf/WeakPtr.h> … … 49 50 bool isCurrentlyAffectingProperty(CSSPropertyID) const; 50 51 bool requiresPseudoElement() const; 52 OptionSet<AnimationImpact> applyKeyframeEffects(RenderStyle& targetStyle, const RenderStyle& previousLastStyleChangeEventStyle); 51 53 52 54 private: -
trunk/Source/WebCore/dom/Element.cpp
r268808 r268932 3823 3823 } 3824 3824 3825 OptionSet<AnimationImpact> Element::applyKeyframeEffects(PseudoId pseudoId, RenderStyle& targetStyle)3826 {3827 OptionSet<AnimationImpact> impact;3828 3829 for (const auto& effect : ensureKeyframeEffectStack(pseudoId).sortedEffects()) {3830 ASSERT(effect->animation());3831 effect->animation()->resolve(targetStyle);3832 3833 if (effect->isRunningAccelerated() || effect->isAboutToRunAccelerated())3834 impact.add(AnimationImpact::RequiresRecomposite);3835 3836 if (effect->triggersStackingContext())3837 impact.add(AnimationImpact::ForcesStackingContext);3838 }3839 3840 return impact;3841 }3842 3843 3825 const AnimationCollection* Element::animations(PseudoId pseudoId) const 3844 3826 { -
trunk/Source/WebCore/dom/Element.h
r268808 r268932 490 490 KeyframeEffectStack& ensureKeyframeEffectStack(PseudoId); 491 491 bool hasKeyframeEffects(PseudoId) const; 492 OptionSet<AnimationImpact> applyKeyframeEffects(PseudoId, RenderStyle&);493 492 494 493 const AnimationCollection* animations(PseudoId) const; -
trunk/Source/WebCore/platform/graphics/GraphicsLayer.h
r268898 r268932 486 486 virtual void pauseAnimation(const String& /*animationName*/, double /*timeOffset*/) { } 487 487 virtual void removeAnimation(const String& /*animationName*/) { } 488 488 virtual void transformRelatedPropertyDidChange() { } 489 489 WEBCORE_EXPORT virtual void suspendAnimations(MonotonicTime); 490 490 WEBCORE_EXPORT virtual void resumeAnimations(); -
trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.cpp
r268898 r268932 667 667 GraphicsLayer::setTransform(t); 668 668 noteLayerPropertyChanged(TransformChanged); 669 670 // If we are currently running a transform-related animation, a change in underlying671 // transform value means we must re-evaluate all transform-related animations to ensure672 // that the base value transform animations are current.673 if (isRunningTransformAnimation())674 noteLayerPropertyChanged(AnimationChanged | CoverageRectChanged);675 669 } 676 670 … … 1108 1102 } 1109 1103 } 1104 } 1105 1106 void GraphicsLayerCA::transformRelatedPropertyDidChange() 1107 { 1108 // If we are currently running a transform-related animation, a change in underlying 1109 // transform value means we must re-evaluate all transform-related animations to ensure 1110 // that the base value transform animations are current. 1111 if (isRunningTransformAnimation()) 1112 noteLayerPropertyChanged(AnimationChanged | CoverageRectChanged); 1110 1113 } 1111 1114 -
trunk/Source/WebCore/platform/graphics/ca/GraphicsLayerCA.h
r268898 r268932 139 139 WEBCORE_EXPORT void pauseAnimation(const String& animationName, double timeOffset) override; 140 140 WEBCORE_EXPORT void removeAnimation(const String& animationName) override; 141 141 WEBCORE_EXPORT void transformRelatedPropertyDidChange() override; 142 142 WEBCORE_EXPORT void setContentsToImage(Image*) override; 143 143 #if PLATFORM(IOS_FAMILY) -
trunk/Source/WebCore/rendering/RenderElement.h
r268021 r268932 231 231 virtual void animationPaused(double /* timeOffset */, const String& /* name */) { } 232 232 virtual void animationFinished(const String& /* name */) { } 233 virtual void transformRelatedPropertyDidChange() { } 233 234 234 235 virtual void suspendAnimations(MonotonicTime = MonotonicTime()) { } -
trunk/Source/WebCore/rendering/RenderLayerBacking.cpp
r268898 r268932 3670 3670 } 3671 3671 3672 void RenderLayerBacking::transformRelatedPropertyDidChange() 3673 { 3674 m_graphicsLayer->transformRelatedPropertyDidChange(); 3675 } 3676 3672 3677 void RenderLayerBacking::notifyAnimationStarted(const GraphicsLayer*, const String&, MonotonicTime) 3673 3678 { -
trunk/Source/WebCore/rendering/RenderLayerBacking.h
r268615 r268932 189 189 void animationPaused(double timeOffset, const String& name); 190 190 void animationFinished(const String& name); 191 191 void transformRelatedPropertyDidChange(); 192 192 void suspendAnimations(MonotonicTime = MonotonicTime()); 193 193 void resumeAnimations(); -
trunk/Source/WebCore/rendering/RenderLayerModelObject.cpp
r267188 r268932 272 272 } 273 273 274 void RenderLayerModelObject::transformRelatedPropertyDidChange() 275 { 276 if (!layer() || !layer()->backing()) 277 return; 278 layer()->backing()->transformRelatedPropertyDidChange(); 279 } 280 274 281 void RenderLayerModelObject::suspendAnimations(MonotonicTime time) 275 282 { -
trunk/Source/WebCore/rendering/RenderLayerModelObject.h
r267188 r268932 73 73 void animationPaused(double timeOffset, const String& name) override; 74 74 void animationFinished(const String& name) override; 75 void transformRelatedPropertyDidChange() override; 75 76 76 77 void suspendAnimations(MonotonicTime = MonotonicTime()) override; -
trunk/Source/WebCore/style/StyleTreeResolver.cpp
r267571 r268932 350 350 // as animations created via the JS API. 351 351 if (styleable.hasKeyframeEffects()) { 352 auto previousLastStyleChangeEventStyle = styleable.lastStyleChangeEventStyle() ? RenderStyle::clonePtr(*styleable.lastStyleChangeEventStyle()) : RenderStyle::createPtr(); 352 353 // Record the style prior to applying animations for this style change event. 353 354 styleable.setLastStyleChangeEventStyle(RenderStyle::clonePtr(*newStyle)); 354 355 // Apply all keyframe effects to the new style. 355 356 auto animatedStyle = RenderStyle::clonePtr(*newStyle); 356 animationImpact = styleable.applyKeyframeEffects(*animatedStyle );357 animationImpact = styleable.applyKeyframeEffects(*animatedStyle, *previousLastStyleChangeEventStyle); 357 358 newStyle = WTFMove(animatedStyle); 358 359 } else -
trunk/Source/WebCore/style/Styleable.h
r268808 r268932 27 27 28 28 #include "Element.h" 29 #include "KeyframeEffectStack.h" 29 30 #include "PseudoElement.h" 30 31 #include "RenderElement.h" … … 87 88 } 88 89 89 OptionSet<AnimationImpact> applyKeyframeEffects(RenderStyle& style) const90 OptionSet<AnimationImpact> applyKeyframeEffects(RenderStyle& targetStyle, const RenderStyle& previousLastStyleChangeEventStyle) const 90 91 { 91 return element. applyKeyframeEffects(pseudoId, style);92 return element.ensureKeyframeEffectStack(pseudoId).applyKeyframeEffects(targetStyle, previousLastStyleChangeEventStyle); 92 93 } 93 94
Note:
See TracChangeset
for help on using the changeset viewer.