Changeset 243926 in webkit
- Timestamp:
- Apr 4, 2019 10:18:17 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r243917 r243926 1 2019-04-04 Simon Fraser <simon.fraser@apple.com> 2 3 [iOS WK2] REGRESSION (r242687): Programmatic scroll of overflow scroll results in bad rendering 4 https://bugs.webkit.org/show_bug.cgi?id=195584 5 6 Reviewed by Zalan Bujtas. 7 8 Testing of programmatic scrolls in frames is prevented by webkit.org/b/196635. 9 10 * scrollingcoordinator/ios/programmatic-overflow-scroll-expected.html: Added. 11 * scrollingcoordinator/ios/programmatic-overflow-scroll.html: Added. 12 * scrollingcoordinator/ios/programmatic-page-scroll-expected.html: Added. 13 * scrollingcoordinator/ios/programmatic-page-scroll.html: Added. 14 1 15 2019-04-04 Shawn Roberts <sroberts@apple.com> 2 16 -
trunk/Source/WebCore/ChangeLog
r243924 r243926 1 2019-04-04 Simon Fraser <simon.fraser@apple.com> 2 3 [iOS WK2] REGRESSION (r242687): Programmatic scroll of overflow scroll results in bad rendering 4 https://bugs.webkit.org/show_bug.cgi?id=195584 5 6 Reviewed by Zalan Bujtas. 7 8 Push data to the scrolling tree about whether an overflow:scroll scroll was programmatic, by having 9 RenderLayer::scrollToOffset() call into AsyncScrollingCoordinator::requestScrollPositionUpdate(), 10 just as we do for frames. 11 12 AsyncScrollingCoordinator::requestScrollPositionUpdate() is generalized to take any ScrollableArea. 13 14 Fix an assumption in the ScrollingTree that we only care about programmatic scrolls on the root node. 15 ScrollingTree::commitTreeState() no longer sets isHandlingProgrammaticScroll; instead, 16 callers of ScrollingTreeScrollingNode::scrollTo() pass a ScrollType. Commit functions pass 17 ScrollType::Programmatic when handling RequestedScrollPosition changes as necessary. 18 19 Programmatic scrolls need to get to the scrolling tree in the UI process so that we update 20 the tree's notion of scroll position, and trigger actual UIScrollView scrolls (layers may have 21 already been put in the right locations, but the UI process needs to know that a scroll happened). 22 However, we need to prevent notifications from programmatic scrolls getting back to the 23 web process, because this causes jumpiness. This is done via an early return in 24 RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll(). 25 26 Tests: scrollingcoordinator/ios/programmatic-overflow-scroll.html 27 scrollingcoordinator/ios/programmatic-page-scroll.html 28 29 * page/scrolling/AsyncScrollingCoordinator.cpp: 30 (WebCore::AsyncScrollingCoordinator::requestScrollPositionUpdate): 31 * page/scrolling/AsyncScrollingCoordinator.h: 32 * page/scrolling/ScrollingCoordinator.h: 33 (WebCore::ScrollingCoordinator::requestScrollPositionUpdate): 34 * page/scrolling/ScrollingTree.cpp: 35 (WebCore::ScrollingTree::commitTreeState): 36 (WebCore::ScrollingTree::isHandlingProgrammaticScroll): Deleted. 37 * page/scrolling/ScrollingTree.h: 38 (WebCore::ScrollingTree::isHandlingProgrammaticScroll const): 39 (WebCore::ScrollingTree::setIsHandlingProgrammaticScroll): 40 * page/scrolling/ScrollingTreeScrollingNode.cpp: 41 (WebCore::ScrollingTreeScrollingNode::scrollBy): 42 (WebCore::ScrollingTreeScrollingNode::scrollTo): 43 * page/scrolling/ScrollingTreeScrollingNode.h: 44 * page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm: 45 (WebCore::ScrollingTreeFrameScrollingNodeMac::commitStateAfterChildren): 46 * rendering/RenderLayer.cpp: 47 (WebCore::RenderLayer::scrollToOffset): 48 (WebCore::RenderLayer::scrollingNodeID const): 49 * rendering/RenderLayer.h: 50 * rendering/RenderMarquee.cpp: 51 (WebCore::RenderMarquee::timerFired): 52 1 53 2019-04-04 Yusuke Suzuki <ysuzuki@apple.com> 2 54 -
trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp
r243919 r243926 205 205 } 206 206 207 bool AsyncScrollingCoordinator::requestScrollPositionUpdate( FrameView& frameView, const IntPoint& scrollPosition)207 bool AsyncScrollingCoordinator::requestScrollPositionUpdate(ScrollableArea& scrollableArea, const IntPoint& scrollPosition) 208 208 { 209 209 ASSERT(isMainThread()); 210 210 ASSERT(m_page); 211 211 212 if (!coordinatesScrollingForFrameView(frameView)) 212 auto scrollingNodeID = scrollableArea.scrollingNodeID(); 213 if (!scrollingNodeID) 213 214 return false; 214 215 215 bool inPageCache = frameView.frame().document()->pageCacheState() != Document::NotInPageCache; 216 bool inProgrammaticScroll = frameView.currentScrollType() == ScrollType::Programmatic; 216 auto* frameView = frameViewForScrollingNode(scrollingNodeID); 217 if (!frameView) 218 return false; 219 220 if (!coordinatesScrollingForFrameView(*frameView)) 221 return false; 222 223 bool inPageCache = frameView->frame().document()->pageCacheState() != Document::NotInPageCache; 224 bool inProgrammaticScroll = scrollableArea.currentScrollType() == ScrollType::Programmatic; 217 225 if (inProgrammaticScroll || inPageCache) 218 updateScrollPositionAfterAsyncScroll( frameView.scrollingNodeID(), scrollPosition, { }, ScrollType::Programmatic, ScrollingLayerPositionAction::Set);226 updateScrollPositionAfterAsyncScroll(scrollingNodeID, scrollPosition, { }, ScrollType::Programmatic, ScrollingLayerPositionAction::Set); 219 227 220 228 // If this frame view's document is being put into the page cache, we don't want to update our … … 223 231 return true; 224 232 225 auto* stateNode = downcast<ScrollingStateScrollingNode>(m_scrollingStateTree->stateNodeForID( frameView.scrollingNodeID()));233 auto* stateNode = downcast<ScrollingStateScrollingNode>(m_scrollingStateTree->stateNodeForID(scrollingNodeID)); 226 234 if (!stateNode) 227 235 return false; -
trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h
r243855 r243926 96 96 WEBCORE_EXPORT void frameViewEventTrackingRegionsChanged(FrameView&) override; 97 97 98 WEBCORE_EXPORT bool requestScrollPositionUpdate( FrameView&, const IntPoint&) override;98 WEBCORE_EXPORT bool requestScrollPositionUpdate(ScrollableArea&, const IntPoint&) override; 99 99 100 100 WEBCORE_EXPORT void applyScrollingTreeLayerPositions() override; -
trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h
r243855 r243926 115 115 // These virtual functions are currently unique to the threaded scrolling architecture. 116 116 virtual void commitTreeStateIfNeeded() { } 117 virtual bool requestScrollPositionUpdate( FrameView&, const IntPoint&) { return false; }117 virtual bool requestScrollPositionUpdate(ScrollableArea&, const IntPoint&) { return false; } 118 118 virtual ScrollingEventResult handleWheelEvent(FrameView&, const PlatformWheelEvent&) { return ScrollingEventResult::DidNotHandleEvent; } 119 119 -
trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp
r243607 r243926 167 167 } 168 168 169 bool scrollRequestIsProgammatic = rootNode ? rootNode->requestedScrollPositionRepresentsProgrammaticScroll() : false;170 SetForScope<bool> changeHandlingProgrammaticScroll(m_isHandlingProgrammaticScroll, scrollRequestIsProgammatic);171 172 169 // unvisitedNodes starts with all nodes in the map; we remove nodes as we visit them. At the end, it's the unvisited nodes. 173 170 // We can't use orphanNodes for this, because orphanNodes won't contain descendants of removed nodes. … … 403 400 m_swipeState.rubberBandsAtTop = canRubberBandAtTop; 404 401 m_swipeState.rubberBandsAtBottom = canRubberBandAtBottom; 405 }406 407 bool ScrollingTree::isHandlingProgrammaticScroll()408 {409 return m_isHandlingProgrammaticScroll;410 402 } 411 403 -
trunk/Source/WebCore/page/scrolling/ScrollingTree.h
r243607 r243926 119 119 WEBCORE_EXPORT void setCanRubberBandState(bool canRubberBandAtLeft, bool canRubberBandAtRight, bool canRubberBandAtTop, bool canRubberBandAtBottom); 120 120 121 bool isHandlingProgrammaticScroll(); 121 bool isHandlingProgrammaticScroll() const { return m_isHandlingProgrammaticScroll; } 122 void setIsHandlingProgrammaticScroll(bool isHandlingProgrammaticScroll) { m_isHandlingProgrammaticScroll = isHandlingProgrammaticScroll; } 122 123 123 124 void setScrollPinningBehavior(ScrollPinningBehavior); … … 205 206 206 207 unsigned m_fixedOrStickyNodeCount { 0 }; 208 bool m_isHandlingProgrammaticScroll { false }; 207 209 bool m_scrollingPerformanceLoggingEnabled { false }; 208 bool m_isHandlingProgrammaticScroll { false };209 210 bool m_asyncFrameOrOverflowScrollingEnabled { false }; 210 211 }; -
trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp
r243309 r243926 153 153 void ScrollingTreeScrollingNode::scrollBy(const FloatSize& delta, ScrollPositionClamp clamp) 154 154 { 155 scrollTo(currentScrollPosition() + delta, clamp);156 } 157 158 void ScrollingTreeScrollingNode::scrollTo(const FloatPoint& position, Scroll PositionClamp clamp)155 scrollTo(currentScrollPosition() + delta, ScrollType::User, clamp); 156 } 157 158 void ScrollingTreeScrollingNode::scrollTo(const FloatPoint& position, ScrollType scrollType, ScrollPositionClamp clamp) 159 159 { 160 160 if (position == m_currentScrollPosition) 161 161 return; 162 162 163 scrollingTree().setIsHandlingProgrammaticScroll(scrollType == ScrollType::Programmatic); 164 163 165 m_currentScrollPosition = adjustedScrollPosition(position, clamp); 164 166 … … 167 169 updateViewportForCurrentScrollPosition(); 168 170 currentScrollPositionChanged(); 171 172 scrollingTree().setIsHandlingProgrammaticScroll(false); 169 173 } 170 174 -
trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h
r243416 r243926 58 58 59 59 // These are imperative; they adjust the scrolling layers. 60 void scrollTo(const FloatPoint&, Scroll PositionClamp = ScrollPositionClamp::ToContentEdges);60 void scrollTo(const FloatPoint&, ScrollType = ScrollType::User, ScrollPositionClamp = ScrollPositionClamp::ToContentEdges); 61 61 void scrollBy(const FloatSize&, ScrollPositionClamp = ScrollPositionClamp::ToContentEdges); 62 62 -
trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm
r243550 r243926 138 138 139 139 // Update the scroll position after child nodes have been updated, because they need to have updated their constraints before any scrolling happens. 140 if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition)) 141 scrollTo(scrollingStateNode.requestedScrollPosition()); 140 if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition)) { 141 auto scrollType = scrollingStateNode.requestedScrollPositionRepresentsProgrammaticScroll() ? ScrollType::Programmatic : ScrollType::User; 142 scrollTo(scrollingStateNode.requestedScrollPosition(), scrollType); 143 } 142 144 143 145 if (isRootNode() -
trunk/Source/WebCore/rendering/RenderLayer.cpp
r243919 r243926 2347 2347 setCurrentScrollType(scrollType); 2348 2348 2349 scrollToOffsetWithoutAnimation(newScrollOffset, clamping); 2349 bool handled = false; 2350 #if ENABLE(ASYNC_SCROLLING) 2351 if (ScrollingCoordinator* scrollingCoordinator = page().scrollingCoordinator()) 2352 handled = scrollingCoordinator->requestScrollPositionUpdate(*this, scrollPositionFromOffset(scrollOffset)); 2353 #endif 2354 2355 if (!handled) 2356 scrollToOffsetWithoutAnimation(newScrollOffset, clamping); 2350 2357 2351 2358 setCurrentScrollType(previousScrollType); … … 2803 2810 2804 2811 return 0; 2812 } 2813 2814 ScrollingNodeID RenderLayer::scrollingNodeID() const 2815 { 2816 if (!isComposited()) 2817 return 0; 2818 2819 return backing()->scrollingNodeIDForRole(ScrollCoordinationRole::Scrolling); 2805 2820 } 2806 2821 -
trunk/Source/WebCore/rendering/RenderLayer.h
r243919 r243926 421 421 422 422 // These are only used by marquee. 423 void scrollToXOffset(int x , ScrollClamping clamping = ScrollClamping::Clamped) { scrollToOffset(ScrollOffset(x, scrollOffset().y()), ScrollType::Programmatic, clamping); }424 void scrollToYOffset(int y , ScrollClamping clamping = ScrollClamping::Clamped) { scrollToOffset(ScrollOffset(scrollOffset().x(), y), ScrollType::Programmatic, clamping); }423 void scrollToXOffset(int x) { scrollToOffset(ScrollOffset(x, scrollOffset().y()), ScrollType::Programmatic, ScrollClamping::Unclamped); } 424 void scrollToYOffset(int y) { scrollToOffset(ScrollOffset(scrollOffset().x(), y), ScrollType::Programmatic, ScrollClamping::Unclamped); } 425 425 426 426 void setPostLayoutScrollPosition(Optional<ScrollPosition>); … … 1051 1051 int scrollSize(ScrollbarOrientation) const override; 1052 1052 void setScrollOffset(const ScrollOffset&) override; 1053 ScrollingNodeID scrollingNodeID() const override; 1053 1054 1054 1055 IntRect visibleContentRectInternal(VisibleContentRectIncludesScrollbars, VisibleContentRectBehavior) const override; -
trunk/Source/WebCore/rendering/RenderMarquee.cpp
r243919 r243926 248 248 m_reset = false; 249 249 if (isHorizontal()) 250 m_layer->scrollToXOffset(m_start , ScrollClamping::Unclamped);250 m_layer->scrollToXOffset(m_start); 251 251 else 252 m_layer->scrollToYOffset(m_start , ScrollClamping::Unclamped);252 m_layer->scrollToYOffset(m_start); 253 253 return; 254 254 } … … 290 290 291 291 if (isHorizontal()) 292 m_layer->scrollToXOffset(newPos , ScrollClamping::Unclamped);292 m_layer->scrollToXOffset(newPos); 293 293 else 294 m_layer->scrollToYOffset(newPos , ScrollClamping::Unclamped);294 m_layer->scrollToYOffset(newPos); 295 295 } 296 296 -
trunk/Source/WebKit/ChangeLog
r243916 r243926 1 2019-04-04 Simon Fraser <simon.fraser@apple.com> 2 3 [iOS WK2] REGRESSION (r242687): Programmatic scroll of overflow scroll results in bad rendering 4 https://bugs.webkit.org/show_bug.cgi?id=195584 5 6 Reviewed by Zalan Bujtas. 7 8 Push data to the scrolling tree about whether an overflow:scroll scroll was programmatic, by having 9 RenderLayer::scrollToOffset() call into AsyncScrollingCoordinator::requestScrollPositionUpdate(), 10 just as we do for frames. 11 12 AsyncScrollingCoordinator::requestScrollPositionUpdate() is generalized to take any ScrollableArea. 13 14 Fix an assumption in the ScrollingTree that we only care about programmatic scrolls on the root node. 15 ScrollingTree::commitTreeState() no longer sets isHandlingProgrammaticScroll; instead, 16 callers of ScrollingTreeScrollingNode::scrollTo() pass a ScrollType. Commit functions pass 17 ScrollType::Programmatic when handling RequestedScrollPosition changes as necessary. 18 19 Programmatic scrolls need to get to the scrolling tree in the UI process so that we update 20 the tree's notion of scroll position, and trigger actual UIScrollView scrolls (layers may have 21 already been put in the right locations, but the UI process needs to know that a scroll happened). 22 However, we need to prevent notifications from programmatic scrolls getting back to the 23 web process, because this causes jumpiness. This is done via an early return in 24 RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll(). 25 26 * UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp: 27 (WebKit::RemoteScrollingCoordinatorProxy::scrollingTreeNodeDidScroll): 28 * UIProcess/RemoteLayerTree/ios/ScrollingTreeFrameScrollingNodeRemoteIOS.mm: 29 (WebKit::ScrollingTreeFrameScrollingNodeRemoteIOS::commitStateAfterChildren): Subframe nodes have 30 a delegate, and that will take care of the requestedScrollPosition update. 31 * UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.h: 32 * UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.mm: 33 (WebKit::ScrollingTreeOverflowScrollingNodeIOS::commitStateAfterChildren): 34 * UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm: 35 (WebKit::ScrollingTreeScrollingNodeDelegateIOS::commitStateAfterChildren): 36 1 37 2019-04-04 Ryan Haddad <ryanhaddad@apple.com> 2 38 -
trunk/Source/WebKit/UIProcess/RemoteLayerTree/RemoteScrollingCoordinatorProxy.cpp
r243316 r243926 217 217 m_webPageProxy.scrollingNodeScrollViewDidScroll(); 218 218 #endif 219 220 if (m_scrollingTree->isHandlingProgrammaticScroll()) 221 return; 222 219 223 m_webPageProxy.send(Messages::RemoteScrollingCoordinator::ScrollPositionChangedForNode(scrolledNodeID, newScrollPosition, scrollingLayerPositionAction == ScrollingLayerPositionAction::Sync)); 220 224 } -
trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeFrameScrollingNodeRemoteIOS.mm
r242356 r243926 83 83 const auto& scrollingStateNode = downcast<ScrollingStateFrameScrollingNode>(stateNode); 84 84 85 if (m_scrollingNodeDelegate) { 86 m_scrollingNodeDelegate->commitStateAfterChildren(scrollingStateNode); 87 return; 88 } 89 85 90 // Update the scroll position after child nodes have been updated, because they need to have updated their constraints before any scrolling happens. 86 if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition)) 87 scrollTo(scrollingStateNode.requestedScrollPosition()); 88 89 if (m_scrollingNodeDelegate) 90 m_scrollingNodeDelegate->commitStateAfterChildren(downcast<ScrollingStateScrollingNode>(stateNode)); 91 if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition)) { 92 auto scrollType = scrollingStateNode.requestedScrollPositionRepresentsProgrammaticScroll() ? ScrollType::Programmatic : ScrollType::User; 93 scrollTo(scrollingStateNode.requestedScrollPosition(), scrollType); 94 } 91 95 } 92 96 -
trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.h
r242132 r243926 47 47 void repositionScrollingLayers() override; 48 48 49 // The delegate is non-null for subframes. 49 50 std::unique_ptr<ScrollingTreeScrollingNodeDelegateIOS> m_scrollingNodeDelegate; 50 51 }; -
trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.mm
r242132 r243926 64 64 { 65 65 ScrollingTreeOverflowScrollingNode::commitStateAfterChildren(stateNode); 66 m_scrollingNodeDelegate->commitStateAfterChildren(downcast<ScrollingStateScrollingNode>(stateNode)); 66 67 const auto& scrollingStateNode = downcast<ScrollingStateScrollingNode>(stateNode); 68 m_scrollingNodeDelegate->commitStateAfterChildren(scrollingStateNode); 67 69 } 68 70 -
trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeScrollingNodeDelegateIOS.mm
r243416 r243926 226 226 { 227 227 SetForScope<bool> updatingChange(m_updatingFromStateNode, true); 228 228 229 if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::ScrollContainerLayer) 229 230 || scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::TotalContentsSize) … … 288 289 END_BLOCK_OBJC_EXCEPTIONS 289 290 } 291 292 if (scrollingStateNode.hasChangedProperty(ScrollingStateScrollingNode::RequestedScrollPosition)) { 293 auto scrollType = scrollingStateNode.requestedScrollPositionRepresentsProgrammaticScroll() ? ScrollType::Programmatic : ScrollType::User; 294 scrollingNode().scrollTo(scrollingStateNode.requestedScrollPosition(), scrollType); 295 } 290 296 } 291 297
Note: See TracChangeset
for help on using the changeset viewer.