Title: [251262] trunk
Revision
251262
Author
simon.fra...@apple.com
Date
2019-10-17 15:15:09 -0700 (Thu, 17 Oct 2019)

Log Message

[ Mojave+ ] Layout Test compositing/fixed-with-main-thread-scrolling.html is a flaky timeout
https://bugs.webkit.org/show_bug.cgi?id=198757

Reviewed by Tim Horton.

Source/WebCore:

WheelEventTestMonitor depends on "deferral reasons" getting added and removed, such that there is always
at least one reason active until scrolling quiesces.

WheelEventTestMonitor made the incorrect assumption that every call into ScrollingTreeScrollingNodeDelegateMac::handleWheelEvent()
would result in a scroll change making it to the main thread, so it would defer "ScrollingThreadSyncNeeded" there,
and rely on AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll() to remove that deferral reason.
That assumption is wrong, because wheel events may coalesce, or have no impact on scroll position if already scrolled
to the max/min extent (e.g. when rubber banding).

Fix by adding a new "HandlingWheelEvent" deferral reason for the duration that the scrolling thread is processing an wheel event,
and then having ScrollingThreadSyncNeeded just represent the phase where any resulting scroll is being sent to the UI process.
These phases should always overlap.

This required moving isMonitoringWheelEvents() from the root scrolling node to the ScrollingTree.

* page/WheelEventTestMonitor.cpp:
(WebCore::operator<<):
* page/WheelEventTestMonitor.h:
* page/scrolling/AsyncScrollingCoordinator.cpp:
(WebCore::AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll):
* page/scrolling/ScrollingTree.cpp:
(WebCore::ScrollingTree::commitTreeState):
* page/scrolling/ScrollingTree.h:
(WebCore::ScrollingTree::isMonitoringWheelEvents const):
* page/scrolling/ScrollingTreeScrollingNode.cpp:
(WebCore::ScrollingTreeScrollingNode::commitStateBeforeChildren):
* page/scrolling/ScrollingTreeScrollingNode.h:
* page/scrolling/ThreadedScrollingTree.cpp:
(WebCore::ThreadedScrollingTree::scrollingTreeNodeDidScroll):
* page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm:
(WebCore::ScrollingTreeScrollingNodeDelegateMac::handleWheelEvent):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::deferWheelEventTestCompletionForReason const):
(WebCore::ScrollingTreeScrollingNodeDelegateMac::removeWheelEventTestCompletionDeferralForReason const):

LayoutTests:

Remove expectation for compositing/fixed-with-main-thread-scrolling.html.

* platform/mac-wk2/TestExpectations:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (251261 => 251262)


--- trunk/LayoutTests/ChangeLog	2019-10-17 22:05:24 UTC (rev 251261)
+++ trunk/LayoutTests/ChangeLog	2019-10-17 22:15:09 UTC (rev 251262)
@@ -1,3 +1,14 @@
+2019-10-17  Simon Fraser  <simon.fra...@apple.com>
+
+        [ Mojave+ ] Layout Test compositing/fixed-with-main-thread-scrolling.html is a flaky timeout
+        https://bugs.webkit.org/show_bug.cgi?id=198757
+
+        Reviewed by Tim Horton.
+        
+        Remove expectation for compositing/fixed-with-main-thread-scrolling.html.
+
+        * platform/mac-wk2/TestExpectations:
+
 2019-10-17  Sihui Liu  <sihui_...@apple.com>
 
         Using version 1 CFRunloopSource for faster task dispatch

Modified: trunk/LayoutTests/platform/mac-wk2/TestExpectations (251261 => 251262)


--- trunk/LayoutTests/platform/mac-wk2/TestExpectations	2019-10-17 22:05:24 UTC (rev 251261)
+++ trunk/LayoutTests/platform/mac-wk2/TestExpectations	2019-10-17 22:15:09 UTC (rev 251262)
@@ -916,8 +916,6 @@
 
 webkit.org/b/198663 http/tests/storageAccess/request-and-grant-access-then-navigate-same-site-should-have-access.html [ Pass Timeout ]
 
-webkit.org/b/198757 [ Mojave+ ] compositing/fixed-with-main-thread-scrolling.html [ Pass Timeout ]
-
 webkit.org/b/198774 imported/w3c/web-platform-tests/websockets/bufferedAmount-unchanged-by-sync-xhr.any.worker.html [ Failure ]
 
 webkit.org/b/176030 [ Debug ] http/tests/websocket/tests/hybi/send-object-tostring-check.html [ Pass Failure ]

Modified: trunk/Source/WebCore/ChangeLog (251261 => 251262)


--- trunk/Source/WebCore/ChangeLog	2019-10-17 22:05:24 UTC (rev 251261)
+++ trunk/Source/WebCore/ChangeLog	2019-10-17 22:15:09 UTC (rev 251262)
@@ -1,3 +1,44 @@
+2019-10-17  Simon Fraser  <simon.fra...@apple.com>
+
+        [ Mojave+ ] Layout Test compositing/fixed-with-main-thread-scrolling.html is a flaky timeout
+        https://bugs.webkit.org/show_bug.cgi?id=198757
+
+        Reviewed by Tim Horton.
+        
+        WheelEventTestMonitor depends on "deferral reasons" getting added and removed, such that there is always
+        at least one reason active until scrolling quiesces.
+
+        WheelEventTestMonitor made the incorrect assumption that every call into ScrollingTreeScrollingNodeDelegateMac::handleWheelEvent()
+        would result in a scroll change making it to the main thread, so it would defer "ScrollingThreadSyncNeeded" there,
+        and rely on AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll() to remove that deferral reason.
+        That assumption is wrong, because wheel events may coalesce, or have no impact on scroll position if already scrolled
+        to the max/min extent (e.g. when rubber banding).
+        
+        Fix by adding a new "HandlingWheelEvent" deferral reason for the duration that the scrolling thread is processing an wheel event,
+        and then having ScrollingThreadSyncNeeded just represent the phase where any resulting scroll is being sent to the UI process.
+        These phases should always overlap.
+        
+        This required moving isMonitoringWheelEvents() from the root scrolling node to the ScrollingTree.
+
+        * page/WheelEventTestMonitor.cpp:
+        (WebCore::operator<<):
+        * page/WheelEventTestMonitor.h:
+        * page/scrolling/AsyncScrollingCoordinator.cpp:
+        (WebCore::AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll):
+        * page/scrolling/ScrollingTree.cpp:
+        (WebCore::ScrollingTree::commitTreeState):
+        * page/scrolling/ScrollingTree.h:
+        (WebCore::ScrollingTree::isMonitoringWheelEvents const):
+        * page/scrolling/ScrollingTreeScrollingNode.cpp:
+        (WebCore::ScrollingTreeScrollingNode::commitStateBeforeChildren):
+        * page/scrolling/ScrollingTreeScrollingNode.h:
+        * page/scrolling/ThreadedScrollingTree.cpp:
+        (WebCore::ThreadedScrollingTree::scrollingTreeNodeDidScroll):
+        * page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm:
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::handleWheelEvent):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::deferWheelEventTestCompletionForReason const):
+        (WebCore::ScrollingTreeScrollingNodeDelegateMac::removeWheelEventTestCompletionDeferralForReason const):
+
 2019-10-17  Ryosuke Niwa  <rn...@webkit.org>
 
         Make requestIdleCallback suspendable

Modified: trunk/Source/WebCore/page/WheelEventTestMonitor.cpp (251261 => 251262)


--- trunk/Source/WebCore/page/WheelEventTestMonitor.cpp	2019-10-17 22:05:24 UTC (rev 251261)
+++ trunk/Source/WebCore/page/WheelEventTestMonitor.cpp	2019-10-17 22:15:09 UTC (rev 251262)
@@ -105,6 +105,7 @@
 TextStream& operator<<(TextStream& ts, WheelEventTestMonitor::DeferReason reason)
 {
     switch (reason) {
+    case WheelEventTestMonitor::HandlingWheelEvent: ts << "handling wheel event"; break;
     case WheelEventTestMonitor::RubberbandInProgress: ts << "rubberbanding"; break;
     case WheelEventTestMonitor::ScrollSnapInProgress: ts << "scroll-snapping"; break;
     case WheelEventTestMonitor::ScrollingThreadSyncNeeded: ts << "scrolling thread sync needed"; break;

Modified: trunk/Source/WebCore/page/WheelEventTestMonitor.h (251261 => 251262)


--- trunk/Source/WebCore/page/WheelEventTestMonitor.h	2019-10-17 22:05:24 UTC (rev 251261)
+++ trunk/Source/WebCore/page/WheelEventTestMonitor.h	2019-10-17 22:15:09 UTC (rev 251262)
@@ -47,10 +47,11 @@
     WEBCORE_EXPORT void clearAllTestDeferrals();
     
     enum DeferReason {
-        RubberbandInProgress        = 1 << 0,
-        ScrollSnapInProgress        = 1 << 1,
-        ScrollingThreadSyncNeeded   = 1 << 2,
-        ContentScrollInProgress     = 1 << 3
+        HandlingWheelEvent          = 1 << 0,
+        RubberbandInProgress        = 1 << 1,
+        ScrollSnapInProgress        = 1 << 2,
+        ScrollingThreadSyncNeeded   = 1 << 3,
+        ContentScrollInProgress     = 1 << 4,
     };
     typedef const void* ScrollableAreaIdentifier;
 

Modified: trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp (251261 => 251262)


--- trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp	2019-10-17 22:05:24 UTC (rev 251261)
+++ trunk/Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp	2019-10-17 22:15:09 UTC (rev 251262)
@@ -350,15 +350,6 @@
 
     if (scrollingNodeID == frameView.scrollingNodeID()) {
         reconcileScrollingState(frameView, scrollPosition, layoutViewportOrigin, scrollType, ViewportRectStability::Stable, scrollingLayerPositionAction);
-
-#if PLATFORM(COCOA)
-        if (m_page->isMonitoringWheelEvents()) {
-            frameView.scrollAnimator().setWheelEventTestMonitor(m_page->wheelEventTestMonitor());
-            if (const auto& monitor = m_page->wheelEventTestMonitor())
-                monitor->removeDeferralForReason(reinterpret_cast<WheelEventTestMonitor::ScrollableAreaIdentifier>(scrollingNodeID), WheelEventTestMonitor::ScrollingThreadSyncNeeded);
-        }
-#endif
-        
         return;
     }
 
@@ -371,14 +362,6 @@
 
         if (scrollingLayerPositionAction == ScrollingLayerPositionAction::Set)
             m_page->editorClient().overflowScrollPositionChanged();
-
-#if PLATFORM(COCOA)
-        if (m_page->isMonitoringWheelEvents()) {
-            frameView.scrollAnimator().setWheelEventTestMonitor(m_page->wheelEventTestMonitor());
-            if (const auto& monitor = m_page->wheelEventTestMonitor())
-                monitor->removeDeferralForReason(reinterpret_cast<WheelEventTestMonitor::ScrollableAreaIdentifier>(scrollingNodeID), WheelEventTestMonitor::ScrollingThreadSyncNeeded);
-        }
-#endif
     }
 }
 

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp (251261 => 251262)


--- trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp	2019-10-17 22:05:24 UTC (rev 251261)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp	2019-10-17 22:15:09 UTC (rev 251262)
@@ -151,7 +151,8 @@
         && (rootStateNodeChanged
             || rootNode->hasChangedProperty(ScrollingStateFrameScrollingNode::EventTrackingRegion)
             || rootNode->hasChangedProperty(ScrollingStateScrollingNode::ScrolledContentsLayer)
-            || rootNode->hasChangedProperty(ScrollingStateFrameScrollingNode::AsyncFrameOrOverflowScrollingEnabled))) {
+            || rootNode->hasChangedProperty(ScrollingStateFrameScrollingNode::AsyncFrameOrOverflowScrollingEnabled)
+            || rootNode->hasChangedProperty(ScrollingStateFrameScrollingNode::IsMonitoringWheelEvents))) {
         LockHolder lock(m_treeStateMutex);
 
         if (rootStateNodeChanged || rootNode->hasChangedProperty(ScrollingStateScrollingNode::ScrolledContentsLayer))
@@ -162,6 +163,9 @@
 
         if (rootStateNodeChanged || rootNode->hasChangedProperty(ScrollingStateFrameScrollingNode::AsyncFrameOrOverflowScrollingEnabled))
             m_asyncFrameOrOverflowScrollingEnabled = scrollingStateTree->rootStateNode()->asyncFrameOrOverflowScrollingEnabled();
+
+        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.

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.h (251261 => 251262)


--- trunk/Source/WebCore/page/scrolling/ScrollingTree.h	2019-10-17 22:05:24 UTC (rev 251261)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.h	2019-10-17 22:15:09 UTC (rev 251262)
@@ -158,6 +158,8 @@
 
     WEBCORE_EXPORT String scrollingTreeAsText(ScrollingStateTreeAsTextBehavior = ScrollingStateTreeAsTextBehaviorNormal);
 
+    bool isMonitoringWheelEvents() const { return m_isMonitoringWheelEvents; }
+
 protected:
     void setMainFrameScrollPosition(FloatPoint);
 
@@ -211,6 +213,7 @@
 
     unsigned m_fixedOrStickyNodeCount { 0 };
     bool m_isHandlingProgrammaticScroll { false };
+    bool m_isMonitoringWheelEvents { false };
     bool m_scrollingPerformanceLoggingEnabled { false };
     bool m_asyncFrameOrOverflowScrollingEnabled { false };
     bool m_wasScrolledByDelegatedScrollingSincePreviousCommit { false };

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp (251261 => 251262)


--- trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp	2019-10-17 22:05:24 UTC (rev 251261)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.cpp	2019-10-17 22:15:09 UTC (rev 251262)
@@ -97,9 +97,6 @@
     if (state.hasChangedProperty(ScrollingStateScrollingNode::ScrollableAreaParams))
         m_scrollableAreaParameters = state.scrollableAreaParameters();
 
-    if (state.hasChangedProperty(ScrollingStateScrollingNode::IsMonitoringWheelEvents))
-        m_isMonitoringWheelEvents = state.isMonitoringWheelEvents();
-
     if (state.hasChangedProperty(ScrollingStateScrollingNode::ScrollContainerLayer))
         m_scrollContainerLayer = state.scrollContainerLayer();
 

Modified: trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h (251261 => 251262)


--- trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h	2019-10-17 22:05:24 UTC (rev 251261)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTreeScrollingNode.h	2019-10-17 22:15:09 UTC (rev 251262)
@@ -126,8 +126,6 @@
     bool hasEnabledHorizontalScrollbar() const { return m_scrollableAreaParameters.hasEnabledHorizontalScrollbar; }
     bool hasEnabledVerticalScrollbar() const { return m_scrollableAreaParameters.hasEnabledVerticalScrollbar; }
 
-    bool isMonitoringWheelEvents() const { return m_isMonitoringWheelEvents; }
-
     LayoutPoint parentToLocalPoint(LayoutPoint) const override;
     LayoutPoint localToContentsPoint(LayoutPoint) const override;
 
@@ -148,7 +146,6 @@
     unsigned m_currentVerticalSnapPointIndex { 0 };
 #endif
     ScrollableAreaParameters m_scrollableAreaParameters;
-    bool m_isMonitoringWheelEvents { false };
     bool m_isFirstCommit { true };
 
     LayerRepresentation m_scrollContainerLayer;

Modified: trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp (251261 => 251262)


--- trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp	2019-10-17 22:05:24 UTC (rev 251261)
+++ trunk/Source/WebCore/page/scrolling/ThreadedScrollingTree.cpp	2019-10-17 22:15:09 UTC (rev 251262)
@@ -110,8 +110,20 @@
     if (is<ScrollingTreeFrameScrollingNode>(node))
         layoutViewportOrigin = downcast<ScrollingTreeFrameScrollingNode>(node).layoutViewport().location();
 
-    RunLoop::main().dispatch([scrollingCoordinator = m_scrollingCoordinator, nodeID = node.scrollingNodeID(), scrollPosition, layoutViewportOrigin, scrollingLayerPositionAction] {
+    bool monitoringWheelEvents = false;
+#if PLATFORM(MAC)
+    monitoringWheelEvents = isMonitoringWheelEvents();
+    if (monitoringWheelEvents)
+        deferWheelEventTestCompletionForReason(reinterpret_cast<WheelEventTestMonitor::ScrollableAreaIdentifier>(node.scrollingNodeID()), WheelEventTestMonitor::ScrollingThreadSyncNeeded);
+#endif
+    RunLoop::main().dispatch([scrollingCoordinator = m_scrollingCoordinator, nodeID = node.scrollingNodeID(), scrollPosition, layoutViewportOrigin, scrollingLayerPositionAction, monitoringWheelEvents] {
         scrollingCoordinator->scheduleUpdateScrollPositionAfterAsyncScroll(nodeID, scrollPosition, layoutViewportOrigin, scrollingLayerPositionAction);
+#if PLATFORM(MAC)
+        if (monitoringWheelEvents)
+            scrollingCoordinator->removeWheelEventTestCompletionDeferralForReason(reinterpret_cast<WheelEventTestMonitor::ScrollableAreaIdentifier>(nodeID), WheelEventTestMonitor::ScrollingThreadSyncNeeded);
+#else
+        UNUSED_PARAM(monitoringWheelEvents);
+#endif
     });
 }
 

Modified: trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm (251261 => 251262)


--- trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm	2019-10-17 22:05:24 UTC (rev 251261)
+++ trunk/Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeDelegateMac.mm	2019-10-17 22:15:09 UTC (rev 251262)
@@ -90,15 +90,18 @@
     }
 
 #if ENABLE(CSS_SCROLL_SNAP) || ENABLE(RUBBER_BANDING)
-    if (scrollingNode().isMonitoringWheelEvents()) {
-        if (scrollingTree().shouldHandleWheelEventSynchronously(wheelEvent))
-            removeWheelEventTestCompletionDeferralForReason(reinterpret_cast<WheelEventTestMonitor::ScrollableAreaIdentifier>(scrollingNode().scrollingNodeID()), WheelEventTestMonitor::ScrollingThreadSyncNeeded);
-        else
-            deferWheelEventTestCompletionForReason(reinterpret_cast<WheelEventTestMonitor::ScrollableAreaIdentifier>(scrollingNode().scrollingNodeID()), WheelEventTestMonitor::ScrollingThreadSyncNeeded);
-    }
+    if (scrollingTree().isMonitoringWheelEvents())
+        deferWheelEventTestCompletionForReason(reinterpret_cast<WheelEventTestMonitor::ScrollableAreaIdentifier>(scrollingNode().scrollingNodeID()), WheelEventTestMonitor::HandlingWheelEvent);
 #endif
 
-    return m_scrollController.handleWheelEvent(wheelEvent);
+    auto handled = m_scrollController.handleWheelEvent(wheelEvent);
+
+#if ENABLE(CSS_SCROLL_SNAP) || ENABLE(RUBBER_BANDING)
+    if (scrollingTree().isMonitoringWheelEvents())
+        removeWheelEventTestCompletionDeferralForReason(reinterpret_cast<WheelEventTestMonitor::ScrollableAreaIdentifier>(scrollingNode().scrollingNodeID()), WheelEventTestMonitor::HandlingWheelEvent);
+#endif
+
+    return handled;
 }
 
 bool ScrollingTreeScrollingNodeDelegateMac::isScrollSnapInProgress() const
@@ -301,7 +304,7 @@
 
 void ScrollingTreeScrollingNodeDelegateMac::deferWheelEventTestCompletionForReason(WheelEventTestMonitor::ScrollableAreaIdentifier identifier, WheelEventTestMonitor::DeferReason reason) const
 {
-    if (!scrollingNode().isMonitoringWheelEvents())
+    if (!scrollingTree().isMonitoringWheelEvents())
         return;
 
     LOG_WITH_STREAM(WheelEventTestMonitor, stream << isMainThread() << "  ScrollingTreeScrollingNodeDelegateMac::deferForReason: STARTING deferral for " << identifier << " because of " << reason);
@@ -310,7 +313,7 @@
     
 void ScrollingTreeScrollingNodeDelegateMac::removeWheelEventTestCompletionDeferralForReason(WheelEventTestMonitor::ScrollableAreaIdentifier identifier, WheelEventTestMonitor::DeferReason reason) const
 {
-    if (!scrollingNode().isMonitoringWheelEvents())
+    if (!scrollingTree().isMonitoringWheelEvents())
         return;
     
     LOG_WITH_STREAM(WheelEventTestMonitor, stream << isMainThread() << "  ScrollingTreeScrollingNodeDelegateMac::deferForReason: ENDING deferral for " << identifier << " because of " << reason);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to