Changeset 245818 in webkit
- Timestamp:
- May 28, 2019 11:11:52 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r245802 r245818 1 2019-05-28 Antti Koivisto <antti@apple.com> 2 3 [async scrolling] Fixed positioning inside stacking context overflow scroll is jumpy 4 https://bugs.webkit.org/show_bug.cgi?id=198292 5 6 Reviewed by Darin Adler. 7 8 * scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-2-expected.html: Added. 9 * scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-2.html: Added. 10 * scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-expected.html: Added. 11 * scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll.html: Added. 12 1 13 2019-05-27 Takashi Komori <Takashi.Komori@sony.com> 2 14 -
trunk/Source/WebCore/ChangeLog
r245816 r245818 1 2019-05-28 Antti Koivisto <antti@apple.com> 2 3 [async scrolling] Fixed positioning inside stacking context overflow scroll is jumpy 4 https://bugs.webkit.org/show_bug.cgi?id=198292 5 6 Reviewed by Darin Adler. 7 8 Tests: scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll-2.html 9 scrollingcoordinator/ios/fixed-in-stacking-context-overflow-scroll.html 10 11 We were computing delta from the layout scroll position in ScrollingTree::notifyRelatedNodesAfterScrollPositionChange 12 based on the passed in node only. If any other node had deltas they were not taken into account at all. This would occur 13 frequently since the function is always invoked for the root node after layer tree commit. 14 15 Fix by moving the delta computation (and fetching layoutViewport) to ScrollingTreeFixedNode. 16 17 * page/scrolling/ScrollingTree.cpp: 18 (WebCore::ScrollingTree::applyLayerPositions): 19 20 No need to pass offset and layoutViewport around anymore. 21 22 (WebCore::ScrollingTree::applyLayerPositionsRecursive): 23 (WebCore::ScrollingTree::notifyRelatedNodesAfterScrollPositionChange): 24 25 Remove the offset and layoutViewport computations. 26 27 (WebCore::ScrollingTree::notifyRelatedNodesRecursive): 28 * page/scrolling/ScrollingTree.h: 29 * page/scrolling/ScrollingTreeFrameHostingNode.cpp: 30 (WebCore::ScrollingTreeFrameHostingNode::applyLayerPositions): 31 * page/scrolling/ScrollingTreeFrameHostingNode.h: 32 * page/scrolling/ScrollingTreeNode.cpp: 33 (WebCore::ScrollingTreeNode::relatedNodeScrollPositionDidChange): 34 * page/scrolling/ScrollingTreeNode.h: 35 * page/scrolling/ScrollingTreeScrollingNode.cpp: 36 (WebCore::ScrollingTreeScrollingNode::applyLayerPositions): 37 * page/scrolling/ScrollingTreeScrollingNode.h: 38 * page/scrolling/cocoa/ScrollingTreeFixedNode.h: 39 * page/scrolling/cocoa/ScrollingTreeFixedNode.mm: 40 (WebCore::ScrollingTreeFixedNode::applyLayerPositions): 41 42 Compute them here instead, always taking all overflow scrollers up to the closest frame into account. 43 44 * page/scrolling/cocoa/ScrollingTreePositionedNode.h: 45 * page/scrolling/cocoa/ScrollingTreePositionedNode.mm: 46 (WebCore::ScrollingTreePositionedNode::applyLayerPositions): 47 (WebCore::ScrollingTreePositionedNode::relatedNodeScrollPositionDidChange): 48 * page/scrolling/cocoa/ScrollingTreeStickyNode.h: 49 * page/scrolling/cocoa/ScrollingTreeStickyNode.mm: 50 (WebCore::ScrollingTreeStickyNode::applyLayerPositions): 51 1 52 2019-05-28 Zalan Bujtas <zalan@apple.com> 2 53 -
trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp
r244772 r245818 265 265 LOG(Scrolling, "\nScrollingTree %p applyLayerPositions", this); 266 266 267 applyLayerPositionsRecursive(*m_rootNode , { }, { });267 applyLayerPositionsRecursive(*m_rootNode); 268 268 269 269 LOG(Scrolling, "ScrollingTree %p applyLayerPositions - done\n", this); 270 270 } 271 271 272 void ScrollingTree::applyLayerPositionsRecursive(ScrollingTreeNode& currNode, FloatRect layoutViewport, FloatSize cumulativeDelta) 273 { 274 if (is<ScrollingTreeFrameScrollingNode>(currNode)) { 275 layoutViewport = downcast<ScrollingTreeFrameScrollingNode>(currNode).layoutViewport(); 276 cumulativeDelta = { }; 277 } 278 279 currNode.applyLayerPositions(layoutViewport, cumulativeDelta); 272 void ScrollingTree::applyLayerPositionsRecursive(ScrollingTreeNode& currNode) 273 { 274 currNode.applyLayerPositions(); 280 275 281 276 if (auto children = currNode.children()) { 282 277 for (auto& child : *children) 283 applyLayerPositionsRecursive(*child , layoutViewport, cumulativeDelta);278 applyLayerPositionsRecursive(*child); 284 279 } 285 280 } … … 297 292 Vector<ScrollingNodeID> additionalUpdateRoots; 298 293 299 FloatSize deltaFromLastCommittedScrollPosition; 300 FloatRect currentFrameLayoutViewport; 301 if (is<ScrollingTreeFrameScrollingNode>(changedNode)) 302 currentFrameLayoutViewport = downcast<ScrollingTreeFrameScrollingNode>(changedNode).layoutViewport(); 303 else if (is<ScrollingTreeOverflowScrollingNode>(changedNode)) { 304 deltaFromLastCommittedScrollPosition = changedNode.lastCommittedScrollPosition() - changedNode.currentScrollPosition(); 305 306 if (auto* frameScrollingNode = changedNode.enclosingFrameNodeIncludingSelf()) 307 currentFrameLayoutViewport = frameScrollingNode->layoutViewport(); 308 294 if (is<ScrollingTreeOverflowScrollingNode>(changedNode)) 309 295 additionalUpdateRoots = overflowRelatedNodes().get(changedNode.scrollingNodeID()); 310 } 311 312 notifyRelatedNodesRecursive(changedNode, changedNode, currentFrameLayoutViewport, deltaFromLastCommittedScrollPosition); 296 297 notifyRelatedNodesRecursive(changedNode, changedNode); 313 298 314 299 for (auto positionedNodeID : additionalUpdateRoots) { 315 300 auto* positionedNode = nodeForID(positionedNodeID); 316 301 if (positionedNode) 317 notifyRelatedNodesRecursive(changedNode, *positionedNode , currentFrameLayoutViewport, deltaFromLastCommittedScrollPosition);318 } 319 } 320 321 void ScrollingTree::notifyRelatedNodesRecursive(ScrollingTreeScrollingNode& changedNode, ScrollingTreeNode& currNode , const FloatRect& layoutViewport, FloatSize cumulativeDelta)322 { 323 currNode.relatedNodeScrollPositionDidChange(changedNode , layoutViewport, cumulativeDelta);302 notifyRelatedNodesRecursive(changedNode, *positionedNode); 303 } 304 } 305 306 void ScrollingTree::notifyRelatedNodesRecursive(ScrollingTreeScrollingNode& changedNode, ScrollingTreeNode& currNode) 307 { 308 currNode.relatedNodeScrollPositionDidChange(changedNode); 324 309 325 310 if (!currNode.children()) 326 311 return; 327 312 328 313 for (auto& child : *currNode.children()) { 329 314 // Never need to cross frame boundaries, since scroll layer adjustments are isolated to each document. … … 331 316 continue; 332 317 333 notifyRelatedNodesRecursive(changedNode, *child , layoutViewport, cumulativeDelta);318 notifyRelatedNodesRecursive(changedNode, *child); 334 319 } 335 320 } -
trunk/Source/WebCore/page/scrolling/ScrollingTree.h
r244772 r245818 166 166 void updateTreeFromStateNode(const ScrollingStateNode*, OrphanScrollingNodeMap&, HashSet<ScrollingNodeID>& unvisitedNodes); 167 167 168 void applyLayerPositionsRecursive(ScrollingTreeNode& , FloatRect layoutViewport, FloatSize cumulativeDelta);169 170 void notifyRelatedNodesRecursive(ScrollingTreeScrollingNode& changedNode, ScrollingTreeNode& currNode , const FloatRect& layoutViewport, FloatSize cumulativeDelta);168 void applyLayerPositionsRecursive(ScrollingTreeNode&); 169 170 void notifyRelatedNodesRecursive(ScrollingTreeScrollingNode& changedNode, ScrollingTreeNode& currNode); 171 171 172 172 Lock m_treeMutex; // Protects the scrolling tree. -
trunk/Source/WebCore/page/scrolling/ScrollingTreeFrameHostingNode.cpp
r242687 r245818 58 58 } 59 59 60 void ScrollingTreeFrameHostingNode::applyLayerPositions( const FloatRect&, FloatSize&)60 void ScrollingTreeFrameHostingNode::applyLayerPositions() 61 61 { 62 62 } -
trunk/Source/WebCore/page/scrolling/ScrollingTreeFrameHostingNode.h
r242687 r245818 43 43 44 44 void commitStateBeforeChildren(const ScrollingStateNode&) final; 45 void applyLayerPositions( const FloatRect&, FloatSize&) final;45 void applyLayerPositions() final; 46 46 47 47 const LayoutRect& parentRelativeScrollableRect() const { return m_parentRelativeScrollableRect; } -
trunk/Source/WebCore/page/scrolling/ScrollingTreeNode.cpp
r242687 r245818 78 78 } 79 79 80 void ScrollingTreeNode::relatedNodeScrollPositionDidChange(const ScrollingTreeScrollingNode& , const FloatRect& layoutViewport, FloatSize& cumulativeDelta)80 void ScrollingTreeNode::relatedNodeScrollPositionDidChange(const ScrollingTreeScrollingNode&) 81 81 { 82 applyLayerPositions( layoutViewport, cumulativeDelta);82 applyLayerPositions(); 83 83 } 84 84 -
trunk/Source/WebCore/page/scrolling/ScrollingTreeNode.h
r243416 r245818 85 85 ScrollingTree& scrollingTree() const { return m_scrollingTree; } 86 86 87 WEBCORE_EXPORT virtual void relatedNodeScrollPositionDidChange(const ScrollingTreeScrollingNode& changedNode , const FloatRect& layoutViewport, FloatSize& cumulativeDelta);87 WEBCORE_EXPORT virtual void relatedNodeScrollPositionDidChange(const ScrollingTreeScrollingNode& changedNode); 88 88 89 virtual void applyLayerPositions( const FloatRect& layoutViewport, FloatSize& cumulativeDelta) = 0;89 virtual void applyLayerPositions() = 0; 90 90 91 91 WEBCORE_EXPORT virtual void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const; -
trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp
r245568 r245818 189 189 } 190 190 191 void ScrollingTreeScrollingNode::applyLayerPositions( const FloatRect&, FloatSize&)191 void ScrollingTreeScrollingNode::applyLayerPositions() 192 192 { 193 193 repositionScrollingLayers(); -
trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h
r245066 r245818 108 108 virtual void repositionRelatedLayers() { } 109 109 110 void applyLayerPositions( const FloatRect& layoutViewport, FloatSize& cumulativeDelta) override;110 void applyLayerPositions() override; 111 111 112 112 const FloatSize& reachableContentsSize() const { return m_reachableContentsSize; } -
trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeFixedNode.h
r242687 r245818 48 48 49 49 void commitStateBeforeChildren(const ScrollingStateNode&) override; 50 void applyLayerPositions( const FloatRect&, FloatSize&) override;50 void applyLayerPositions() override; 51 51 52 52 void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const override; -
trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeFixedNode.mm
r242687 r245818 32 32 #import "ScrollingStateFixedNode.h" 33 33 #import "ScrollingTree.h" 34 #import "ScrollingTreeFrameScrollingNode.h" 35 #import "ScrollingTreeOverflowScrollingNode.h" 34 36 #import "WebCoreCALayerExtras.h" 35 37 #import <wtf/text/TextStream.h> … … 64 66 } 65 67 66 void ScrollingTreeFixedNode::applyLayerPositions( const FloatRect& layoutViewport, FloatSize& cumulativeDelta)68 void ScrollingTreeFixedNode::applyLayerPositions() 67 69 { 68 FloatPoint layerPosition = m_constraints.layerPositionForViewportRect(layoutViewport); 70 auto computeLayerPosition = [&] { 71 FloatSize overflowScrollDelta; 72 // FIXME: This code is wrong in complex cases where the fixed element is inside a positioned node as 73 // the scroll container order does not match the scrolling tree ancestor order. 74 for (auto* node = parent(); node; node = node->parent()) { 75 if (is<ScrollingTreeFrameScrollingNode>(*node)) { 76 // Fixed nodes are positioned relative to the containing frame scrolling node. 77 // We bail out after finding one. 78 auto layoutViewport = downcast<ScrollingTreeFrameScrollingNode>(*node).layoutViewport(); 79 return m_constraints.layerPositionForViewportRect(layoutViewport) - overflowScrollDelta; 80 } 69 81 70 LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeFixedNode " << scrollingNodeID() << " relatedNodeScrollPositionDidChange: new viewport " << layoutViewport << " viewportRectAtLastLayout " << m_constraints.viewportRectAtLastLayout() << " last layer pos " << m_constraints.layerPositionAtLastLayout() << " new offset from top " << (layoutViewport.y() - layerPosition.y())); 82 if (is<ScrollingTreeOverflowScrollingNode>(*node)) { 83 // To keep the layer still during async scrolling we adjust by how much the position has changed since layout. 84 auto& overflowNode = downcast<ScrollingTreeOverflowScrollingNode>(*node); 85 auto localDelta = overflowNode.lastCommittedScrollPosition() - overflowNode.currentScrollPosition(); 86 overflowScrollDelta += localDelta; 87 } 88 } 89 ASSERT_NOT_REACHED(); 90 return FloatPoint(); 91 }; 71 92 72 layerPosition -= cumulativeDelta; 93 auto layerPosition = computeLayerPosition(); 94 95 LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeFixedNode " << scrollingNodeID() << " relatedNodeScrollPositionDidChange: viewportRectAtLastLayout " << m_constraints.viewportRectAtLastLayout() << " last layer pos " << m_constraints.layerPositionAtLastLayout() << " layerPosition " << layerPosition); 73 96 74 97 [m_layer _web_setLayerTopLeftPosition:layerPosition - m_constraints.alignmentOffset()]; 75 cumulativeDelta += layerPosition - m_constraints.layerPositionAtLastLayout();76 98 } 77 99 -
trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.h
r243380 r245818 51 51 52 52 void commitStateBeforeChildren(const ScrollingStateNode&) override; 53 void relatedNodeScrollPositionDidChange(const ScrollingTreeScrollingNode& changedNode , const FloatRect& layoutViewport, FloatSize& cumulativeDelta) override;53 void relatedNodeScrollPositionDidChange(const ScrollingTreeScrollingNode& changedNode) override; 54 54 55 void applyLayerPositions( const FloatRect& layoutViewport, FloatSize& cumulativeDelta) override;55 void applyLayerPositions() override; 56 56 57 57 WEBCORE_EXPORT void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const override; -
trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.mm
r243380 r245818 77 77 } 78 78 79 void ScrollingTreePositionedNode::applyLayerPositions( const FloatRect&, FloatSize& cumulativeDelta)79 void ScrollingTreePositionedNode::applyLayerPositions() 80 80 { 81 // Note that we ignore cumulativeDelta because it will contain the delta for ancestor scrollers,82 // but not non-ancestor ones, so it's simpler to just recompute from the scrollers we know about here.83 81 FloatSize scrollOffsetSinceLastCommit; 84 82 for (auto nodeID : m_relatedOverflowScrollingNodes) { … … 101 99 102 100 [m_layer _web_setLayerTopLeftPosition:layerPosition - m_constraints.alignmentOffset()]; 103 104 // FIXME: Should our scroller deltas propagate to descendants?105 cumulativeDelta = layerPosition - m_constraints.layerPositionAtLastLayout();106 101 } 107 102 108 void ScrollingTreePositionedNode::relatedNodeScrollPositionDidChange(const ScrollingTreeScrollingNode& changedNode , const FloatRect& layoutViewport, FloatSize& cumulativeDelta)103 void ScrollingTreePositionedNode::relatedNodeScrollPositionDidChange(const ScrollingTreeScrollingNode& changedNode) 109 104 { 110 105 if (!m_relatedOverflowScrollingNodes.contains(changedNode.scrollingNodeID())) 111 106 return; 112 107 113 applyLayerPositions( layoutViewport, cumulativeDelta);108 applyLayerPositions(); 114 109 } 115 110 -
trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNode.h
r242913 r245818 46 46 47 47 void commitStateBeforeChildren(const ScrollingStateNode&) override; 48 void applyLayerPositions( const FloatRect& layoutViewport, FloatSize& cumulativeDelta) override;48 void applyLayerPositions() override; 49 49 50 50 void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const override; -
trunk/Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNode.mm
r244630 r245818 66 66 } 67 67 68 void ScrollingTreeStickyNode::applyLayerPositions( const FloatRect& layoutViewport, FloatSize& cumulativeDelta)68 void ScrollingTreeStickyNode::applyLayerPositions() 69 69 { 70 70 FloatRect constrainingRect; … … 74 74 constrainingRect = FloatRect(downcast<ScrollingTreeOverflowScrollingNode>(*enclosingScrollingNode).currentScrollPosition(), m_constraints.constrainingRectAtLastLayout().size()); 75 75 else if (is<ScrollingTreeFrameScrollingNode>(enclosingScrollingNode)) 76 constrainingRect = layoutViewport;76 constrainingRect = downcast<ScrollingTreeFrameScrollingNode>(enclosingScrollingNode)->layoutViewport(); 77 77 else 78 78 return; 79 79 80 LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeStickyNode " << scrollingNodeID() << " relatedNodeScrollPositionDidChange: new viewport " << layoutViewport << " constrainingRectAtLastLayout " << m_constraints.constrainingRectAtLastLayout() << " last layer pos " << m_constraints.layerPositionAtLastLayout());80 FloatPoint layerPosition = m_constraints.layerPositionForConstrainingRect(constrainingRect) - m_constraints.alignmentOffset(); 81 81 82 FloatPoint layerPosition = m_constraints.layerPositionForConstrainingRect(constrainingRect) - m_constraints.alignmentOffset(); 82 LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeStickyNode " << scrollingNodeID() << " constrainingRect " << constrainingRect << " constrainingRectAtLastLayout " << m_constraints.constrainingRectAtLastLayout() << " last layer pos " << m_constraints.layerPositionAtLastLayout() << " layerPosition " << layerPosition); 83 83 84 [m_layer _web_setLayerTopLeftPosition:layerPosition]; 84 85 cumulativeDelta += layerPosition - m_constraints.layerPositionAtLastLayout();86 85 } 87 86 -
trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFixedNode.cpp
r242687 r245818 55 55 } 56 56 57 void ScrollingTreeFixedNode::applyLayerPositions( const FloatRect&, FloatSize&)57 void ScrollingTreeFixedNode::applyLayerPositions() 58 58 { 59 59 } -
trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFixedNode.h
r242687 r245818 43 43 44 44 void commitStateBeforeChildren(const ScrollingStateNode&) override; 45 void applyLayerPositions( const FloatRect& layoutViewport, FloatSize& cumulativeDelta) override;45 void applyLayerPositions() override; 46 46 }; 47 47 -
trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeStickyNode.cpp
r242687 r245818 55 55 } 56 56 57 void ScrollingTreeStickyNode::applyLayerPositions( const FloatRect&, FloatSize&)57 void ScrollingTreeStickyNode::applyLayerPositions() 58 58 { 59 59 } -
trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeStickyNode.h
r242687 r245818 43 43 44 44 void commitStateBeforeChildren(const ScrollingStateNode&) override; 45 void applyLayerPositions( const FloatRect& layoutViewport, FloatSize& cumulativeDelta) override;45 void applyLayerPositions() override; 46 46 47 47 };
Note: See TracChangeset
for help on using the changeset viewer.