Title: [260190] trunk
Revision
260190
Author
[email protected]
Date
2020-04-16 08:55:22 -0700 (Thu, 16 Apr 2020)

Log Message

[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.

Source/WebCore:

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:

LayoutTests:

* 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.

Modified Paths

Added Paths

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();
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to