Diff
Modified: trunk/LayoutTests/ChangeLog (260189 => 260190)
--- trunk/LayoutTests/ChangeLog 2020-04-16 15:52:58 UTC (rev 260189)
+++ trunk/LayoutTests/ChangeLog 2020-04-16 15:55:22 UTC (rev 260190)
@@ -1,3 +1,17 @@
+2020-04-16 Simon Fraser <[email protected]>
+
+ [Async overflow scrolling] Slow-repaint overflow scroll have force their enclosing scrollers to be slow too
+ https://bugs.webkit.org/show_bug.cgi?id=210591
+
+ Reviewed by Antti Koivisto.
+
+ * scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-non-cb-overflow-expected.txt: Added.
+ * scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-non-cb-overflow.html: Added.
+ * scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-overflow-expected.txt: Added.
+ * scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-overflow.html: Added.
+ * scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-overflow2-expected.txt: Added.
+ * scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-overflow2.html: Added.
+
2020-04-16 Antoine Quint <[email protected]>
[ Mac wk2 Debug ] media/modern-media-controls/media-controller/media-controller-auto-hide.html is flaky timing out.
Added: trunk/LayoutTests/scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-non-cb-overflow-expected.txt (0 => 260190)
--- trunk/LayoutTests/scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-non-cb-overflow-expected.txt (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-non-cb-overflow-expected.txt 2020-04-16 15:55:22 UTC (rev 260190)
@@ -0,0 +1,47 @@
+Outer scrolling content
+Inner scrolling content
+Fixed background
+
+(scrolling tree
+ (frame scrolling node
+ (scrollable area size width=800 height=600)
+ (total content size width=800 height=600)
+ (last committed scroll position (0,0))
+ (scrollable area parameters
+ (horizontal scroll elasticity 2)
+ (vertical scroll elasticity 2)
+ (horizontal scrollbar mode 0)
+ (vertical scrollbar mode 0))
+ (synchronous scrolling reasons Has slow repaint objects, Has slow repaint descendant scrollers)
+ (layout viewport (0,0) width=800 height=600)
+ (min layoutViewport origin (0,0))
+ (max layoutViewport origin (0,0))
+ (behavior for fixed 0)
+ (overflow scrolling node
+ (scrollable area size width=405 height=305)
+ (total content size width=405 height=1020)
+ (last committed scroll position (0,0))
+ (scrollable area parameters
+ (horizontal scroll elasticity 0)
+ (vertical scroll elasticity 0)
+ (horizontal scrollbar mode 0)
+ (vertical scrollbar mode 0)
+ (has enabled vertical scrollbar 1))
+ (synchronous scrolling reasons Has slow repaint descendant scrollers)
+ (positioned node
+ (layout constraints
+ (layer-position-at-last-layout (10,128)))
+ (related overflow nodes 1)
+ (overflow scrolling node
+ (scrollable area size width=355 height=305)
+ (total content size width=410 height=1020)
+ (last committed scroll position (0,0))
+ (scrollable area parameters
+ (horizontal scroll elasticity 0)
+ (vertical scroll elasticity 0)
+ (horizontal scrollbar mode 0)
+ (vertical scrollbar mode 0)
+ (has enabled horizontal scrollbar 1)
+ (has enabled vertical scrollbar 1))
+ (synchronous scrolling reasons Has slow repaint objects))))))
+
Added: trunk/LayoutTests/scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-non-cb-overflow.html (0 => 260190)
--- trunk/LayoutTests/scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-non-cb-overflow.html (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-non-cb-overflow.html 2020-04-16 15:55:22 UTC (rev 260190)
@@ -0,0 +1,69 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+ <title>Scrolling tree should show slow-repaint reasons on the overflow and root nodes</title>
+ <style>
+
+ .outer.scroller {
+ opacity: 0.9;
+ }
+ .scroller {
+ background-color: silver;
+ border: 1px solid black;
+ padding: 10px;
+ width: 400px;
+ height: 300px;
+ overflow: scroll;
+ }
+
+ .scroller .scroller {
+ position: absolute;
+ margin-top: 100px;
+ width: 350px;
+ height: 300px;
+ }
+
+ .scrolling-content {
+ height: 1000px;
+ }
+
+ .fixed-background {
+ margin-top: 100px;
+ width: 400px;
+ height: 300px;
+ background-image: linear-gradient(green, blue);
+ background-attachment: fixed;
+ }
+ .filler {
+ width: 100px;
+ height: 250px;
+ }
+ </style>
+ <script src=""
+ <script>
+ if (window.testRunner)
+ testRunner.dumpAsText();
+
+ window.addEventListener('load', () => {
+ if (window.internals)
+ document.getElementById('scrollingTree').innerText = window.internals.scrollingTreeAsText() + "\n";
+ }, false);
+ </script>
+</head>
+<body>
+ <div class="outer scroller">
+ <div class="scrolling-content">
+ Outer scrolling content
+ <div class="scroller">
+ <div class="scrolling-content">
+ Inner scrolling content
+ <div class="fixed-background">
+ Fixed background
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <pre id="scrollingTree"></pre>
+</body>
+</html>
Added: trunk/LayoutTests/scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-overflow-expected.txt (0 => 260190)
--- trunk/LayoutTests/scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-overflow-expected.txt (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-overflow-expected.txt 2020-04-16 15:55:22 UTC (rev 260190)
@@ -0,0 +1,43 @@
+Outer scrolling content
+Inner scrolling content
+Fixed background
+
+(scrolling tree
+ (frame scrolling node
+ (scrollable area size width=800 height=600)
+ (total content size width=800 height=600)
+ (last committed scroll position (0,0))
+ (scrollable area parameters
+ (horizontal scroll elasticity 2)
+ (vertical scroll elasticity 2)
+ (horizontal scrollbar mode 0)
+ (vertical scrollbar mode 0))
+ (synchronous scrolling reasons Has slow repaint objects, Has slow repaint descendant scrollers)
+ (layout viewport (0,0) width=800 height=600)
+ (min layoutViewport origin (0,0))
+ (max layoutViewport origin (0,0))
+ (behavior for fixed 0)
+ (overflow scrolling node
+ (scrollable area size width=405 height=305)
+ (total content size width=405 height=1020)
+ (last committed scroll position (0,0))
+ (scrollable area parameters
+ (horizontal scroll elasticity 0)
+ (vertical scroll elasticity 0)
+ (horizontal scrollbar mode 0)
+ (vertical scrollbar mode 0)
+ (has enabled vertical scrollbar 1))
+ (synchronous scrolling reasons Has slow repaint descendant scrollers)
+ (overflow scrolling node
+ (scrollable area size width=355 height=305)
+ (total content size width=410 height=1020)
+ (last committed scroll position (0,0))
+ (scrollable area parameters
+ (horizontal scroll elasticity 0)
+ (vertical scroll elasticity 0)
+ (horizontal scrollbar mode 0)
+ (vertical scrollbar mode 0)
+ (has enabled horizontal scrollbar 1)
+ (has enabled vertical scrollbar 1))
+ (synchronous scrolling reasons Has slow repaint objects)))))
+
Added: trunk/LayoutTests/scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-overflow.html (0 => 260190)
--- trunk/LayoutTests/scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-overflow.html (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-overflow.html 2020-04-16 15:55:22 UTC (rev 260190)
@@ -0,0 +1,63 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+ <title>Scrolling tree should show slow-repaint reasons on the overflow and root nodes</title>
+ <style>
+ .scroller {
+ background-color: silver;
+ border: 1px solid black;
+ padding: 10px;
+ width: 400px;
+ height: 300px;
+ overflow: scroll;
+ }
+
+ .scroller .scroller {
+ margin-top: 100px;
+ width: 350px;
+ height: 300px;
+ }
+
+ .scrolling-content {
+ height: 1000px;
+ }
+
+ .fixed-background {
+ margin-top: 100px;
+ width: 400px;
+ height: 300px;
+ background-image: linear-gradient(green, blue);
+ background-attachment: fixed;
+ }
+ .filler {
+ width: 100px;
+ height: 250px;
+ }
+ </style>
+ <script>
+ if (window.testRunner)
+ testRunner.dumpAsText();
+
+ window.addEventListener('load', () => {
+ if (window.internals)
+ document.getElementById('scrollingTree').innerText = window.internals.scrollingTreeAsText() + "\n";
+ }, false);
+ </script>
+</head>
+<body>
+ <div class="scroller">
+ <div class="scrolling-content">
+ Outer scrolling content
+ <div class="scroller">
+ <div class="scrolling-content">
+ Inner scrolling content
+ <div class="fixed-background">
+ Fixed background
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <pre id="scrollingTree"></pre>
+</body>
+</html>
Added: trunk/LayoutTests/scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-overflow2-expected.txt (0 => 260190)
--- trunk/LayoutTests/scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-overflow2-expected.txt (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-overflow2-expected.txt 2020-04-16 15:55:22 UTC (rev 260190)
@@ -0,0 +1,45 @@
+Outer scrolling content
+Inner scrolling content
+Fixed background
+
+(scrolling tree
+ (frame scrolling node
+ (scrollable area size width=800 height=600)
+ (total content size width=800 height=600)
+ (last committed scroll position (0,0))
+ (scrollable area parameters
+ (horizontal scroll elasticity 2)
+ (vertical scroll elasticity 2)
+ (horizontal scrollbar mode 0)
+ (vertical scrollbar mode 0))
+ (synchronous scrolling reasons Has slow repaint objects, Has slow repaint descendant scrollers)
+ (layout viewport (0,0) width=800 height=600)
+ (min layoutViewport origin (0,0))
+ (max layoutViewport origin (0,0))
+ (behavior for fixed 0)
+ (overflow scrolling node
+ (scrollable area size width=405 height=305)
+ (total content size width=405 height=1020)
+ (last committed scroll position (0,0))
+ (scrollable area parameters
+ (horizontal scroll elasticity 0)
+ (vertical scroll elasticity 0)
+ (horizontal scrollbar mode 0)
+ (vertical scrollbar mode 0)
+ (has enabled vertical scrollbar 1))
+ (synchronous scrolling reasons Has slow repaint descendant scrollers))
+ (overflow scroll proxy node
+ (related overflow scrolling node scroll position (0,0))
+ (overflow scrolling node
+ (scrollable area size width=355 height=305)
+ (total content size width=410 height=1020)
+ (last committed scroll position (0,0))
+ (scrollable area parameters
+ (horizontal scroll elasticity 0)
+ (vertical scroll elasticity 0)
+ (horizontal scrollbar mode 0)
+ (vertical scrollbar mode 0)
+ (has enabled horizontal scrollbar 1)
+ (has enabled vertical scrollbar 1))
+ (synchronous scrolling reasons Has slow repaint objects)))))
+
Added: trunk/LayoutTests/scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-overflow2.html (0 => 260190)
--- trunk/LayoutTests/scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-overflow2.html (rev 0)
+++ trunk/LayoutTests/scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-overflow2.html 2020-04-16 15:55:22 UTC (rev 260190)
@@ -0,0 +1,68 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+ <title>Scrolling tree should show slow-repaint reasons on the overflow and root nodes</title>
+ <style>
+ .scroller {
+ background-color: silver;
+ border: 1px solid black;
+ padding: 10px;
+ width: 400px;
+ height: 300px;
+ overflow: scroll;
+ }
+
+ .relative {
+ position: relative;
+ }
+ .scroller .scroller {
+ margin-top: 100px;
+ width: 350px;
+ height: 300px;
+ }
+
+ .scrolling-content {
+ height: 1000px;
+ }
+
+ .fixed-background {
+ margin-top: 100px;
+ width: 400px;
+ height: 300px;
+ background-image: linear-gradient(green, blue);
+ background-attachment: fixed;
+ }
+ .filler {
+ width: 100px;
+ height: 250px;
+ }
+ </style>
+ <script>
+ if (window.testRunner)
+ testRunner.dumpAsText();
+
+ window.addEventListener('load', () => {
+ if (window.internals)
+ document.getElementById('scrollingTree').innerText = window.internals.scrollingTreeAsText() + "\n";
+ }, false);
+ </script>
+</head>
+<body>
+ <div class="scroller">
+ <div class="scrolling-content">
+ Outer scrolling content
+ <div class="relative">
+ <div class="scroller">
+ <div class="scrolling-content">
+ Inner scrolling content
+ <div class="fixed-background">
+ Fixed background
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <pre id="scrollingTree"></pre>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (260189 => 260190)
--- trunk/Source/WebCore/ChangeLog 2020-04-16 15:52:58 UTC (rev 260189)
+++ trunk/Source/WebCore/ChangeLog 2020-04-16 15:55:22 UTC (rev 260190)
@@ -1,3 +1,54 @@
+2020-04-16 Simon Fraser <[email protected]>
+
+ [Async overflow scrolling] Slow-repaint overflow scroll have force their enclosing scrollers to be slow too
+ https://bugs.webkit.org/show_bug.cgi?id=210591
+
+ Reviewed by Antti Koivisto.
+
+ If an overflow:scroll has background-attachment:fixed in the contents, then both it and all its containing-block
+ scrolling ancestors have to be slow-scrolling too, because scrolling any of them affects the local geometry
+ of the fixed backgrounds which paint on scroll.
+
+ Implement this by having the scrolling tree do a post-commit pass over the nodes with sync scrolling reasons
+ (which we collect during the commit phase). For each slow-scrolling node, walk its ancestor chain (via
+ proxy nodes when necessary) and mark the scrolling node ancestors with the "DescendantScrollersHaveSynchronousScrolling"
+ reason.
+
+ For testing, expose internals.scrollingTreeAsText(), which needs a bit of synchronization via
+ waitForScrollingTreeCommit() since the commit happens on the scrolling thread.
+
+ Tests: scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-non-cb-overflow.html
+ scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-overflow.html
+ scrollingcoordinator/mac/fixed-backgrounds/fixed-background-in-nested-overflow2.html
+
+ * page/scrolling/AsyncScrollingCoordinator.cpp:
+ (WebCore::AsyncScrollingCoordinator::scrollingStateTreeAsText const):
+ (WebCore::AsyncScrollingCoordinator::scrollingTreeAsText const):
+ * page/scrolling/AsyncScrollingCoordinator.h:
+ * page/scrolling/ScrollingCoordinator.cpp:
+ (WebCore::ScrollingCoordinator::scrollingStateTreeAsText const):
+ (WebCore::ScrollingCoordinator::scrollingTreeAsText const):
+ (WebCore::ScrollingCoordinator::synchronousScrollingReasonsAsText):
+ * page/scrolling/ScrollingCoordinator.h:
+ * page/scrolling/ScrollingCoordinatorTypes.h:
+ * page/scrolling/ScrollingTree.cpp:
+ (WebCore::ScrollingTree::commitTreeState):
+ (WebCore::ScrollingTree::updateTreeFromStateNodeRecursive):
+ (WebCore::ScrollingTree::propagateSynchronousScrollingReasons):
+ (WebCore::ScrollingTree::updateTreeFromStateNode): Deleted.
+ * page/scrolling/ScrollingTree.h:
+ (WebCore::ScrollingTree::waitForScrollingTreeCommit):
+ * page/scrolling/ScrollingTreeScrollingNode.cpp:
+ (WebCore::ScrollingTreeScrollingNode::commitStateAfterChildren):
+ * page/scrolling/ScrollingTreeScrollingNode.h:
+ * page/scrolling/ThreadedScrollingTree.cpp:
+ (WebCore::ThreadedScrollingTree::waitForScrollingTreeCommit):
+ * page/scrolling/ThreadedScrollingTree.h:
+ * testing/Internals.cpp:
+ (WebCore::Internals::scrollingTreeAsText const):
+ * testing/Internals.h:
+ * testing/Internals.idl:
+
2020-04-16 Claudio Saavedra <[email protected]>
Clean a couple of unused-parameters warnings
Modified: trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp (260189 => 260190)
--- trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp 2020-04-16 15:52:58 UTC (rev 260189)
+++ trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp 2020-04-16 15:55:22 UTC (rev 260190)
@@ -820,9 +820,18 @@
return m_scrollingStateTree->rootStateNode()->scrollingStateTreeAsText(behavior);
}
- return String();
+ return emptyString();
}
+String AsyncScrollingCoordinator::scrollingTreeAsText(ScrollingStateTreeAsTextBehavior behavior) const
+{
+ if (!m_scrollingTree)
+ return emptyString();
+
+ m_scrollingTree->waitForScrollingTreeCommit();
+ return m_scrollingTree->scrollingTreeAsText(behavior);
+}
+
#if PLATFORM(COCOA)
void AsyncScrollingCoordinator::setActiveScrollSnapIndices(ScrollingNodeID scrollingNodeID, unsigned horizontalIndex, unsigned verticalIndex)
{
Modified: trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h (260189 => 260190)
--- trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h 2020-04-16 15:52:58 UTC (rev 260189)
+++ trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h 2020-04-16 15:55:22 UTC (rev 260190)
@@ -78,6 +78,7 @@
void updateScrollPositionAfterAsyncScroll(ScrollingNodeID, const FloatPoint&, Optional<FloatPoint> layoutViewportOrigin, ScrollType, ScrollingLayerPositionAction);
WEBCORE_EXPORT String scrollingStateTreeAsText(ScrollingStateTreeAsTextBehavior = ScrollingStateTreeAsTextBehaviorNormal) const override;
+ WEBCORE_EXPORT String scrollingTreeAsText(ScrollingStateTreeAsTextBehavior = ScrollingStateTreeAsTextBehaviorNormal) const override;
WEBCORE_EXPORT void willCommitTree() override;
bool eventTrackingRegionsDirty() const { return m_eventTrackingRegionsDirty; }
Modified: trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp (260189 => 260190)
--- trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp 2020-04-16 15:52:58 UTC (rev 260189)
+++ trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp 2020-04-16 15:55:22 UTC (rev 260190)
@@ -387,9 +387,14 @@
String ScrollingCoordinator::scrollingStateTreeAsText(ScrollingStateTreeAsTextBehavior) const
{
- return String();
+ return emptyString();
}
+String ScrollingCoordinator::scrollingTreeAsText(ScrollingStateTreeAsTextBehavior) const
+{
+ return emptyString();
+}
+
String ScrollingCoordinator::synchronousScrollingReasonsAsText(OptionSet<SynchronousScrollingReason> reasons)
{
StringBuilder stringBuilder;
@@ -396,15 +401,22 @@
if (reasons & SynchronousScrollingReason::ForcedOnMainThread)
stringBuilder.appendLiteral("Forced on main thread, ");
+
if (reasons & SynchronousScrollingReason::HasSlowRepaintObjects)
stringBuilder.appendLiteral("Has slow repaint objects, ");
+
if (reasons & SynchronousScrollingReason::HasViewportConstrainedObjectsWithoutSupportingFixedLayers)
stringBuilder.appendLiteral("Has viewport constrained objects without supporting fixed layers, ");
+
if (reasons & SynchronousScrollingReason::HasNonLayerViewportConstrainedObjects)
stringBuilder.appendLiteral("Has non-layer viewport-constrained objects, ");
+
if (reasons & SynchronousScrollingReason::IsImageDocument)
stringBuilder.appendLiteral("Is image document, ");
+ if (reasons & SynchronousScrollingReason::DescendantScrollersHaveSynchronousScrolling)
+ stringBuilder.appendLiteral("Has slow repaint descendant scrollers, ");
+
if (stringBuilder.length())
stringBuilder.resize(stringBuilder.length() - 2);
return stringBuilder.toString();
Modified: trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h (260189 => 260190)
--- trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h 2020-04-16 15:52:58 UTC (rev 260189)
+++ trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.h 2020-04-16 15:55:22 UTC (rev 260190)
@@ -161,6 +161,7 @@
virtual void reconcileViewportConstrainedLayerPositions(ScrollingNodeID, const LayoutRect&, ScrollingLayerPositionAction) { }
virtual String scrollingStateTreeAsText(ScrollingStateTreeAsTextBehavior = ScrollingStateTreeAsTextBehaviorNormal) const;
+ virtual String scrollingTreeAsText(ScrollingStateTreeAsTextBehavior = ScrollingStateTreeAsTextBehaviorNormal) const;
virtual bool isRubberBandInProgress() const { return false; }
virtual bool isScrollSnapInProgress() const { return false; }
virtual void updateScrollSnapPropertiesWithFrameView(const FrameView&) { }
Modified: trunk/Source/WebCore/page/scrolling/ScrollingCoordinatorTypes.h (260189 => 260190)
--- trunk/Source/WebCore/page/scrolling/ScrollingCoordinatorTypes.h 2020-04-16 15:52:58 UTC (rev 260189)
+++ trunk/Source/WebCore/page/scrolling/ScrollingCoordinatorTypes.h 2020-04-16 15:55:22 UTC (rev 260190)
@@ -30,11 +30,14 @@
namespace WebCore {
enum class SynchronousScrollingReason {
+ // Flags for frame scrolling.
ForcedOnMainThread = 1 << 0,
- HasSlowRepaintObjects = 1 << 1,
- HasViewportConstrainedObjectsWithoutSupportingFixedLayers = 1 << 2,
- HasNonLayerViewportConstrainedObjects = 1 << 3,
- IsImageDocument = 1 << 4
+ HasViewportConstrainedObjectsWithoutSupportingFixedLayers = 1 << 1,
+ HasNonLayerViewportConstrainedObjects = 1 << 2,
+ IsImageDocument = 1 << 3,
+ // Flags for frame and overflow scrolling.
+ HasSlowRepaintObjects = 1 << 4,
+ DescendantScrollersHaveSynchronousScrolling = 1 << 5,
};
enum class ScrollingNodeType : uint8_t {
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp (260189 => 260190)
--- trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp 2020-04-16 15:52:58 UTC (rev 260189)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp 2020-04-16 15:55:22 UTC (rev 260190)
@@ -44,6 +44,18 @@
namespace WebCore {
+using OrphanScrollingNodeMap = HashMap<ScrollingNodeID, RefPtr<ScrollingTreeNode>>;
+
+struct CommitTreeState {
+ // unvisitedNodes starts with all nodes in the map; we remove nodes as we visit them. At the end, it's the unvisited nodes.
+ // We can't use orphanNodes for this, because orphanNodes won't contain descendants of removed nodes.
+ HashSet<ScrollingNodeID> unvisitedNodes;
+ // Nodes with non-empty synchronousScrollingReasons.
+ HashSet<ScrollingNodeID> synchronousScrollingNodes;
+ // orphanNodes keeps child nodes alive while we rebuild child lists.
+ OrphanScrollingNodeMap orphanNodes;
+};
+
ScrollingTree::ScrollingTree() = default;
ScrollingTree::~ScrollingTree() = default;
@@ -173,22 +185,19 @@
if (rootStateNodeChanged || rootNode->hasChangedProperty(ScrollingStateFrameScrollingNode::IsMonitoringWheelEvents))
m_isMonitoringWheelEvents = scrollingStateTree->rootStateNode()->isMonitoringWheelEvents();
}
-
- // unvisitedNodes starts with all nodes in the map; we remove nodes as we visit them. At the end, it's the unvisited nodes.
- // We can't use orphanNodes for this, because orphanNodes won't contain descendants of removed nodes.
- HashSet<ScrollingNodeID> unvisitedNodes;
- for (auto nodeID : m_nodeMap.keys())
- unvisitedNodes.add(nodeID);
m_overflowRelatedNodesMap.clear();
m_activeOverflowScrollProxyNodes.clear();
m_activePositionedNodes.clear();
- // orphanNodes keeps child nodes alive while we rebuild child lists.
- OrphanScrollingNodeMap orphanNodes;
- updateTreeFromStateNode(rootNode, orphanNodes, unvisitedNodes);
-
- for (auto nodeID : unvisitedNodes) {
+ CommitTreeState commitState;
+ for (auto nodeID : m_nodeMap.keys())
+ commitState.unvisitedNodes.add(nodeID);
+
+ updateTreeFromStateNodeRecursive(rootNode, commitState);
+ propagateSynchronousScrollingReasons(commitState.synchronousScrollingNodes);
+
+ for (auto nodeID : commitState.unvisitedNodes) {
m_latchingController.nodeWasRemoved(nodeID);
LOG(Scrolling, "ScrollingTree::commitTreeState - removing unvisited node %" PRIu64, nodeID);
@@ -198,7 +207,7 @@
LOG_WITH_STREAM(Scrolling, stream << "committed ScrollingTree" << scrollingTreeAsText(ScrollingStateTreeAsTextBehaviorDebug));
}
-void ScrollingTree::updateTreeFromStateNode(const ScrollingStateNode* stateNode, OrphanScrollingNodeMap& orphanNodes, HashSet<ScrollingNodeID>& unvisitedNodes)
+void ScrollingTree::updateTreeFromStateNodeRecursive(const ScrollingStateNode* stateNode, CommitTreeState& state)
{
if (!stateNode) {
m_nodeMap.clear();
@@ -214,7 +223,7 @@
RefPtr<ScrollingTreeNode> node;
if (it != m_nodeMap.end()) {
node = it->value;
- unvisitedNodes.remove(nodeID);
+ state.unvisitedNodes.remove(nodeID);
} else {
node = createScrollingTreeNode(stateNode->nodeType(), nodeID);
if (!parentNodeID) {
@@ -251,7 +260,7 @@
// Move all children into the orphanNodes map. Live ones will get added back as we recurse over children.
for (auto& childScrollingNode : node->children()) {
childScrollingNode->setParent(nullptr);
- orphanNodes.add(childScrollingNode->scrollingNodeID(), childScrollingNode.ptr());
+ state.orphanNodes.add(childScrollingNode->scrollingNodeID(), childScrollingNode.ptr());
}
node->removeAllChildren();
@@ -258,10 +267,15 @@
// Now update the children if we have any.
if (auto children = stateNode->children()) {
for (auto& child : *children)
- updateTreeFromStateNode(child.get(), orphanNodes, unvisitedNodes);
+ updateTreeFromStateNodeRecursive(child.get(), state);
}
node->commitStateAfterChildren(*stateNode);
+
+#if ENABLE(SCROLLING_THREAD)
+ if (is<ScrollingTreeScrollingNode>(*node) && !downcast<ScrollingTreeScrollingNode>(*node).synchronousScrollingReasons().isEmpty())
+ state.synchronousScrollingNodes.add(nodeID);
+#endif
}
void ScrollingTree::applyLayerPositionsAfterCommit()
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.h (260189 => 260190)
--- trunk/Source/WebCore/page/scrolling/ScrollingTree.h 2020-04-16 15:52:58 UTC (rev 260189)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.h 2020-04-16 15:55:22 UTC (rev 260190)
@@ -170,6 +170,8 @@
virtual void lockLayersForHitTesting() { }
virtual void unlockLayersForHitTesting() { }
+ virtual void waitForScrollingTreeCommit() { }
+
protected:
FloatPoint mainFrameScrollPosition() const;
void setMainFrameScrollPosition(FloatPoint);
@@ -177,8 +179,8 @@
WEBCORE_EXPORT virtual ScrollingEventResult handleWheelEvent(const PlatformWheelEvent&);
private:
- using OrphanScrollingNodeMap = HashMap<ScrollingNodeID, RefPtr<ScrollingTreeNode>>;
- void updateTreeFromStateNode(const ScrollingStateNode*, OrphanScrollingNodeMap&, HashSet<ScrollingNodeID>& unvisitedNodes);
+ void updateTreeFromStateNodeRecursive(const ScrollingStateNode*, struct CommitTreeState&);
+ virtual void propagateSynchronousScrollingReasons(const HashSet<ScrollingNodeID>&) { }
void applyLayerPositionsRecursive(ScrollingTreeNode&);
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp (260189 => 260190)
--- trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp 2020-04-16 15:52:58 UTC (rev 260189)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp 2020-04-16 15:55:22 UTC (rev 260190)
@@ -117,6 +117,10 @@
scrollingTree().scrollingTreeNodeRequestsScroll(scrollingNodeID(), requestedScrollData.scrollPosition, requestedScrollData.scrollType, requestedScrollData.clamping);
}
+ // This synthetic bit is added back in ScrollingTree::propagateSynchronousScrollingReasons().
+#if ENABLE(SCROLLING_THREAD)
+ m_synchronousScrollingReasons.remove(SynchronousScrollingReason::DescendantScrollersHaveSynchronousScrolling);
+#endif
m_isFirstCommit = false;
}
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h (260189 => 260190)
--- trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h 2020-04-16 15:52:58 UTC (rev 260189)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h 2020-04-16 15:55:22 UTC (rev 260190)
@@ -74,6 +74,7 @@
#if ENABLE(SCROLLING_THREAD)
OptionSet<SynchronousScrollingReason> synchronousScrollingReasons() const { return m_synchronousScrollingReasons; }
+ void addSynchronousScrollingReason(SynchronousScrollingReason reason) { m_synchronousScrollingReasons.add(reason); }
bool shouldUpdateScrollLayerPositionSynchronously() const { return !m_synchronousScrollingReasons.isEmpty(); }
#endif
Modified: trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp (260189 => 260190)
--- trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp 2020-04-16 15:52:58 UTC (rev 260189)
+++ trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp 2020-04-16 15:55:22 UTC (rev 260190)
@@ -33,6 +33,7 @@
#include "ScrollingThread.h"
#include "ScrollingTreeFrameScrollingNode.h"
#include "ScrollingTreeNode.h"
+#include "ScrollingTreeOverflowScrollProxyNode.h"
#include "ScrollingTreeScrollingNode.h"
#include <wtf/RunLoop.h>
@@ -92,6 +93,32 @@
decrementPendingCommitCount();
}
+void ThreadedScrollingTree::propagateSynchronousScrollingReasons(const HashSet<ScrollingNodeID>& synchronousScrollingNodes)
+{
+ auto propagateStateToAncestors = [&](ScrollingTreeNode& node) {
+ ASSERT(is<ScrollingTreeScrollingNode>(node) && !downcast<ScrollingTreeScrollingNode>(node).synchronousScrollingReasons().isEmpty());
+
+ auto currNode = node.parent();
+
+ while (currNode) {
+ if (is<ScrollingTreeScrollingNode>(currNode))
+ downcast<ScrollingTreeScrollingNode>(*currNode).addSynchronousScrollingReason(SynchronousScrollingReason::DescendantScrollersHaveSynchronousScrolling);
+
+ if (is<ScrollingTreeOverflowScrollProxyNode>(currNode)) {
+ currNode = nodeForID(downcast<ScrollingTreeOverflowScrollProxyNode>(*currNode).overflowScrollingNodeID());
+ continue;
+ }
+
+ currNode = currNode->parent();
+ }
+ };
+
+ for (auto nodeID : synchronousScrollingNodes) {
+ if (auto node = nodeForID(nodeID))
+ propagateStateToAncestors(*node);
+ }
+}
+
void ThreadedScrollingTree::scrollingTreeNodeDidScroll(ScrollingTreeScrollingNode& node, ScrollingLayerPositionAction scrollingLayerPositionAction)
{
if (!m_scrollingCoordinator)
@@ -155,6 +182,11 @@
m_commitCondition.wait(m_pendingCommitCountMutex);
}
+void ThreadedScrollingTree::waitForScrollingTreeCommit()
+{
+ waitForPendingCommits();
+}
+
void ThreadedScrollingTree::applyLayerPositions()
{
waitForPendingCommits();
Modified: trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.h (260189 => 260190)
--- trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.h 2020-04-16 15:52:58 UTC (rev 260189)
+++ trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.h 2020-04-16 15:55:22 UTC (rev 260190)
@@ -78,6 +78,8 @@
private:
bool isThreadedScrollingTree() const override { return true; }
void applyLayerPositions() override;
+ void waitForScrollingTreeCommit() override;
+ void propagateSynchronousScrollingReasons(const HashSet<ScrollingNodeID>&) override;
RefPtr<AsyncScrollingCoordinator> m_scrollingCoordinator;
Modified: trunk/Source/WebCore/testing/Internals.cpp (260189 => 260190)
--- trunk/Source/WebCore/testing/Internals.cpp 2020-04-16 15:52:58 UTC (rev 260189)
+++ trunk/Source/WebCore/testing/Internals.cpp 2020-04-16 15:55:22 UTC (rev 260190)
@@ -2833,6 +2833,26 @@
return page->scrollingStateTreeAsText();
}
+ExceptionOr<String> Internals::scrollingTreeAsText() const
+{
+ Document* document = contextDocument();
+ if (!document || !document->frame())
+ return Exception { InvalidAccessError };
+
+ document->updateLayoutIgnorePendingStylesheets();
+
+ auto page = document->page();
+ if (!page)
+ return String();
+
+ auto scrollingCoordinator = page->scrollingCoordinator();
+ if (!scrollingCoordinator)
+ return String();
+
+ scrollingCoordinator->commitTreeStateIfNeeded();
+ return scrollingCoordinator->scrollingTreeAsText();
+}
+
ExceptionOr<String> Internals::mainThreadScrollingReasons() const
{
Document* document = contextDocument();
Modified: trunk/Source/WebCore/testing/Internals.h (260189 => 260190)
--- trunk/Source/WebCore/testing/Internals.h 2020-04-16 15:52:58 UTC (rev 260189)
+++ trunk/Source/WebCore/testing/Internals.h 2020-04-16 15:55:22 UTC (rev 260190)
@@ -393,6 +393,7 @@
ExceptionOr<bool> scrollbarUsingDarkAppearance(Node*) const;
ExceptionOr<String> scrollingStateTreeAsText() const;
+ ExceptionOr<String> scrollingTreeAsText() const;
ExceptionOr<String> mainThreadScrollingReasons() const;
ExceptionOr<Ref<DOMRectList>> nonFastScrollableRects() const;
Modified: trunk/Source/WebCore/testing/Internals.idl (260189 => 260190)
--- trunk/Source/WebCore/testing/Internals.idl 2020-04-16 15:52:58 UTC (rev 260189)
+++ trunk/Source/WebCore/testing/Internals.idl 2020-04-16 15:55:22 UTC (rev 260190)
@@ -461,6 +461,7 @@
[MayThrowException] boolean scrollbarUsingDarkAppearance(optional Node? node = null);
[MayThrowException] DOMString scrollingStateTreeAsText();
+ [MayThrowException] DOMString scrollingTreeAsText();
[MayThrowException] DOMString mainThreadScrollingReasons(); // FIXME: rename to synchronousScrollingReasons().
[MayThrowException] DOMRectList nonFastScrollableRects();