Changeset 230578 in webkit
- Timestamp:
- Apr 12, 2018 9:34:42 AM (6 years ago)
- Location:
- trunk
- Files:
-
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r230574 r230578 1 2018-04-12 Antoine Quint <graouts@apple.com> 2 3 [Web Animations] Ensure elements overlapping with elements animating also get composited 4 https://bugs.webkit.org/show_bug.cgi?id=184539 5 6 Reviewed by Jon Lee. 7 8 Opt more tests in the CSS Animations and CSS Transitions as Web Animations runtime flag since they now pass. 9 10 * compositing/backing/backface-visibility-flip.html: 11 * compositing/layer-creation/overlap-animation-clipping.html: 12 * compositing/layer-creation/overlap-animation-container.html: 13 * compositing/layer-creation/overlap-animation.html: 14 * compositing/layer-creation/translate-animation-overlap.html: 15 1 16 2018-04-11 Antoine Quint <graouts@apple.com> 2 17 -
trunk/LayoutTests/compositing/backing/backface-visibility-flip.html
r172183 r230578 1 <!DOCTYPE html> 1 <!DOCTYPE html><!-- webkit-test-runner [ enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations=true ] --> 2 2 3 3 <html> -
trunk/LayoutTests/compositing/layer-creation/overlap-animation-clipping.html
r139493 r230578 1 <!DOCTYPE html> 1 <!DOCTYPE html><!-- webkit-test-runner [ enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations=true ] --> 2 2 3 3 <html> -
trunk/LayoutTests/compositing/layer-creation/overlap-animation-container.html
r139493 r230578 1 <!DOCTYPE html> 1 <!DOCTYPE html><!-- webkit-test-runner [ enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations=true ] --> 2 2 3 3 <html> -
trunk/LayoutTests/compositing/layer-creation/overlap-animation.html
r180441 r230578 1 <!DOCTYPE html> 1 <!DOCTYPE html><!-- webkit-test-runner [ enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations=true ] --> 2 2 3 3 <html> -
trunk/LayoutTests/compositing/layer-creation/translate-animation-overlap.html
r181515 r230578 1 <!DOCTYPE html> 1 <!DOCTYPE html><!-- webkit-test-runner [ enableCSSAnimationsAndCSSTransitionsBackedByWebAnimations=true ] --> 2 2 3 3 <html> -
trunk/Source/WebCore/ChangeLog
r230574 r230578 1 2018-04-12 Antoine Quint <graouts@apple.com> 2 3 [Web Animations] Ensure elements overlapping with elements animating also get composited 4 https://bugs.webkit.org/show_bug.cgi?id=184539 5 6 Reviewed by Jon Lee. 7 8 A number of compositing tests failed because we didn't call into the Web Animations engine while various calls 9 on RenderLayer and RenderLayerBacking were made. We bring the functionality over from CSSAnimationController to 10 DocumentTimeline and KeyframeAnimation to KeyframeEffectReadOnly. 11 12 * animation/AnimationTimeline.cpp: 13 (WebCore::AnimationTimeline::animationsForElement const): Update this method's signature to be const since it 14 should be callable by other const method. 15 (WebCore::AnimationTimeline::animationsForElement): Deleted. 16 * animation/AnimationTimeline.h: 17 * animation/DocumentTimeline.cpp: 18 (WebCore::DocumentTimeline::computeExtentOfAnimation const): Adapt this method from CSSAnimationController. 19 (WebCore::DocumentTimeline::isRunningAnimationOnRenderer const): Adapt this method from CSSAnimationController. 20 (WebCore::DocumentTimeline::isRunningAcceleratedAnimationOnRenderer const): Adapt this method from CSSAnimationController. 21 * animation/DocumentTimeline.h: 22 * animation/KeyframeEffectReadOnly.cpp: 23 (WebCore::KeyframeEffectReadOnly::computeExtentOfTransformAnimation const): Bring this method over from KeyframeAnimation. 24 (WebCore::containsRotation): Bring this method over from KeyframeAnimation. 25 (WebCore::KeyframeEffectReadOnly::computeTransformedExtentViaTransformList const): Bring this method over from KeyframeAnimation. 26 (WebCore::KeyframeEffectReadOnly::computeTransformedExtentViaMatrix const): Bring this method over from KeyframeAnimation. 27 * animation/KeyframeEffectReadOnly.h: 28 (WebCore::KeyframeEffectReadOnly::animatedProperties const): DocumentTimeline::computeExtentOfAnimation() needs to get a list 29 of all animated properties to see if a transform is animated, so we now expose such a list. 30 * rendering/RenderLayer.cpp: 31 (WebCore::RenderLayer::currentTransform const): Update this method to call into DocumentTimeline if the CSS Animations 32 and CSS Transitions as Web Animations flag is on. 33 (WebCore::RenderLayer::calculateClipRects const): Update this method to call into DocumentTimeline if the CSS Animations 34 and CSS Transitions as Web Animations flag is on. 35 * rendering/RenderLayerBacking.cpp: 36 (WebCore::RenderLayerBacking::updateGeometry): Update this method to call into DocumentTimeline if the CSS Animations 37 and CSS Transitions as Web Animations flag is on. 38 * rendering/RenderLayerCompositor.cpp: 39 (WebCore::RenderLayerCompositor::isRunningTransformAnimation const): Update this method to call into DocumentTimeline 40 if the CSS Animations and CSS Transitions as Web Animations flag is on. 41 * rendering/RenderObject.h: 42 (WebCore::RenderObject::documentTimeline const): 43 1 44 2018-04-11 Antoine Quint <graouts@apple.com> 2 45 -
trunk/Source/WebCore/animation/AnimationTimeline.cpp
r229890 r230578 116 116 } 117 117 118 Vector<RefPtr<WebAnimation>> AnimationTimeline::animationsForElement(Element& element) 118 Vector<RefPtr<WebAnimation>> AnimationTimeline::animationsForElement(Element& element) const 119 119 { 120 120 Vector<RefPtr<WebAnimation>> animations; -
trunk/Source/WebCore/animation/AnimationTimeline.h
r229890 r230578 59 59 60 60 const ListHashSet<RefPtr<WebAnimation>>& animations() const { return m_animations; } 61 Vector<RefPtr<WebAnimation>> animationsForElement(Element&) ;61 Vector<RefPtr<WebAnimation>> animationsForElement(Element&) const; 62 62 void cancelAnimationsForElement(Element&); 63 63 void animationWasAddedToElement(WebAnimation&, Element&); -
trunk/Source/WebCore/animation/DocumentTimeline.cpp
r230574 r230578 191 191 } 192 192 193 bool DocumentTimeline::computeExtentOfAnimation(RenderElement& renderer, LayoutRect& bounds) const 194 { 195 if (!renderer.element()) 196 return true; 197 198 KeyframeEffectReadOnly* matchingEffect; 199 for (const auto& animation : animationsForElement(*renderer.element())) { 200 auto* effect = animation->effect(); 201 if (is<KeyframeEffectReadOnly>(effect)) { 202 auto* keyframeEffect = downcast<KeyframeEffectReadOnly>(effect); 203 if (keyframeEffect->animatedProperties().contains(CSSPropertyTransform)) 204 matchingEffect = downcast<KeyframeEffectReadOnly>(effect); 205 } 206 } 207 208 if (matchingEffect) 209 return matchingEffect->computeExtentOfTransformAnimation(bounds); 210 211 return true; 212 } 213 214 bool DocumentTimeline::isRunningAnimationOnRenderer(RenderElement& renderer, CSSPropertyID property) const 215 { 216 if (!renderer.element()) 217 return false; 218 219 for (const auto& animation : animationsForElement(*renderer.element())) { 220 auto playState = animation->playState(); 221 if (playState != WebAnimation::PlayState::Running && playState != WebAnimation::PlayState::Paused) 222 continue; 223 auto* effect = animation->effect(); 224 if (is<KeyframeEffectReadOnly>(effect) && downcast<KeyframeEffectReadOnly>(effect)->animatedProperties().contains(property)) 225 return true; 226 } 227 228 return false; 229 } 230 231 bool DocumentTimeline::isRunningAcceleratedAnimationOnRenderer(RenderElement& renderer, CSSPropertyID property) const 232 { 233 if (!renderer.element()) 234 return false; 235 236 for (const auto& animation : animationsForElement(*renderer.element())) { 237 auto playState = animation->playState(); 238 if (playState != WebAnimation::PlayState::Running && playState != WebAnimation::PlayState::Paused) 239 continue; 240 auto* effect = animation->effect(); 241 if (is<KeyframeEffectReadOnly>(effect)) { 242 auto* keyframeEffect = downcast<KeyframeEffectReadOnly>(effect); 243 if (keyframeEffect->isRunningAccelerated() && keyframeEffect->animatedProperties().contains(property)) 244 return true; 245 } 246 } 247 248 return false; 249 } 250 193 251 std::unique_ptr<RenderStyle> DocumentTimeline::animatedStyleForRenderer(RenderElement& renderer) 194 252 { -
trunk/Source/WebCore/animation/DocumentTimeline.h
r230574 r230578 58 58 void windowScreenDidChange(PlatformDisplayID); 59 59 60 // If possible, compute the visual extent of any transform animation on the given renderer 61 // using the given rect, returning the result in the rect. Return false if there is some 62 // transform animation but we were unable to cheaply compute its effect on the extent. 63 bool computeExtentOfAnimation(RenderElement&, LayoutRect&) const; 60 64 std::unique_ptr<RenderStyle> animatedStyleForRenderer(RenderElement& renderer); 65 bool isRunningAnimationOnRenderer(RenderElement&, CSSPropertyID) const; 66 bool isRunningAcceleratedAnimationOnRenderer(RenderElement&, CSSPropertyID) const; 61 67 void animationAcceleratedRunningStateDidChange(WebAnimation&); 62 68 void applyPendingAcceleratedAnimations(); -
trunk/Source/WebCore/animation/KeyframeEffectReadOnly.cpp
r230574 r230578 38 38 #include "Element.h" 39 39 #include "FontCascade.h" 40 #include "GeometryUtilities.h" 40 41 #include "JSCompositeOperation.h" 41 42 #include "JSKeyframeEffectReadOnly.h" … … 1258 1259 } 1259 1260 1261 bool KeyframeEffectReadOnly::computeExtentOfTransformAnimation(LayoutRect& bounds) const 1262 { 1263 ASSERT(m_blendingKeyframes.containsProperty(CSSPropertyTransform)); 1264 1265 if (!is<RenderBox>(renderer())) 1266 return true; // Non-boxes don't get transformed; 1267 1268 RenderBox& box = downcast<RenderBox>(*renderer()); 1269 FloatRect rendererBox = snapRectToDevicePixels(box.borderBoxRect(), box.document().deviceScaleFactor()); 1270 1271 FloatRect cumulativeBounds = bounds; 1272 1273 for (const auto& keyframe : m_blendingKeyframes.keyframes()) { 1274 // FIXME: maybe for declarative animations we always say it's true for the first and last keyframe. 1275 if (!keyframe.containsProperty(CSSPropertyTransform)) 1276 continue; 1277 1278 LayoutRect keyframeBounds = bounds; 1279 1280 bool canCompute; 1281 if (transformFunctionListsMatch()) 1282 canCompute = computeTransformedExtentViaTransformList(rendererBox, *keyframe.style(), keyframeBounds); 1283 else 1284 canCompute = computeTransformedExtentViaMatrix(rendererBox, *keyframe.style(), keyframeBounds); 1285 1286 if (!canCompute) 1287 return false; 1288 1289 cumulativeBounds.unite(keyframeBounds); 1290 } 1291 1292 bounds = LayoutRect(cumulativeBounds); 1293 return true; 1294 } 1295 1296 static bool containsRotation(const Vector<RefPtr<TransformOperation>>& operations) 1297 { 1298 for (const auto& operation : operations) { 1299 if (operation->type() == TransformOperation::ROTATE) 1300 return true; 1301 } 1302 return false; 1303 } 1304 1305 bool KeyframeEffectReadOnly::computeTransformedExtentViaTransformList(const FloatRect& rendererBox, const RenderStyle& style, LayoutRect& bounds) const 1306 { 1307 FloatRect floatBounds = bounds; 1308 FloatPoint transformOrigin; 1309 1310 bool applyTransformOrigin = containsRotation(style.transform().operations()) || style.transform().affectedByTransformOrigin(); 1311 if (applyTransformOrigin) { 1312 transformOrigin.setX(rendererBox.x() + floatValueForLength(style.transformOriginX(), rendererBox.width())); 1313 transformOrigin.setY(rendererBox.y() + floatValueForLength(style.transformOriginY(), rendererBox.height())); 1314 // Ignore transformOriginZ because we'll bail if we encounter any 3D transforms. 1315 1316 floatBounds.moveBy(-transformOrigin); 1317 } 1318 1319 for (const auto& operation : style.transform().operations()) { 1320 if (operation->type() == TransformOperation::ROTATE) { 1321 // For now, just treat this as a full rotation. This could take angle into account to reduce inflation. 1322 floatBounds = boundsOfRotatingRect(floatBounds); 1323 } else { 1324 TransformationMatrix transform; 1325 operation->apply(transform, rendererBox.size()); 1326 if (!transform.isAffine()) 1327 return false; 1328 1329 if (operation->type() == TransformOperation::MATRIX || operation->type() == TransformOperation::MATRIX_3D) { 1330 TransformationMatrix::Decomposed2Type toDecomp; 1331 transform.decompose2(toDecomp); 1332 // Any rotation prevents us from using a simple start/end rect union. 1333 if (toDecomp.angle) 1334 return false; 1335 } 1336 1337 floatBounds = transform.mapRect(floatBounds); 1338 } 1339 } 1340 1341 if (applyTransformOrigin) 1342 floatBounds.moveBy(transformOrigin); 1343 1344 bounds = LayoutRect(floatBounds); 1345 return true; 1346 } 1347 1348 bool KeyframeEffectReadOnly::computeTransformedExtentViaMatrix(const FloatRect& rendererBox, const RenderStyle& style, LayoutRect& bounds) const 1349 { 1350 TransformationMatrix transform; 1351 style.applyTransform(transform, rendererBox, RenderStyle::IncludeTransformOrigin); 1352 if (!transform.isAffine()) 1353 return false; 1354 1355 TransformationMatrix::Decomposed2Type fromDecomp; 1356 transform.decompose2(fromDecomp); 1357 // Any rotation prevents us from using a simple start/end rect union. 1358 if (fromDecomp.angle) 1359 return false; 1360 1361 bounds = LayoutRect(transform.mapRect(bounds)); 1362 return true; 1363 } 1364 1260 1365 } // namespace WebCore -
trunk/Source/WebCore/animation/KeyframeEffectReadOnly.h
r230574 r230578 117 117 bool stylesWouldYieldNewCSSTransitionsBlendingKeyframes(const RenderStyle& oldStyle, const RenderStyle& newStyle) const; 118 118 bool hasBlendingKeyframes() const { return m_blendingKeyframes.size(); } 119 const HashSet<CSSPropertyID>& animatedProperties() const { return m_blendingKeyframes.properties(); } 120 121 bool computeExtentOfTransformAnimation(LayoutRect&) const; 122 bool computeTransformedExtentViaTransformList(const FloatRect&, const RenderStyle&, LayoutRect&) const; 123 bool computeTransformedExtentViaMatrix(const FloatRect&, const RenderStyle&, LayoutRect&) const; 119 124 120 125 protected: -
trunk/Source/WebCore/rendering/RenderLayer.cpp
r230274 r230578 54 54 #include "DocumentEventQueue.h" 55 55 #include "DocumentMarkerController.h" 56 #include "DocumentTimeline.h" 56 57 #include "Element.h" 57 58 #include "EventHandler.h" … … 108 109 #include "RenderTreeAsText.h" 109 110 #include "RenderView.h" 111 #include "RuntimeEnabledFeatures.h" 110 112 #include "SVGNames.h" 111 113 #include "ScaleTransformOperation.h" … … 1000 1002 RenderBox* box = renderBox(); 1001 1003 1002 if (renderer().animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyTransform, AnimationBase::Running | AnimationBase::Paused)) { 1003 TransformationMatrix currTransform; 1004 FloatRect pixelSnappedBorderRect = snapRectToDevicePixels(box->borderBoxRect(), box->document().deviceScaleFactor()); 1005 std::unique_ptr<RenderStyle> style = renderer().animation().animatedStyleForRenderer(renderer()); 1006 style->applyTransform(currTransform, pixelSnappedBorderRect, applyOrigin); 1007 makeMatrixRenderable(currTransform, canRender3DTransforms()); 1008 return currTransform; 1009 } 1004 if (RuntimeEnabledFeatures::sharedFeatures().cssAnimationsAndCSSTransitionsBackedByWebAnimationsEnabled()) { 1005 if (auto* timeline = renderer().documentTimeline()) { 1006 if (timeline->isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyTransform)) { 1007 TransformationMatrix currTransform; 1008 FloatRect pixelSnappedBorderRect = snapRectToDevicePixels(box->borderBoxRect(), box->document().deviceScaleFactor()); 1009 std::unique_ptr<RenderStyle> style = timeline->animatedStyleForRenderer(renderer()); 1010 style->applyTransform(currTransform, pixelSnappedBorderRect, applyOrigin); 1011 makeMatrixRenderable(currTransform, canRender3DTransforms()); 1012 return currTransform; 1013 } 1014 } 1015 } else { 1016 if (renderer().animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyTransform, AnimationBase::Running | AnimationBase::Paused)) { 1017 TransformationMatrix currTransform; 1018 FloatRect pixelSnappedBorderRect = snapRectToDevicePixels(box->borderBoxRect(), box->document().deviceScaleFactor()); 1019 std::unique_ptr<RenderStyle> style = renderer().animation().animatedStyleForRenderer(renderer()); 1020 style->applyTransform(currTransform, pixelSnappedBorderRect, applyOrigin); 1021 makeMatrixRenderable(currTransform, canRender3DTransforms()); 1022 return currTransform; 1023 } 1024 } 1025 1010 1026 1011 1027 // m_transform includes transform-origin, so we need to recompute the transform here. … … 5776 5792 5777 5793 LayoutRect animatedBounds = bounds; 5778 if (renderer().animation().computeExtentOfAnimation(renderer(), animatedBounds)) { 5779 bounds = animatedBounds; 5780 return true; 5794 if (RuntimeEnabledFeatures::sharedFeatures().cssAnimationsAndCSSTransitionsBackedByWebAnimationsEnabled()) { 5795 if (auto* timeline = renderer().documentTimeline()) { 5796 if (timeline->computeExtentOfAnimation(renderer(), animatedBounds)) { 5797 bounds = animatedBounds; 5798 return true; 5799 } 5800 } 5801 } else { 5802 if (renderer().animation().computeExtentOfAnimation(renderer(), animatedBounds)) { 5803 bounds = animatedBounds; 5804 return true; 5805 } 5781 5806 } 5782 5807 -
trunk/Source/WebCore/rendering/RenderLayerBacking.cpp
r230574 r230578 34 34 #include "CachedImage.h" 35 35 #include "Chrome.h" 36 #include "DocumentTimeline.h" 36 37 #include "FilterEffectRenderer.h" 37 38 #include "Frame.h" … … 62 63 #include "RenderVideo.h" 63 64 #include "RenderView.h" 65 #include "RuntimeEnabledFeatures.h" 64 66 #include "ScrollingCoordinator.h" 65 67 #include "Settings.h" … … 949 951 const RenderStyle& style = renderer().style(); 950 952 951 bool isRunningAcceleratedTransformAnimation = renderer().animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyTransform, AnimationBase::Running | AnimationBase::Paused); 952 bool isRunningAcceleratedOpacityAnimation = renderer().animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyOpacity, AnimationBase::Running | AnimationBase::Paused); 953 bool isRunningAcceleratedTransformAnimation = false; 954 bool isRunningAcceleratedOpacityAnimation = false; 955 if (RuntimeEnabledFeatures::sharedFeatures().cssAnimationsAndCSSTransitionsBackedByWebAnimationsEnabled()) { 956 if (auto* timeline = renderer().documentTimeline()) { 957 isRunningAcceleratedTransformAnimation = timeline->isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyTransform); 958 isRunningAcceleratedOpacityAnimation = timeline->isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyOpacity); 959 } 960 } else { 961 isRunningAcceleratedTransformAnimation = renderer().animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyTransform, AnimationBase::Running | AnimationBase::Paused); 962 isRunningAcceleratedOpacityAnimation = renderer().animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyOpacity, AnimationBase::Running | AnimationBase::Paused); 963 } 953 964 954 965 // Set transform property, if it is not animating. We have to do this here because the transform -
trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp
r230574 r230578 2720 2720 return false; 2721 2721 2722 if (RuntimeEnabledFeatures::sharedFeatures().cssAnimationsAndCSSTransitionsBackedByWebAnimationsEnabled()) { 2723 if (auto* element = renderer.element()) { 2724 if (auto* timeline = element->document().existingTimeline()) 2725 return timeline->isRunningAnimationOnRenderer(renderer, CSSPropertyTransform); 2726 } 2727 return false; 2728 } 2722 2729 return renderer.animation().isRunningAnimationOnRenderer(renderer, CSSPropertyTransform, AnimationBase::Running | AnimationBase::Paused); 2723 2730 } -
trunk/Source/WebCore/rendering/RenderObject.h
r228908 r230578 47 47 class Cursor; 48 48 class Document; 49 class DocumentTimeline; 49 50 class HitTestLocation; 50 51 class HitTestRequest; … … 755 756 756 757 CSSAnimationController& animation() const; 758 DocumentTimeline* documentTimeline() const; 757 759 758 760 // Map points and quads through elements, potentially via 3d transforms. You should never need to call these directly; use … … 1005 1007 } 1006 1008 1009 inline DocumentTimeline* RenderObject::documentTimeline() const 1010 { 1011 return document().existingTimeline(); 1012 } 1013 1007 1014 inline bool RenderObject::renderTreeBeingDestroyed() const 1008 1015 {
Note: See TracChangeset
for help on using the changeset viewer.