Diff
Modified: trunk/Source/WebCore/ChangeLog (283982 => 283983)
--- trunk/Source/WebCore/ChangeLog 2021-10-12 15:47:13 UTC (rev 283982)
+++ trunk/Source/WebCore/ChangeLog 2021-10-12 15:48:46 UTC (rev 283983)
@@ -1,3 +1,55 @@
+2021-10-12 Simon Fraser <[email protected]>
+
+ Have the ScrollingTree track nodes with animated scrolls
+ https://bugs.webkit.org/show_bug.cgi?id=231554
+
+ Reviewed by Tim Horton.
+
+ A future patch will require that a ScrollingCoordinator knows when there are any nodes with
+ active scroll animations running.
+
+ Create the plumbing for this via ScrollingTree::setAnimatedScrollInProgressForNode() which
+ updates a HashSet data member.
+
+ ScrollingTreeScrollingNode subclasses which can run animations via their delegate, i.e.
+ ScrollingTree{Overflow, Frame}ScrollingNode{Mac, Nicosia, iOS} now call
+ willStartAnimatedScroll() if the animation started. The existing
+ ScrollingTreeScrollingNode::didStopAnimatedScroll() is the book-end.
+
+ ThreadedScrollingTree changes are a hint of things to come; we will need to tell a future
+ ScrollingCoordinator subclass when scroll animations start/stop, and displayDidRefresh() and
+ willStartRenderingUpdate() code need to do the same stuff when animations are running as
+ they do when handling wheel events.
+
+ * page/scrolling/AsyncScrollingCoordinator.h:
+ (WebCore::AsyncScrollingCoordinator::hasNodeWithAnimatedScrollChanged):
+ * page/scrolling/ScrollingTree.cpp:
+ (WebCore::ScrollingTree::isAnimatedScrollInProgressForNode):
+ (WebCore::ScrollingTree::setAnimatedScrollInProgressForNode):
+ (WebCore::ScrollingTree::hasNodeWithActiveAnimatedScroll):
+ * page/scrolling/ScrollingTree.h:
+ (WebCore::ScrollingTree::hasNodeWithAnimatedScrollChanged):
+ * page/scrolling/ScrollingTreeScrollingNode.cpp:
+ (WebCore::ScrollingTreeScrollingNode::didStopAnimatedScroll):
+ (WebCore::ScrollingTreeScrollingNode::willStartAnimatedScroll):
+ * page/scrolling/ScrollingTreeScrollingNode.h:
+ * page/scrolling/ThreadedScrollingTree.cpp:
+ (WebCore::ThreadedScrollingTree::scrollingThreadIsActive):
+ (WebCore::ThreadedScrollingTree::willStartRenderingUpdate):
+ (WebCore::ThreadedScrollingTree::hasNodeWithAnimatedScrollChanged):
+ (WebCore::ThreadedScrollingTree::displayDidRefresh):
+ * page/scrolling/ThreadedScrollingTree.h:
+ * page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm:
+ (WebCore::ScrollingTreeFrameScrollingNodeMac::startAnimatedScrollToPosition):
+ (WebCore::ScrollingTreeFrameScrollingNodeMac::currentScrollPositionChanged):
+ * page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm:
+ (WebCore::ScrollingTreeOverflowScrollingNodeMac::startAnimatedScrollToPosition):
+ * page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm:
+ * page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp:
+ (WebCore::ScrollingTreeFrameScrollingNodeNicosia::startAnimatedScrollToPosition):
+ * page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.cpp:
+ (WebCore::ScrollingTreeOverflowScrollingNodeNicosia::startAnimatedScrollToPosition):
+
2021-10-12 Alex Christensen <[email protected]>
Begin migration from WTF::Variant to std::variant
Modified: trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h (283982 => 283983)
--- trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h 2021-10-12 15:47:13 UTC (rev 283982)
+++ trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h 2021-10-12 15:48:46 UTC (rev 283983)
@@ -71,6 +71,8 @@
bool scrollAnimatorEnabled() const;
+ virtual void hasNodeWithAnimatedScrollChanged(bool) { };
+
protected:
WEBCORE_EXPORT AsyncScrollingCoordinator(Page*);
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp (283982 => 283983)
--- trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp 2021-10-12 15:47:13 UTC (rev 283982)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp 2021-10-12 15:48:46 UTC (rev 283983)
@@ -583,6 +583,40 @@
m_treeState.nodesWithActiveScrollSnap.remove(nodeID);
}
+bool ScrollingTree::isAnimatedScrollInProgressForNode(ScrollingNodeID nodeID)
+{
+ if (!nodeID)
+ return false;
+
+ Locker locker { m_treeStateLock };
+ return m_treeState.nodesWithActiveAnimatedScrolls.contains(nodeID);
+}
+
+void ScrollingTree::setAnimatedScrollInProgressForNode(ScrollingNodeID nodeID, bool isAnimatedScrollInProgress)
+{
+ if (!nodeID)
+ return;
+
+ Locker locker { m_treeStateLock };
+
+ bool hadAnyAnimatedScrollingNodes = !m_treeState.nodesWithActiveAnimatedScrolls.isEmpty();
+
+ if (isAnimatedScrollInProgress)
+ m_treeState.nodesWithActiveAnimatedScrolls.add(nodeID);
+ else
+ m_treeState.nodesWithActiveAnimatedScrolls.remove(nodeID);
+
+ bool hasAnyAnimatedScrollingNodes = !m_treeState.nodesWithActiveAnimatedScrolls.isEmpty();
+ if (hasAnyAnimatedScrollingNodes != hadAnyAnimatedScrollingNodes)
+ hasNodeWithAnimatedScrollChanged(hasAnyAnimatedScrollingNodes);
+}
+
+bool ScrollingTree::hasNodeWithActiveAnimatedScroll()
+{
+ Locker locker { m_treeStateLock };
+ return !m_treeState.nodesWithActiveAnimatedScrolls.isEmpty();
+}
+
void ScrollingTree::setMainFramePinnedState(RectEdges<bool> edgePinningState)
{
Locker locker { m_swipeStateLock };
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.h (283982 => 283983)
--- trunk/Source/WebCore/page/scrolling/ScrollingTree.h 2021-10-12 15:47:13 UTC (rev 283982)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.h 2021-10-12 15:48:46 UTC (rev 283983)
@@ -113,6 +113,9 @@
bool isScrollSnapInProgressForNode(ScrollingNodeID);
void setNodeScrollSnapInProgress(ScrollingNodeID, bool);
+ bool isAnimatedScrollInProgressForNode(ScrollingNodeID);
+ void setAnimatedScrollInProgressForNode(ScrollingNodeID, bool);
+
virtual void invalidate() { }
WEBCORE_EXPORT void commitTreeState(std::unique_ptr<ScrollingStateTree>&&);
@@ -222,7 +225,6 @@
void windowScreenDidChange(PlatformDisplayID, std::optional<FramesPerSecond> nominalFramesPerSecond);
PlatformDisplayID displayID();
- bool hasProcessedWheelEventsRecently();
WEBCORE_EXPORT void willProcessWheelEvent();
void addPendingScrollUpdate(ScrollUpdate&&);
@@ -241,7 +243,12 @@
void applyLayerPositionsInternal() WTF_REQUIRES_LOCK(m_treeLock);
void removeAllNodes() WTF_REQUIRES_LOCK(m_treeLock);
+
+ virtual void hasNodeWithAnimatedScrollChanged(bool /* hasNodeWithAnimatedScroll */) { }
+ bool hasProcessedWheelEventsRecently();
+ bool hasNodeWithActiveAnimatedScroll();
+
Lock m_treeLock; // Protects the scrolling tree.
private:
@@ -262,7 +269,7 @@
OptionSet<WheelEventProcessingSteps> computeWheelProcessingSteps(const PlatformWheelEvent&) WTF_REQUIRES_LOCK(m_treeStateLock);
virtual void receivedWheelEvent(const PlatformWheelEvent&) { }
-
+
RefPtr<ScrollingTreeFrameScrollingNode> m_rootNode;
using ScrollingTreeNodeMap = HashMap<ScrollingNodeID, RefPtr<ScrollingTreeNode>>;
@@ -285,6 +292,7 @@
HashSet<ScrollingNodeID> nodesWithActiveRubberBanding;
HashSet<ScrollingNodeID> nodesWithActiveScrollSnap;
HashSet<ScrollingNodeID> nodesWithActiveUserScrolls;
+ HashSet<ScrollingNodeID> nodesWithActiveAnimatedScrolls;
};
Lock m_treeStateLock;
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp (283982 => 283983)
--- trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp 2021-10-12 15:47:13 UTC (rev 283982)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp 2021-10-12 15:48:46 UTC (rev 283983)
@@ -229,6 +229,7 @@
{
LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeScrollingNode " << scrollingNodeID() << " didStopAnimatedScroll");
scrollingTree().scrollingTreeNodeDidStopAnimatedScroll(*this);
+ scrollingTree().setAnimatedScrollInProgressForNode(scrollingNodeID(), false);
}
void ScrollingTreeScrollingNode::handleScrollPositionRequest(const RequestedScrollData& requestedScrollData)
@@ -259,6 +260,11 @@
return scrollPosition;
}
+void ScrollingTreeScrollingNode::willStartAnimatedScroll()
+{
+ scrollingTree().setAnimatedScrollInProgressForNode(scrollingNodeID(), true);
+}
+
void ScrollingTreeScrollingNode::scrollBy(const FloatSize& delta, ScrollClamping clamp)
{
scrollTo(currentScrollPosition() + delta, ScrollType::User, clamp);
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h (283982 => 283983)
--- trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h 2021-10-12 15:47:13 UTC (rev 283982)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h 2021-10-12 15:48:46 UTC (rev 283983)
@@ -128,6 +128,9 @@
virtual bool startAnimatedScrollToPosition(FloatPoint) { return false; }
virtual void stopAnimatedScroll() { }
+ void willStartAnimatedScroll();
+ void didStopAnimatedScroll();
+
virtual void currentScrollPositionChanged(ScrollType, ScrollingLayerPositionAction = ScrollingLayerPositionAction::Sync);
virtual void updateViewportForCurrentScrollPosition(std::optional<FloatRect> = { }) { }
virtual bool scrollPositionAndLayoutViewportMatch(const FloatPoint& position, std::optional<FloatRect> overrideLayoutViewport);
@@ -137,8 +140,6 @@
void applyLayerPositions() override;
- void didStopAnimatedScroll();
-
const FloatSize& reachableContentsSize() const { return m_reachableContentsSize; }
bool isLatchedNode() const;
Modified: trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp (283982 => 283983)
--- trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp 2021-10-12 15:47:13 UTC (rev 283982)
+++ trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp 2021-10-12 15:48:46 UTC (rev 283983)
@@ -328,11 +328,18 @@
}
#endif
+bool ThreadedScrollingTree::scrollingThreadIsActive()
+{
+ return hasProcessedWheelEventsRecently() || hasNodeWithActiveAnimatedScroll();
+}
+
void ThreadedScrollingTree::willStartRenderingUpdate()
{
ASSERT(isMainThread());
- if (!hasProcessedWheelEventsRecently())
+ LOG_WITH_STREAM(ScrollAnimations, stream << "ThreadedScrollingTree::willStartRenderingUpdate - scrollingThreadIsActive " << scrollingThreadIsActive());
+
+ if (!scrollingThreadIsActive())
return;
tracePoint(ScrollingThreadRenderUpdateSyncStart);
@@ -358,6 +365,13 @@
return allowableFrameFraction * frameDuration;
}
+void ThreadedScrollingTree::hasNodeWithAnimatedScrollChanged(bool hasNodeWithAnimatedScroll)
+{
+ RunLoop::main().dispatch([scrollingCoordinator = m_scrollingCoordinator, hasNodeWithAnimatedScroll] {
+ scrollingCoordinator->hasNodeWithAnimatedScrollChanged(hasNodeWithAnimatedScroll);
+ });
+}
+
// This code allows the main thread about half a frame to complete its rendering udpate. If the main thread
// is responsive (i.e. managing to render every frame), then we expect to get a didCompleteRenderingUpdate()
// within 8ms of willStartRenderingUpdate(). We time this via m_stateCondition, which blocks the scrolling
@@ -451,16 +465,16 @@
void ThreadedScrollingTree::displayDidRefresh(PlatformDisplayID displayID)
{
- bool hasProcessedWheelEventsRecently = this->hasProcessedWheelEventsRecently();
+ bool scrollingThreadIsActive = this->scrollingThreadIsActive();
// We're on the EventDispatcher thread or in the ThreadedCompositor thread here.
- tracePoint(ScrollingTreeDisplayDidRefresh, displayID, hasProcessedWheelEventsRecently);
+ tracePoint(ScrollingTreeDisplayDidRefresh, displayID, scrollingThreadIsActive);
if (displayID != this->displayID())
return;
#if !PLATFORM(WPE) && !PLATFORM(GTK)
- if (!hasProcessedWheelEventsRecently)
+ if (!scrollingThreadIsActive)
return;
#endif
Modified: trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.h (283982 => 283983)
--- trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.h 2021-10-12 15:47:13 UTC (rev 283982)
+++ trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.h 2021-10-12 15:48:46 UTC (rev 283983)
@@ -101,7 +101,11 @@
void scheduleDelayedRenderingUpdateDetectionTimer(Seconds) WTF_REQUIRES_LOCK(m_treeLock);
void delayedRenderingUpdateDetectionTimerFired();
+ void hasNodeWithAnimatedScrollChanged(bool) final;
+
Seconds maxAllowableRenderingUpdateDurationForSynchronization();
+
+ bool scrollingThreadIsActive();
enum class SynchronizationState : uint8_t {
Idle,
Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm (283982 => 283983)
--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm 2021-10-12 15:47:13 UTC (rev 283982)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm 2021-10-12 15:48:46 UTC (rev 283983)
@@ -127,7 +127,10 @@
bool ScrollingTreeFrameScrollingNodeMac::startAnimatedScrollToPosition(FloatPoint destinationPosition)
{
- return m_delegate.startAnimatedScrollToPosition(destinationPosition);
+ bool started = m_delegate.startAnimatedScrollToPosition(destinationPosition);
+ if (started)
+ willStartAnimatedScroll();
+ return started;
}
void ScrollingTreeFrameScrollingNodeMac::stopAnimatedScroll()
@@ -148,7 +151,7 @@
void ScrollingTreeFrameScrollingNodeMac::currentScrollPositionChanged(ScrollType scrollType, ScrollingLayerPositionAction action)
{
- LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeFrameScrollingNodeMac " << scrollingNodeID() << " currentScrollPositionChanged to " << currentScrollPosition() << " min: " << minimumScrollPosition() << " max: " << maximumScrollPosition() << " sync: " << hasSynchronousScrollingReasons());
+ LOG_WITH_STREAM(Scrolling, stream << "ScrollingTreeFrameScrollingNodeMac " << scrollingNodeID() << " currentScrollPositionChanged to " << currentScrollPosition() << " min: " << minimumScrollPosition() << " max: " << maximumScrollPosition() << " sync: " << hasSynchronousScrollingReasons() << " is animating: " << scrollingTree().isAnimatedScrollInProgressForNode(scrollingNodeID()));
m_delegate.currentScrollPositionChanged();
Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm (283982 => 283983)
--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm 2021-10-12 15:47:13 UTC (rev 283982)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeOverflowScrollingNodeMac.mm 2021-10-12 15:48:46 UTC (rev 283983)
@@ -76,7 +76,10 @@
bool ScrollingTreeOverflowScrollingNodeMac::startAnimatedScrollToPosition(FloatPoint destinationPosition)
{
- return m_delegate.startAnimatedScrollToPosition(destinationPosition);
+ bool started = m_delegate.startAnimatedScrollToPosition(destinationPosition);
+ if (started)
+ willStartAnimatedScroll();
+ return started;
}
void ScrollingTreeOverflowScrollingNodeMac::stopAnimatedScroll()
Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm (283982 => 283983)
--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm 2021-10-12 15:47:13 UTC (rev 283982)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm 2021-10-12 15:48:46 UTC (rev 283983)
@@ -402,7 +402,7 @@
scrollingTree().deferWheelEventTestCompletionForReason(identifier, reason);
}
-
+
void ScrollingTreeScrollingNodeDelegateMac::removeWheelEventTestCompletionDeferralForReason(WheelEventTestMonitor::ScrollableAreaIdentifier identifier, WheelEventTestMonitor::DeferReason reason) const
{
if (!scrollingTree().isMonitoringWheelEvents())
Modified: trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp (283982 => 283983)
--- trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp 2021-10-12 15:47:13 UTC (rev 283982)
+++ trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeFrameScrollingNodeNicosia.cpp 2021-10-12 15:48:46 UTC (rev 283983)
@@ -104,7 +104,11 @@
bool ScrollingTreeFrameScrollingNodeNicosia::startAnimatedScrollToPosition(FloatPoint destinationPosition)
{
- return m_delegate.startAnimatedScrollToPosition(destinationPosition);
+ bool started = m_delegate.startAnimatedScrollToPosition(destinationPosition);
+ if (started)
+ willStartAnimatedScroll();
+
+ return started;
}
void ScrollingTreeFrameScrollingNodeNicosia::stopAnimatedScroll()
Modified: trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.cpp (283982 => 283983)
--- trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.cpp 2021-10-12 15:47:13 UTC (rev 283982)
+++ trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeOverflowScrollingNodeNicosia.cpp 2021-10-12 15:48:46 UTC (rev 283983)
@@ -87,7 +87,11 @@
bool ScrollingTreeOverflowScrollingNodeNicosia::startAnimatedScrollToPosition(FloatPoint destinationPosition)
{
- return m_delegate.startAnimatedScrollToPosition(destinationPosition);
+ bool started = m_delegate.startAnimatedScrollToPosition(destinationPosition);
+ if (started)
+ willStartAnimatedScroll();
+
+ return started;
}
void ScrollingTreeOverflowScrollingNodeNicosia::stopAnimatedScroll()
Modified: trunk/Source/WebKit/ChangeLog (283982 => 283983)
--- trunk/Source/WebKit/ChangeLog 2021-10-12 15:47:13 UTC (rev 283982)
+++ trunk/Source/WebKit/ChangeLog 2021-10-12 15:48:46 UTC (rev 283983)
@@ -1,3 +1,13 @@
+2021-10-12 Simon Fraser <[email protected]>
+
+ Have the ScrollingTree track nodes with animated scrolls
+ https://bugs.webkit.org/show_bug.cgi?id=231554
+
+ Reviewed by Tim Horton.
+
+ * UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.mm:
+ (WebKit::ScrollingTreeOverflowScrollingNodeIOS::startAnimatedScrollToPosition):
+
2021-10-12 Alex Christensen <[email protected]>
Begin migration from WTF::Variant to std::variant
Modified: trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.mm (283982 => 283983)
--- trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.mm 2021-10-12 15:47:13 UTC (rev 283982)
+++ trunk/Source/WebKit/UIProcess/RemoteLayerTree/ios/ScrollingTreeOverflowScrollingNodeIOS.mm 2021-10-12 15:48:46 UTC (rev 283983)
@@ -80,7 +80,10 @@
bool ScrollingTreeOverflowScrollingNodeIOS::startAnimatedScrollToPosition(FloatPoint destinationPosition)
{
- return m_scrollingNodeDelegate->startAnimatedScrollToPosition(destinationPosition);
+ bool started = m_scrollingNodeDelegate->startAnimatedScrollToPosition(destinationPosition);
+ if (started)
+ willStartAnimatedScroll();
+ return started;
}
void ScrollingTreeOverflowScrollingNodeIOS::stopAnimatedScroll()