Changeset 286932 in webkit
- Timestamp:
- Dec 12, 2021, 6:42:35 PM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 6 edited
-
ChangeLog (modified) (1 diff)
-
page/scrolling/ScrollingTreeScrollingNode.cpp (modified) (1 diff)
-
page/scrolling/ScrollingTreeScrollingNode.h (modified) (2 diffs)
-
page/scrolling/ThreadedScrollingTree.cpp (modified) (2 diffs)
-
page/scrolling/ThreadedScrollingTree.h (modified) (1 diff)
-
page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r286931 r286932 1 2021-12-12 Simon Fraser <simon.fraser@apple.com> 2 3 Ensure that the scrolling thread always commits layer position changes to reduce scrolling stutters 4 https://bugs.webkit.org/show_bug.cgi?id=234213 5 6 Reviewed by Tim Horton. 7 8 On a page where CA commits on the main thread take a long time (e.g. because of expensive 9 painting), it's possible that the main thread has updated the scrolling layer position, and 10 then the scrolling thread detects that the commit is taking a long time and attempts to 11 trigger its own commit, but because the layer position property doesn't change, no commit 12 occurs. 13 14 Work around this by setting the layer position to 0,0 and back when we're on the scrolling 15 thread. Only do this if the scroll position changed since the last display refresh to avoid 16 triggering redundant commits. 17 18 Ideally we'd traverse the scrolling tree and do this for every scrolling node, but scrolling 19 trees can get large so for now just apply this to the root node. 20 21 * page/scrolling/ScrollingTreeScrollingNode.cpp: 22 (WebCore::ScrollingTreeScrollingNode::updateScrollPositionAtLastDisplayRefresh): 23 * page/scrolling/ScrollingTreeScrollingNode.h: 24 * page/scrolling/ThreadedScrollingTree.cpp: 25 (WebCore::ThreadedScrollingTree::displayDidRefreshOnScrollingThread): 26 (WebCore::ThreadedScrollingTree::storeScrollPositionsAtLastDisplayRefresh): 27 * page/scrolling/ThreadedScrollingTree.h: 28 * page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm: 29 (WebCore::ScrollingTreeFrameScrollingNodeMac::repositionScrollingLayers): 30 1 31 2021-12-12 Alan Bujtas <zalan@apple.com> 2 32 -
trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp
r286351 r286932 304 304 } 305 305 306 void ScrollingTreeScrollingNode::updateScrollPositionAtLastDisplayRefresh() 307 { 308 m_scrollPositionAtLastDisplayRefresh = m_currentScrollPosition; 309 } 310 306 311 bool ScrollingTreeScrollingNode::scrollPositionAndLayoutViewportMatch(const FloatPoint& position, std::optional<FloatRect>) 307 312 { -
trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h
r286352 r286932 142 142 virtual void repositionScrollingLayers() { } 143 143 virtual void repositionRelatedLayers() { } 144 145 void updateScrollPositionAtLastDisplayRefresh(); 146 std::optional<FloatPoint> scrollPositionAtLastDisplayRefresh() { return m_scrollPositionAtLastDisplayRefresh; }; 144 147 145 148 void applyLayerPositions() override; … … 175 178 std::optional<unsigned> m_currentVerticalSnapPointIndex; 176 179 ScrollableAreaParameters m_scrollableAreaParameters; 180 std::optional<FloatPoint> m_scrollPositionAtLastDisplayRefresh; 177 181 #if ENABLE(SCROLLING_THREAD) 178 182 OptionSet<SynchronousScrollingReason> m_synchronousScrollingReasons; -
trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp
r286905 r286932 501 501 break; 502 502 } 503 504 storeScrollPositionsAtLastDisplayRefresh(); 503 505 } 504 506 … … 526 528 } 527 529 530 void ThreadedScrollingTree::storeScrollPositionsAtLastDisplayRefresh() 531 { 532 // Ideally this would be a tree walk for every scrolling node, but scrolling trees can get big so for now just do this for the root; 533 // ScrollingTreeFrameScrollingNodeMac::repositionScrollingLayers() uses the state to know whether it should force a commit. 534 if (auto* rootNode = this->rootNode()) 535 rootNode->updateScrollPositionAtLastDisplayRefresh(); 536 } 537 528 538 } // namespace WebCore 529 539 -
trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.h
r286905 r286932 108 108 void hasNodeWithAnimatedScrollChanged(bool) final; 109 109 110 void storeScrollPositionsAtLastDisplayRefresh() WTF_REQUIRES_LOCK(m_treeLock); 111 110 112 void serviceScrollAnimations(MonotonicTime) WTF_REQUIRES_LOCK(m_treeLock); 111 113 -
trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm
r286352 r286932 36 36 #import "ScrollingCoordinator.h" 37 37 #import "ScrollingStateTree.h" 38 #import "ScrollingThread.h" 38 39 #import "ScrollingTree.h" 39 40 #import "TileController.h" … … 175 176 { 176 177 BEGIN_BLOCK_OBJC_EXCEPTIONS 178 179 auto* layer = static_cast<CALayer*>(scrolledContentsLayer()); 180 if (ScrollingThread::isCurrentThread()) { 181 // If we're committing on the scrolling thread, it means that ThreadedScrollingTree is in "desynchronized" mode. 182 // The main thread may already have set the same layer position, but here we need to trigger a scrolling thread commit to 183 // ensure that the scroll happens even when the main thread commit is taking a long time. So make sure the layer property changes 184 // when there has been a scroll position change. 185 if (scrollPositionAtLastDisplayRefresh() && scrollPositionAtLastDisplayRefresh().value() != currentScrollPosition()) 186 layer.position = CGPointZero; 187 } 188 177 189 // We use scroll position here because the root content layer is offset to account for scrollOrigin (see FrameView::positionForRootContentLayer). 178 static_cast<CALayer*>(scrolledContentsLayer()).position = -currentScrollPosition();190 layer.position = -currentScrollPosition(); 179 191 END_BLOCK_OBJC_EXCEPTIONS 180 192 }
Note:
See TracChangeset
for help on using the changeset viewer.