Changeset 286975 in webkit
- Timestamp:
- Dec 13, 2021, 12:56:57 PM (5 years ago)
- Location:
- branches/safari-612-branch/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
-
branches/safari-612-branch/Source/WebCore/ChangeLog
r286974 r286975 1 2021-12-13 Alan Coon <alancoon@apple.com> 2 3 Cherry-pick r286932. rdar://problem/86385697 4 5 Ensure that the scrolling thread always commits layer position changes to reduce scrolling stutters 6 https://bugs.webkit.org/show_bug.cgi?id=234213 7 8 Reviewed by Tim Horton. 9 10 On a page where CA commits on the main thread take a long time (e.g. because of expensive 11 painting), it's possible that the main thread has updated the scrolling layer position, and 12 then the scrolling thread detects that the commit is taking a long time and attempts to 13 trigger its own commit, but because the layer position property doesn't change, no commit 14 occurs. 15 16 Work around this by setting the layer position to 0,0 and back when we're on the scrolling 17 thread. Only do this if the scroll position changed since the last display refresh to avoid 18 triggering redundant commits. 19 20 Ideally we'd traverse the scrolling tree and do this for every scrolling node, but scrolling 21 trees can get large so for now just apply this to the root node. 22 23 * page/scrolling/ScrollingTreeScrollingNode.cpp: 24 (WebCore::ScrollingTreeScrollingNode::updateScrollPositionAtLastDisplayRefresh): 25 * page/scrolling/ScrollingTreeScrollingNode.h: 26 * page/scrolling/ThreadedScrollingTree.cpp: 27 (WebCore::ThreadedScrollingTree::displayDidRefreshOnScrollingThread): 28 (WebCore::ThreadedScrollingTree::storeScrollPositionsAtLastDisplayRefresh): 29 * page/scrolling/ThreadedScrollingTree.h: 30 * page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm: 31 (WebCore::ScrollingTreeFrameScrollingNodeMac::repositionScrollingLayers): 32 33 git-svn-id: https://svn.webkit.org/repository/webkit/trunk@286932 268f45cc-cd09-0410-ab3c-d52691b4dbfc 34 35 2021-12-12 Simon Fraser <simon.fraser@apple.com> 36 37 Ensure that the scrolling thread always commits layer position changes to reduce scrolling stutters 38 https://bugs.webkit.org/show_bug.cgi?id=234213 39 40 Reviewed by Tim Horton. 41 42 On a page where CA commits on the main thread take a long time (e.g. because of expensive 43 painting), it's possible that the main thread has updated the scrolling layer position, and 44 then the scrolling thread detects that the commit is taking a long time and attempts to 45 trigger its own commit, but because the layer position property doesn't change, no commit 46 occurs. 47 48 Work around this by setting the layer position to 0,0 and back when we're on the scrolling 49 thread. Only do this if the scroll position changed since the last display refresh to avoid 50 triggering redundant commits. 51 52 Ideally we'd traverse the scrolling tree and do this for every scrolling node, but scrolling 53 trees can get large so for now just apply this to the root node. 54 55 * page/scrolling/ScrollingTreeScrollingNode.cpp: 56 (WebCore::ScrollingTreeScrollingNode::updateScrollPositionAtLastDisplayRefresh): 57 * page/scrolling/ScrollingTreeScrollingNode.h: 58 * page/scrolling/ThreadedScrollingTree.cpp: 59 (WebCore::ThreadedScrollingTree::displayDidRefreshOnScrollingThread): 60 (WebCore::ThreadedScrollingTree::storeScrollPositionsAtLastDisplayRefresh): 61 * page/scrolling/ThreadedScrollingTree.h: 62 * page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm: 63 (WebCore::ScrollingTreeFrameScrollingNodeMac::repositionScrollingLayers): 64 1 65 2021-12-13 Alan Coon <alancoon@apple.com> 2 66 -
branches/safari-612-branch/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp
r286692 r286975 274 274 } 275 275 276 void ScrollingTreeScrollingNode::updateScrollPositionAtLastDisplayRefresh() 277 { 278 m_scrollPositionAtLastDisplayRefresh = m_currentScrollPosition; 279 } 280 276 281 bool ScrollingTreeScrollingNode::scrollPositionAndLayoutViewportMatch(const FloatPoint& position, std::optional<FloatRect>) 277 282 { -
branches/safari-612-branch/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h
r286692 r286975 129 129 virtual void repositionScrollingLayers() { } 130 130 virtual void repositionRelatedLayers() { } 131 132 void updateScrollPositionAtLastDisplayRefresh(); 133 std::optional<FloatPoint> scrollPositionAtLastDisplayRefresh() { return m_scrollPositionAtLastDisplayRefresh; }; 131 134 132 135 void applyLayerPositions() override; … … 162 165 std::optional<unsigned> m_currentVerticalSnapPointIndex; 163 166 ScrollableAreaParameters m_scrollableAreaParameters; 167 std::optional<FloatPoint> m_scrollPositionAtLastDisplayRefresh; 164 168 #if ENABLE(SCROLLING_THREAD) 165 169 OptionSet<SynchronousScrollingReason> m_synchronousScrollingReasons; -
branches/safari-612-branch/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp
r286688 r286975 407 407 break; 408 408 } 409 410 storeScrollPositionsAtLastDisplayRefresh(); 409 411 } 410 412 … … 429 431 } 430 432 433 void ThreadedScrollingTree::storeScrollPositionsAtLastDisplayRefresh() 434 { 435 // 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; 436 // ScrollingTreeFrameScrollingNodeMac::repositionScrollingLayers() uses the state to know whether it should force a commit. 437 if (auto* rootNode = this->rootNode()) 438 rootNode->updateScrollPositionAtLastDisplayRefresh(); 439 } 440 431 441 } // namespace WebCore 432 442 -
branches/safari-612-branch/Source/WebCore/page/scrolling/ThreadedScrollingTree.h
r286687 r286975 95 95 void delayedRenderingUpdateDetectionTimerFired(); 96 96 97 void storeScrollPositionsAtLastDisplayRefresh() WTF_REQUIRES_LOCK(m_treeLock); 98 97 99 Seconds frameDuration(); 98 100 Seconds maxAllowableRenderingUpdateDurationForSynchronization(); -
branches/safari-612-branch/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm
r279218 r286975 36 36 #import "ScrollingCoordinator.h" 37 37 #import "ScrollingStateTree.h" 38 #import "ScrollingThread.h" 38 39 #import "ScrollingTree.h" 39 40 #import "TileController.h" … … 167 168 { 168 169 BEGIN_BLOCK_OBJC_EXCEPTIONS 170 171 auto* layer = static_cast<CALayer*>(scrolledContentsLayer()); 172 if (ScrollingThread::isCurrentThread()) { 173 // If we're committing on the scrolling thread, it means that ThreadedScrollingTree is in "desynchronized" mode. 174 // The main thread may already have set the same layer position, but here we need to trigger a scrolling thread commit to 175 // ensure that the scroll happens even when the main thread commit is taking a long time. So make sure the layer property changes 176 // when there has been a scroll position change. 177 if (scrollPositionAtLastDisplayRefresh() && scrollPositionAtLastDisplayRefresh().value() != currentScrollPosition()) 178 layer.position = CGPointZero; 179 } 180 169 181 // We use scroll position here because the root content layer is offset to account for scrollOrigin (see FrameView::positionForRootContentLayer). 170 static_cast<CALayer*>(scrolledContentsLayer()).position = -currentScrollPosition();182 layer.position = -currentScrollPosition(); 171 183 END_BLOCK_OBJC_EXCEPTIONS 172 184 }
Note:
See TracChangeset
for help on using the changeset viewer.