Changeset 271524 in webkit
- Timestamp:
- Jan 15, 2021 9:47:18 AM (18 months ago)
- Location:
- trunk
- Files:
-
- 6 added
- 11 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/platform/win/TestExpectations (modified) (1 diff)
-
LayoutTests/webanimations/combining-transform-animations-with-different-acceleration-capabilities-2-expected.txt (added)
-
LayoutTests/webanimations/combining-transform-animations-with-different-acceleration-capabilities-2.html (added)
-
LayoutTests/webanimations/combining-transform-animations-with-different-acceleration-capabilities-3-expected.txt (added)
-
LayoutTests/webanimations/combining-transform-animations-with-different-acceleration-capabilities-3.html (added)
-
LayoutTests/webanimations/combining-transform-animations-with-different-acceleration-capabilities-expected.txt (added)
-
LayoutTests/webanimations/combining-transform-animations-with-different-acceleration-capabilities.html (added)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/animation/DocumentTimeline.cpp (modified) (2 diffs)
-
Source/WebCore/animation/KeyframeEffect.cpp (modified) (8 diffs)
-
Source/WebCore/animation/KeyframeEffect.h (modified) (3 diffs)
-
Source/WebCore/animation/KeyframeEffectStack.cpp (modified) (1 diff)
-
Source/WebCore/animation/KeyframeEffectStack.h (modified) (1 diff)
-
Source/WebCore/animation/WebAnimation.cpp (modified) (1 diff)
-
Source/WebCore/animation/WebAnimation.h (modified) (1 diff)
-
Source/WebCore/animation/WebAnimationTypes.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r271523 r271524 1 2021-01-15 Antoine Quint <graouts@webkit.org> 2 3 Reversed transform animation not applied alongside other transform animations 4 https://bugs.webkit.org/show_bug.cgi?id=218655 5 <rdar://problem/71116284> 6 7 Reviewed by Simon Fraser. 8 9 Add new tests that start a transform-related animation that runs accelerated, then add another 10 transform-related animation that either initially or eventually is not accelerated. In all cases, 11 we check that once the second animation is no longer accelerated that the first animation is also 12 no longer accelerated. 13 14 * platform/win/TestExpectations: 15 * webanimations/combining-transform-animations-with-different-acceleration-capabilities-2-expected.txt: Added. 16 * webanimations/combining-transform-animations-with-different-acceleration-capabilities-2.html: Added. 17 * webanimations/combining-transform-animations-with-different-acceleration-capabilities-3-expected.txt: Added. 18 * webanimations/combining-transform-animations-with-different-acceleration-capabilities-3.html: Added. 19 * webanimations/combining-transform-animations-with-different-acceleration-capabilities-expected.txt: Added. 20 * webanimations/combining-transform-animations-with-different-acceleration-capabilities.html: Added. 21 1 22 2021-01-15 Tomoki Imai <Tomoki.Imai@sony.com> 2 23 -
trunk/LayoutTests/platform/win/TestExpectations
r271425 r271524 4616 4616 4617 4617 webkit.org/b/220536 fast/text/cjk-multi-codepoint-cluster-vertical.html [ ImageOnlyFailure ] 4618 4619 # These tests time out on Windows 4620 webkit.org/b/220653 webanimations/combining-transform-animations-with-different-acceleration-capabilities-2.html [ Skip ] 4621 webkit.org/b/220653 webanimations/combining-transform-animations-with-different-acceleration-capabilities-3.html [ Skip ] 4622 webkit.org/b/220653 webanimations/combining-transform-animations-with-different-acceleration-capabilities.html [ Skip ] -
trunk/Source/WebCore/ChangeLog
r271523 r271524 1 2021-01-15 Antoine Quint <graouts@webkit.org> 2 3 Reversed transform animation not applied alongside other transform animations 4 https://bugs.webkit.org/show_bug.cgi?id=218655 5 <rdar://problem/71116284> 6 7 Reviewed by Simon Fraser. 8 9 Tests: webanimations/combining-transform-animations-with-different-acceleration-capabilities-2.html 10 webanimations/combining-transform-animations-with-different-acceleration-capabilities-3.html 11 webanimations/combining-transform-animations-with-different-acceleration-capabilities.html 12 13 While, in theory, animations for a transform-related CSS property (translate, rotate, scale and transform) 14 can be accelerated, there are various reasons why it might not, in fact, run accelerated. 15 16 One example is that the timing function is not something we can translate in terms Core Animation can 17 understand, such as the steps() timing function. In this case, the KeyframeEffect itself is aware of 18 the limitation and the method KeyframeEffect::canBeAccelerated() returns false. 19 20 Another example is that the playback rate of the animation is not 1, which we currently don't support for 21 Core Animation animations (see bug 211839). In this case, GraphicsLayerCA is where the impossibility to 22 run an animation accelerated is determined. 23 24 While we support running transform-related animations with or without acceleration, one thing we cannot 25 support is, for the same element, running some transform-related animations with acceleration, and some 26 without. 27 28 Thus, regardless of where we determine that a transform-related animation cannot be accelerated, we need 29 to send this information up to the KeyframeEffectStack in which this animation's effect belongs to make 30 sure that any other transform-related animation that may already be running accelerated no longer does 31 and continues running without acceleration. 32 33 There are two locations where we determine that a transform-related animation cannot be accelerated: 34 35 1. in DocumentTimeline::applyPendingAcceleratedAnimations() under which we start, update or stop 36 accelerated animations that have been invalidated since the last page rendering, 37 2. in KeyframeEffect::updateAcceleratedActions() which is called for each page rendering, including 38 animations that cannot be accelerated. 39 40 In the first case, we catch situations where an animation that could have been accelerated but failed 41 to be started due to the internal logic of GraphicsLayerCA. We use the new KeyframeEffect method 42 applyPendingAcceleratedActions() return value to determine this, and for each effect where the result 43 indicates that a transform-related animation could not be accelerated, we add the KeyframeEffectStack 44 to which it belongs and, once we're done with updating all effects, call the new 45 stopAcceleratingTransformRelatedProperties() method on the keyframe effect stack. 46 47 In the second case, we catch situations where an animation is known to not be able to run accelerated 48 even without involving GraphicsLayerCA. We check whether the animation targets a transform-related 49 property and if it is active, and if so call stopAcceleratingTransformRelatedProperties() 50 on the keyframe effect stack there as well. 51 52 When KeyframeEffectStack::stopAcceleratingTransformRelatedProperties() is called, we go 53 through all the registered effects and call stopAcceleratingTransformRelatedProperties(). This new 54 KeyframeEffect method will either add a pending accelerated action to stop the accelerated animation, 55 or if we're currently apply accelerated actions (ie. during DocumentTimeline::applyPendingAcceleratedAnimations()), 56 we stop the accelerated animation right away. 57 58 In both cases we know not to try running this animation again with acceleration by setting m_runningAccelerated 59 to RunningAccelerated::No. 60 61 * animation/DocumentTimeline.cpp: 62 (WebCore::DocumentTimeline::applyPendingAcceleratedAnimations): 63 * animation/KeyframeEffect.cpp: 64 (WebCore::KeyframeEffect::isTargetingTransformRelatedProperty const): 65 (WebCore::KeyframeEffect::isRunningAcceleratedTransformRelatedAnimation const): 66 (WebCore::KeyframeEffect::updateAcceleratedActions): 67 (WebCore::KeyframeEffect::applyPendingAcceleratedActions): 68 (WebCore::KeyframeEffect::stopAcceleratingTransformRelatedProperties): 69 * animation/KeyframeEffect.h: 70 * animation/KeyframeEffectStack.cpp: 71 (WebCore::KeyframeEffectStack::stopAcceleratingTransformRelatedProperties): 72 * animation/KeyframeEffectStack.h: 73 * animation/WebAnimation.cpp: 74 (WebCore::WebAnimation::applyPendingAcceleratedActions): Deleted. 75 * animation/WebAnimation.h: 76 * animation/WebAnimationTypes.h: 77 1 78 2021-01-15 Tomoki Imai <Tomoki.Imai@sony.com> 2 79 -
trunk/Source/WebCore/animation/DocumentTimeline.cpp
r268809 r271524 42 42 #include "RenderLayer.h" 43 43 #include "RenderLayerBacking.h" 44 #include "WebAnimationTypes.h" 44 45 45 46 namespace WebCore { … … 443 444 m_acceleratedAnimationsPendingRunningStateChange.clear(); 444 445 446 // Animations may fail to run accelerated for reasons private to GraphicsLayerCA. If that happens, and the animation 447 // in question targets a transform-related property, we must prevent all other transform-related animations for this 448 // element to run accelerated since we can't run some transform-related animations accelerated, and some not. To do 449 // this, we keep a list of all KeyframeEffectStack objects containing an effect that failed to start a transform-related 450 // animation so that we can return any transform-related accelerated animation to run non-accelerated. 451 HashSet<KeyframeEffectStack*> effectStacksContainingEffectThatFailedToRunAcceleratedTransformRelatedAnimation; 452 445 453 bool hasForcedLayout = false; 446 454 for (auto& animation : acceleratedAnimationsPendingRunningStateChange) { 447 if (!hasForcedLayout) { 448 auto* effect = animation->effect(); 449 if (is<KeyframeEffect>(effect)) 450 hasForcedLayout |= downcast<KeyframeEffect>(effect)->forceLayoutIfNeeded(); 451 } 452 animation->applyPendingAcceleratedActions(); 453 } 455 auto* effect = animation->effect(); 456 if (!is<KeyframeEffect>(effect)) 457 continue; 458 459 auto& keyframeEffect = downcast<KeyframeEffect>(*effect); 460 if (!hasForcedLayout) 461 hasForcedLayout |= keyframeEffect.forceLayoutIfNeeded(); 462 auto pendingAccelerationActionResult = keyframeEffect.applyPendingAcceleratedActions(); 463 if (pendingAccelerationActionResult.contains(AcceleratedActionApplicationResult::TransformRelatedAnimationCannotBeAccelerated)) { 464 ASSERT(keyframeEffect.targetStyleable()); 465 ASSERT(keyframeEffect.targetStyleable()->keyframeEffectStack()); 466 effectStacksContainingEffectThatFailedToRunAcceleratedTransformRelatedAnimation.add(keyframeEffect.targetStyleable()->keyframeEffectStack()); 467 } 468 } 469 470 for (auto& effectStack : effectStacksContainingEffectThatFailedToRunAcceleratedTransformRelatedAnimation) 471 effectStack->stopAcceleratingTransformRelatedProperties(UseAcceleratedAction::No); 454 472 } 455 473 -
trunk/Source/WebCore/animation/KeyframeEffect.cpp
r271269 r271524 1282 1282 } 1283 1283 1284 bool KeyframeEffect::isRunningAcceleratedTransformRelatedAnimation() const 1285 { 1286 if (!isRunningAccelerated()) 1287 return false; 1288 1284 bool KeyframeEffect::isTargetingTransformRelatedProperty() const 1285 { 1289 1286 return m_blendingKeyframes.properties().contains(CSSPropertyTranslate) 1290 1287 || m_blendingKeyframes.properties().contains(CSSPropertyScale) 1291 1288 || m_blendingKeyframes.properties().contains(CSSPropertyRotate) 1292 1289 || m_blendingKeyframes.properties().contains(CSSPropertyTransform); 1290 } 1291 1292 bool KeyframeEffect::isRunningAcceleratedTransformRelatedAnimation() const 1293 { 1294 return isRunningAccelerated() && isTargetingTransformRelatedProperty(); 1293 1295 } 1294 1296 … … 1575 1577 void KeyframeEffect::updateAcceleratedActions() 1576 1578 { 1577 if (!canBeAccelerated()) 1578 return; 1579 if (!canBeAccelerated()) { 1580 // In the case where this animation is actively targeting a transform-related property and yet 1581 // cannot be accelerated, we must notify the effect stack such that any running accelerated 1582 // transform-related animation targeting this element reverts to running non-accelerated. 1583 if (isTargetingTransformRelatedProperty() 1584 && animation()->playState() == WebAnimation::PlayState::Running 1585 && getComputedTiming().phase == AnimationEffectPhase::Active) { 1586 ASSERT(targetStyleable()); 1587 ASSERT(targetStyleable()->keyframeEffectStack()); 1588 targetStyleable()->keyframeEffectStack()->stopAcceleratingTransformRelatedProperties(UseAcceleratedAction::Yes); 1589 } 1590 return; 1591 } 1579 1592 1580 1593 auto computedTiming = getComputedTiming(); … … 1668 1681 } 1669 1682 1670 void KeyframeEffect::applyPendingAcceleratedActions() 1671 { 1683 OptionSet<AcceleratedActionApplicationResult> KeyframeEffect::applyPendingAcceleratedActions() 1684 { 1685 OptionSet<AcceleratedActionApplicationResult> result; 1686 1672 1687 // Once an accelerated animation has been committed, we no longer want to force a layout. 1673 1688 // This should have been performed by a call to forceLayoutIfNeeded() prior to applying … … 1676 1691 1677 1692 if (m_pendingAcceleratedActions.isEmpty()) 1678 return ;1693 return result; 1679 1694 1680 1695 auto* renderer = this->renderer(); … … 1686 1701 m_runningAccelerated = RunningAccelerated::NotStarted; 1687 1702 } 1688 return ;1703 return result; 1689 1704 } 1690 1705 … … 1720 1735 if (m_runningAccelerated == RunningAccelerated::No) { 1721 1736 m_lastRecordedAcceleratedAction = AcceleratedAction::Stop; 1722 return; 1737 if (isTargetingTransformRelatedProperty()) 1738 result.add(AcceleratedActionApplicationResult::TransformRelatedAnimationCannotBeAccelerated); 1739 return result; 1723 1740 } 1724 1741 break; … … 1737 1754 if (!document()->renderTreeBeingDestroyed()) 1738 1755 m_target->invalidateStyleAndLayerComposition(); 1739 m_runningAccelerated = RunningAccelerated::NotStarted;1756 m_runningAccelerated = canBeAccelerated() ? RunningAccelerated::NotStarted : RunningAccelerated::No; 1740 1757 break; 1741 1758 case AcceleratedAction::TransformChange: … … 1744 1761 } 1745 1762 } 1763 1764 if (m_runningAccelerated == RunningAccelerated::No && isTargetingTransformRelatedProperty()) 1765 result.add(AcceleratedActionApplicationResult::TransformRelatedAnimationCannotBeAccelerated); 1766 1767 return result; 1768 } 1769 1770 void KeyframeEffect::stopAcceleratingTransformRelatedProperties(UseAcceleratedAction useAcceleratedAction) 1771 { 1772 if (!isRunningAcceleratedTransformRelatedAnimation()) 1773 return; 1774 1775 if (useAcceleratedAction == UseAcceleratedAction::Yes) { 1776 addPendingAcceleratedAction(AcceleratedAction::Stop); 1777 return; 1778 } 1779 1780 auto* renderer = this->renderer(); 1781 if (!renderer || !renderer->isComposited()) 1782 return; 1783 1784 ASSERT(document()); 1785 renderer->animationFinished(m_blendingKeyframes.animationName()); 1786 if (!document()->renderTreeBeingDestroyed()) 1787 m_target->invalidateStyleAndLayerComposition(); 1788 1789 m_runningAccelerated = RunningAccelerated::No; 1746 1790 } 1747 1791 -
trunk/Source/WebCore/animation/KeyframeEffect.h
r270837 r271524 134 134 void animationTimingDidChange(); 135 135 void transformRelatedPropertyDidChange(); 136 voidapplyPendingAcceleratedActions();136 OptionSet<AcceleratedActionApplicationResult> applyPendingAcceleratedActions(); 137 137 138 138 void willChangeRenderer(); … … 172 172 bool requiresPseudoElement() const; 173 173 bool hasImplicitKeyframes() const; 174 175 void stopAcceleratingTransformRelatedProperties(UseAcceleratedAction); 174 176 175 177 private: … … 204 206 Seconds timeToNextTick() const final; 205 207 Optional<double> progressUntilNextStep(double) const final; 208 bool isTargetingTransformRelatedProperty() const; 206 209 void checkForMatchingTransformFunctionLists(); 207 210 void checkForMatchingFilterFunctionLists(); -
trunk/Source/WebCore/animation/KeyframeEffectStack.cpp
r270837 r271524 149 149 } 150 150 151 void KeyframeEffectStack::stopAcceleratingTransformRelatedProperties(UseAcceleratedAction useAcceleratedAction) 152 { 153 for (auto& effect : m_effects) 154 effect->stopAcceleratingTransformRelatedProperties(useAcceleratedAction); 155 } 156 151 157 } // namespace WebCore -
trunk/Source/WebCore/animation/KeyframeEffectStack.h
r270837 r271524 54 54 bool hasEffectWithImplicitKeyframes() const; 55 55 56 void stopAcceleratingTransformRelatedProperties(UseAcceleratedAction); 57 56 58 private: 57 59 void ensureEffectsAreSorted(); -
trunk/Source/WebCore/animation/WebAnimation.cpp
r269914 r271524 1254 1254 } 1255 1255 1256 void WebAnimation::applyPendingAcceleratedActions()1257 {1258 if (is<KeyframeEffect>(m_effect))1259 downcast<KeyframeEffect>(*m_effect).applyPendingAcceleratedActions();1260 }1261 1262 1256 WebAnimation& WebAnimation::readyPromiseResolve() 1263 1257 { -
trunk/Source/WebCore/animation/WebAnimation.h
r269914 r271524 125 125 void effectTargetDidChange(const Optional<const Styleable>& previousTarget, const Optional<const Styleable>& newTarget); 126 126 void acceleratedStateDidChange(); 127 void applyPendingAcceleratedActions();128 127 void willChangeRenderer(); 129 128 -
trunk/Source/WebCore/animation/WebAnimationTypes.h
r267188 r271524 56 56 }; 57 57 58 enum class AcceleratedActionApplicationResult { 59 TransformRelatedAnimationCannotBeAccelerated = 1 << 0 60 }; 61 62 enum class UseAcceleratedAction : uint8_t { Yes, No }; 63 58 64 using MarkableDouble = Markable<double, WebAnimationsMarkableDoubleTraits>; 59 65
Note: See TracChangeset
for help on using the changeset viewer.