<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[283068] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/283068">283068</a></dd>
<dt>Author</dt> <dd>simon.fraser@apple.com</dd>
<dt>Date</dt> <dd>2021-09-24 16:49:29 -0700 (Fri, 24 Sep 2021)</dd>
</dl>

<h3>Log Message</h3>
<pre>Have ScrollingEffectsController drive all the ScrollAnimations
https://bugs.webkit.org/show_bug.cgi?id=230739

Reviewed by Tim Horton.

Instead of each ScrollAnimation subclass having its own timer code, have them all
implement serviceAnimations(), so that ScrollingEffectsController can then drive
them all via its existing animationCallback() code.

Give ScrollingTreeScrollingNodeDelegateNicosia a temporary timer to drive its animations,
but leave FIXME comments noting that these animations should move into ScrollingEffectsCoordinator.

Push a bit more common ScrollAnimation logic into the base class, and add a
'willStart' client function which ScrollingEffectsController can use to
start callbacks if necessary.

ScrollAnimation lifetime is controlled by ScrollingEffectsController; an animation
will be deleted in the first animationCallback() where it is no longer active. This
avoids potential pitfalls where an animation might be deleted inside the scrollAnimationDidEnd()
callback.

* platform/PlatformWheelEvent.h:
(WebCore::PlatformWheelEvent::swipeVelocity const):
* platform/ScrollAnimation.h:
(WebCore::ScrollAnimationClient::scrollAnimationWillStart):
(WebCore::ScrollAnimation::stop):
(WebCore::ScrollAnimation::isActive const):
(WebCore::ScrollAnimation::currentOffset const):
(WebCore::ScrollAnimation::didStart):
(WebCore::ScrollAnimation::didEnd):
(WebCore::ScrollAnimation::timeSinceStart const):
(WebCore::ScrollAnimation::serviceAnimation): Deleted.
* platform/ScrollAnimationKinetic.cpp:
(WebCore::ScrollAnimationKinetic::PerAxisData::animateScroll):
(WebCore::ScrollAnimationKinetic::ScrollAnimationKinetic):
(WebCore::ScrollAnimationKinetic::computeVelocity):
(WebCore::ScrollAnimationKinetic::startAnimatedScrollWithInitialVelocity):
(WebCore::ScrollAnimationKinetic::serviceAnimation):
(WebCore::ScrollAnimationKinetic::stop): Deleted.
(WebCore::ScrollAnimationKinetic::isActive const): Deleted.
(WebCore::ScrollAnimationKinetic::animationTimerFired): Deleted.
(WebCore::ScrollAnimationKinetic::deltaToNextFrame): Deleted.
* platform/ScrollAnimationKinetic.h:
* platform/ScrollAnimationMomentum.cpp:
(WebCore::ScrollAnimationMomentum::startAnimatedScrollWithInitialVelocity):
(WebCore::ScrollAnimationMomentum::retargetActiveAnimation):
(WebCore::ScrollAnimationMomentum::stop):
(WebCore::ScrollAnimationMomentum::serviceAnimation):
(WebCore::ScrollAnimationMomentum::updateScrollExtents):
(WebCore::ScrollAnimationMomentum::isActive const): Deleted.
* platform/ScrollAnimationMomentum.h:
* platform/ScrollAnimationSmooth.cpp:
(WebCore::ScrollAnimationSmooth::ScrollAnimationSmooth):
(WebCore::ScrollAnimationSmooth::startOrRetargetAnimation):
(WebCore::ScrollAnimationSmooth::serviceAnimation):
(WebCore::ScrollAnimationSmooth::stop): Deleted.
(WebCore::ScrollAnimationSmooth::animationTimerFired): Deleted.
(WebCore::ScrollAnimationSmooth::startNextTimer): Deleted.
(WebCore::ScrollAnimationSmooth::isActive const): Deleted.
* platform/ScrollAnimationSmooth.h:
* platform/ScrollingEffectsController.cpp:
(WebCore::ScrollingEffectsController::animationCallback):
(WebCore::ScrollingEffectsController::startOrStopAnimationCallbacks):
(WebCore::ScrollingEffectsController::startAnimatedScrollToDestination):
(WebCore::ScrollingEffectsController::scrollAnimationWillStart):
(WebCore::ScrollingEffectsController::scrollAnimationDidEnd):
(WebCore::ScrollingEffectsController::updateScrollSnapAnimatingState): Deleted.
* platform/ScrollingEffectsController.h:
* platform/mac/ScrollingEffectsController.mm:
(WebCore::ScrollingEffectsController::processWheelEventForScrollSnap): If transitionToGlideAnimationState()
starts an animation we have to call startScrollSnapAnimation() (because the previous stop() will have
puts us in a "not animating scroll snap" state).
(WebCore::ScrollingEffectsController::updateScrollSnapAnimatingState): Deleted.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorepagescrollingnicosiaScrollingTreeScrollingNodeDelegateNicosiacpp">trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.cpp</a></li>
<li><a href="#trunkSourceWebCorepagescrollingnicosiaScrollingTreeScrollingNodeDelegateNicosiah">trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.h</a></li>
<li><a href="#trunkSourceWebCoreplatformPlatformWheelEventh">trunk/Source/WebCore/platform/PlatformWheelEvent.h</a></li>
<li><a href="#trunkSourceWebCoreplatformScrollAnimationh">trunk/Source/WebCore/platform/ScrollAnimation.h</a></li>
<li><a href="#trunkSourceWebCoreplatformScrollAnimationKineticcpp">trunk/Source/WebCore/platform/ScrollAnimationKinetic.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformScrollAnimationKinetich">trunk/Source/WebCore/platform/ScrollAnimationKinetic.h</a></li>
<li><a href="#trunkSourceWebCoreplatformScrollAnimationMomentumcpp">trunk/Source/WebCore/platform/ScrollAnimationMomentum.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformScrollAnimationMomentumh">trunk/Source/WebCore/platform/ScrollAnimationMomentum.h</a></li>
<li><a href="#trunkSourceWebCoreplatformScrollAnimationSmoothcpp">trunk/Source/WebCore/platform/ScrollAnimationSmooth.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformScrollAnimationSmoothh">trunk/Source/WebCore/platform/ScrollAnimationSmooth.h</a></li>
<li><a href="#trunkSourceWebCoreplatformScrollingEffectsControllercpp">trunk/Source/WebCore/platform/ScrollingEffectsController.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformScrollingEffectsControllerh">trunk/Source/WebCore/platform/ScrollingEffectsController.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmacScrollingEffectsControllermm">trunk/Source/WebCore/platform/mac/ScrollingEffectsController.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (283067 => 283068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2021-09-24 23:17:00 UTC (rev 283067)
+++ trunk/Source/WebCore/ChangeLog      2021-09-24 23:49:29 UTC (rev 283068)
</span><span class="lines">@@ -1,3 +1,79 @@
</span><ins>+2021-09-24  Simon Fraser  <simon.fraser@apple.com>
+
+        Have ScrollingEffectsController drive all the ScrollAnimations
+        https://bugs.webkit.org/show_bug.cgi?id=230739
+
+        Reviewed by Tim Horton.
+
+        Instead of each ScrollAnimation subclass having its own timer code, have them all
+        implement serviceAnimations(), so that ScrollingEffectsController can then drive
+        them all via its existing animationCallback() code.
+
+        Give ScrollingTreeScrollingNodeDelegateNicosia a temporary timer to drive its animations,
+        but leave FIXME comments noting that these animations should move into ScrollingEffectsCoordinator.
+
+        Push a bit more common ScrollAnimation logic into the base class, and add a
+        'willStart' client function which ScrollingEffectsController can use to
+        start callbacks if necessary.
+
+        ScrollAnimation lifetime is controlled by ScrollingEffectsController; an animation
+        will be deleted in the first animationCallback() where it is no longer active. This
+        avoids potential pitfalls where an animation might be deleted inside the scrollAnimationDidEnd()
+        callback.
+
+        * platform/PlatformWheelEvent.h:
+        (WebCore::PlatformWheelEvent::swipeVelocity const):
+        * platform/ScrollAnimation.h:
+        (WebCore::ScrollAnimationClient::scrollAnimationWillStart):
+        (WebCore::ScrollAnimation::stop):
+        (WebCore::ScrollAnimation::isActive const):
+        (WebCore::ScrollAnimation::currentOffset const):
+        (WebCore::ScrollAnimation::didStart):
+        (WebCore::ScrollAnimation::didEnd):
+        (WebCore::ScrollAnimation::timeSinceStart const):
+        (WebCore::ScrollAnimation::serviceAnimation): Deleted.
+        * platform/ScrollAnimationKinetic.cpp:
+        (WebCore::ScrollAnimationKinetic::PerAxisData::animateScroll):
+        (WebCore::ScrollAnimationKinetic::ScrollAnimationKinetic):
+        (WebCore::ScrollAnimationKinetic::computeVelocity):
+        (WebCore::ScrollAnimationKinetic::startAnimatedScrollWithInitialVelocity):
+        (WebCore::ScrollAnimationKinetic::serviceAnimation):
+        (WebCore::ScrollAnimationKinetic::stop): Deleted.
+        (WebCore::ScrollAnimationKinetic::isActive const): Deleted.
+        (WebCore::ScrollAnimationKinetic::animationTimerFired): Deleted.
+        (WebCore::ScrollAnimationKinetic::deltaToNextFrame): Deleted.
+        * platform/ScrollAnimationKinetic.h:
+        * platform/ScrollAnimationMomentum.cpp:
+        (WebCore::ScrollAnimationMomentum::startAnimatedScrollWithInitialVelocity):
+        (WebCore::ScrollAnimationMomentum::retargetActiveAnimation):
+        (WebCore::ScrollAnimationMomentum::stop):
+        (WebCore::ScrollAnimationMomentum::serviceAnimation):
+        (WebCore::ScrollAnimationMomentum::updateScrollExtents):
+        (WebCore::ScrollAnimationMomentum::isActive const): Deleted.
+        * platform/ScrollAnimationMomentum.h:
+        * platform/ScrollAnimationSmooth.cpp:
+        (WebCore::ScrollAnimationSmooth::ScrollAnimationSmooth):
+        (WebCore::ScrollAnimationSmooth::startOrRetargetAnimation):
+        (WebCore::ScrollAnimationSmooth::serviceAnimation):
+        (WebCore::ScrollAnimationSmooth::stop): Deleted.
+        (WebCore::ScrollAnimationSmooth::animationTimerFired): Deleted.
+        (WebCore::ScrollAnimationSmooth::startNextTimer): Deleted.
+        (WebCore::ScrollAnimationSmooth::isActive const): Deleted.
+        * platform/ScrollAnimationSmooth.h:
+        * platform/ScrollingEffectsController.cpp:
+        (WebCore::ScrollingEffectsController::animationCallback):
+        (WebCore::ScrollingEffectsController::startOrStopAnimationCallbacks):
+        (WebCore::ScrollingEffectsController::startAnimatedScrollToDestination):
+        (WebCore::ScrollingEffectsController::scrollAnimationWillStart):
+        (WebCore::ScrollingEffectsController::scrollAnimationDidEnd):
+        (WebCore::ScrollingEffectsController::updateScrollSnapAnimatingState): Deleted.
+        * platform/ScrollingEffectsController.h:
+        * platform/mac/ScrollingEffectsController.mm:
+        (WebCore::ScrollingEffectsController::processWheelEventForScrollSnap): If transitionToGlideAnimationState()
+        starts an animation we have to call startScrollSnapAnimation() (because the previous stop() will have
+        puts us in a "not animating scroll snap" state).
+        (WebCore::ScrollingEffectsController::updateScrollSnapAnimatingState): Deleted.
+
</ins><span class="cx"> 2021-09-24  Antoine Quint  <graouts@webkit.org>
</span><span class="cx"> 
</span><span class="cx">         [Media Controls] Allow for a close button
</span></span></pre></div>
<a id="trunkSourceWebCorepagescrollingnicosiaScrollingTreeScrollingNodeDelegateNicosiacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.cpp (283067 => 283068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.cpp        2021-09-24 23:17:00 UTC (rev 283067)
+++ trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.cpp   2021-09-24 23:49:29 UTC (rev 283068)
</span><span class="lines">@@ -32,6 +32,10 @@
</span><span class="cx"> #include "NicosiaPlatformLayer.h"
</span><span class="cx"> #include "ScrollingTreeFrameScrollingNode.h"
</span><span class="cx"> 
</span><ins>+#if USE(GLIB_EVENT_LOOP)
+#include <wtf/glib/RunLoopSourcePriority.h>
+#endif
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> class ScrollAnimation;
</span><span class="cx"> class ScrollAnimationKinetic;
</span><span class="lines">@@ -39,12 +43,18 @@
</span><span class="cx"> ScrollingTreeScrollingNodeDelegateNicosia::ScrollingTreeScrollingNodeDelegateNicosia(ScrollingTreeScrollingNode& scrollingNode, bool scrollAnimatorEnabled)
</span><span class="cx">     : ScrollingTreeScrollingNodeDelegate(scrollingNode)
</span><span class="cx">     , m_scrollAnimatorEnabled(scrollAnimatorEnabled)
</span><ins>+#if ENABLE(KINETIC_SCROLLING) || ENABLE(SMOOTH_SCROLLING)
+    , m_animationTimer(RunLoop::current(), this, &ScrollingTreeScrollingNodeDelegateNicosia::animationTimerFired)
+#endif
</ins><span class="cx"> {
</span><ins>+#if ENABLE(KINETIC_SCROLLING) || ENABLE(SMOOTH_SCROLLING)
+#if USE(GLIB_EVENT_LOOP)
+    m_animationTimer.setPriority(WTF::RunLoopSourcePriority::DisplayRefreshMonitorTimer);
+#endif
+#endif    
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-ScrollingTreeScrollingNodeDelegateNicosia::~ScrollingTreeScrollingNodeDelegateNicosia()
-{
-}
</del><ins>+ScrollingTreeScrollingNodeDelegateNicosia::~ScrollingTreeScrollingNodeDelegateNicosia() = default;
</ins><span class="cx"> 
</span><span class="cx"> std::unique_ptr<Nicosia::SceneIntegration::UpdateScope> ScrollingTreeScrollingNodeDelegateNicosia::createUpdateScope()
</span><span class="cx"> {
</span><span class="lines">@@ -80,6 +90,7 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     m_kineticAnimation = makeUnique<ScrollAnimationKinetic>(*this);
</span><ins>+    startTimerIfNecessary();
</ins><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="lines">@@ -90,6 +101,7 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     m_smoothAnimation = makeUnique<ScrollAnimationSmooth>(*this);
</span><ins>+    startTimerIfNecessary();
</ins><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="lines">@@ -116,6 +128,7 @@
</span><span class="cx">     }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    // FIXME: This needs to share code with ScrollAnimator::handleWheelEvent(), perhaps by moving code into ScrollingEffectsController::handleWheelEvent().
</ins><span class="cx">     float deltaX = canHaveHorizontalScrollbar ? wheelEvent.deltaX() : 0;
</span><span class="cx">     float deltaY = canHaveVerticalScrollbar ? wheelEvent.deltaY() : 0;
</span><span class="cx">     if ((deltaX < 0 && currentScrollPosition().x() >= maximumScrollPosition().x())
</span><span class="lines">@@ -187,6 +200,9 @@
</span><span class="cx">     if (m_smoothAnimation)
</span><span class="cx">         m_smoothAnimation->stop();
</span><span class="cx"> #endif
</span><ins>+#if ENABLE(KINETIC_SCROLLING) || ENABLE(SMOOTH_SCROLLING)
+    m_animationTimer.stop();
+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> float ScrollingTreeScrollingNodeDelegateNicosia::pageScaleFactor()
</span><span class="lines">@@ -197,7 +213,7 @@
</span><span class="cx">         downcast<ScrollingTreeFrameScrollingNode>(scrollingNode()).frameScaleFactor() : 1.;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ScrollingTreeScrollingNodeDelegateNicosia::scrollAnimationDidUpdate(ScrollAnimation& animation, const FloatPoint& position)
</del><ins>+void ScrollingTreeScrollingNodeDelegateNicosia::scrollAnimationDidUpdate(ScrollAnimation& animation, const FloatPoint& offset)
</ins><span class="cx"> {
</span><span class="cx"> #if ENABLE(SMOOTH_SCROLLING)
</span><span class="cx">     if (&animation == m_kineticAnimation.get()) {
</span><span class="lines">@@ -206,7 +222,9 @@
</span><span class="cx">     }
</span><span class="cx"> #endif
</span><span class="cx">     auto updateScope = createUpdateScope();
</span><del>-    scrollingNode().scrollTo(position);
</del><ins>+
+    // FIXME: Need to convert an offset to a position.
+    scrollingNode().scrollTo(offset);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ScrollingTreeScrollingNodeDelegateNicosia::scrollAnimationDidEnd(ScrollAnimation&)
</span><span class="lines">@@ -221,6 +239,35 @@
</span><span class="cx">     };
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ScrollingTreeScrollingNodeDelegateNicosia::startTimerIfNecessary()
+{
+#if ENABLE(KINETIC_SCROLLING) || ENABLE(SMOOTH_SCROLLING)
+    if (m_animationTimer.isActive())
+        return;
+
+    static constexpr double frameRate = 60;
+    static constexpr Seconds tickTime = 1_s / frameRate;
+    
+    m_animationTimer.startRepeating(tickTime);
+#endif
+}
+
+void ScrollingTreeScrollingNodeDelegateNicosia::animationTimerFired()
+{
+#if ENABLE(KINETIC_SCROLLING) || ENABLE(SMOOTH_SCROLLING)
+    auto now = MonotonicTime::now();
+#endif
+
+#if ENABLE(KINETIC_SCROLLING)
+    if (m_kineticAnimation)
+        m_kineticAnimation->serviceAnimation(now);
+#endif
+#if ENABLE(SMOOTH_SCROLLING)
+    if (m_smoothAnimation)
+        m_smoothAnimation->serviceAnimation(now);
+#endif    
+}
+
</ins><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(ASYNC_SCROLLING) && USE(NICOSIA)
</span></span></pre></div>
<a id="trunkSourceWebCorepagescrollingnicosiaScrollingTreeScrollingNodeDelegateNicosiah"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.h (283067 => 283068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.h  2021-09-24 23:17:00 UTC (rev 283067)
+++ trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.h     2021-09-24 23:49:29 UTC (rev 283068)
</span><span class="lines">@@ -43,8 +43,13 @@
</span><span class="cx"> #include "ScrollAnimationSmooth.h"
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if ENABLE(KINETIC_SCROLLING) || ENABLE(SMOOTH_SCROLLING)
+#include <wtf/RunLoop.h>
+#endif
+
</ins><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+// FIXME: This should not be a ScrollAnimationClient.
</ins><span class="cx"> class ScrollingTreeScrollingNodeDelegateNicosia : public ScrollingTreeScrollingNodeDelegate, public ScrollAnimationClient {
</span><span class="cx"> public:
</span><span class="cx">     explicit ScrollingTreeScrollingNodeDelegateNicosia(ScrollingTreeScrollingNode&, bool scrollAnimatorEnabled);
</span><span class="lines">@@ -67,11 +72,17 @@
</span><span class="cx">     void ensureScrollAnimationSmooth();
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    void animationTimerFired();
+    void startTimerIfNecessary();
+
</ins><span class="cx">     // ScrollAnimationClient
</span><span class="cx">     void scrollAnimationDidUpdate(ScrollAnimation&, const FloatPoint& currentPosition) final;
</span><span class="cx">     void scrollAnimationDidEnd(ScrollAnimation&) final;
</span><span class="cx">     ScrollExtents scrollExtentsForAnimation(ScrollAnimation&) final;
</span><span class="cx"> 
</span><ins>+    // FIXME: These animations should not live here. They need to be managed by ScrollingEffectsController,
+    // to be coordinated with other kinds of scroll animations, and be referenced by ScrollingEffectsController::m_currentAnimation.
+    
</ins><span class="cx"> #if ENABLE(KINETIC_SCROLLING)
</span><span class="cx">     std::unique_ptr<ScrollAnimationKinetic> m_kineticAnimation;
</span><span class="cx"> #endif
</span><span class="lines">@@ -78,6 +89,11 @@
</span><span class="cx"> #if ENABLE(SMOOTH_SCROLLING)
</span><span class="cx">     std::unique_ptr<ScrollAnimationSmooth> m_smoothAnimation;
</span><span class="cx"> #endif
</span><ins>+
+#if ENABLE(KINETIC_SCROLLING) || ENABLE(SMOOTH_SCROLLING)
+    // FIXME: When the above two animations are removed, this timer can be removed.
+    RunLoop::Timer<ScrollingTreeScrollingNodeDelegateNicosia> m_animationTimer;
+#endif
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformPlatformWheelEventh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/PlatformWheelEvent.h (283067 => 283068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/PlatformWheelEvent.h       2021-09-24 23:17:00 UTC (rev 283067)
+++ trunk/Source/WebCore/platform/PlatformWheelEvent.h  2021-09-24 23:49:29 UTC (rev 283068)
</span><span class="lines">@@ -173,7 +173,7 @@
</span><span class="cx"> 
</span><span class="cx">     bool isEndOfNonMomentumScroll() const;
</span><span class="cx">     bool isTransitioningToMomentumScroll() const;
</span><del>-    FloatPoint swipeVelocity() const;
</del><ins>+    FloatSize swipeVelocity() const;
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(WIN)
</span><span class="lines">@@ -262,10 +262,10 @@
</span><span class="cx">     return m_phase == PlatformWheelEventPhase::None && m_momentumPhase == PlatformWheelEventPhase::Began;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline FloatPoint PlatformWheelEvent::swipeVelocity() const
</del><ins>+inline FloatSize PlatformWheelEvent::swipeVelocity() const
</ins><span class="cx"> {
</span><span class="cx">     // The swiping velocity is stored in the deltas of the event declaring it.
</span><del>-    return isTransitioningToMomentumScroll() ? FloatPoint(m_wheelTicksX, m_wheelTicksY) : FloatPoint();
</del><ins>+    return isTransitioningToMomentumScroll() ? FloatSize(m_wheelTicksX, m_wheelTicksY) : FloatSize();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(KINETIC_SCROLLING)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformScrollAnimationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ScrollAnimation.h (283067 => 283068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ScrollAnimation.h  2021-09-24 23:17:00 UTC (rev 283067)
+++ trunk/Source/WebCore/platform/ScrollAnimation.h     2021-09-24 23:49:29 UTC (rev 283068)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> 
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><ins>+#include "FloatPoint.h"
</ins><span class="cx"> #include "ScrollTypes.h"
</span><span class="cx"> #include <wtf/FastMalloc.h>
</span><span class="cx"> #include <wtf/MonotonicTime.h>
</span><span class="lines">@@ -40,6 +41,7 @@
</span><span class="cx">     virtual ~ScrollAnimationClient() = default;
</span><span class="cx"> 
</span><span class="cx">     virtual void scrollAnimationDidUpdate(ScrollAnimation&, const FloatPoint& /* currentOffset */) { }
</span><ins>+    virtual void scrollAnimationWillStart(ScrollAnimation&) { }
</ins><span class="cx">     virtual void scrollAnimationDidEnd(ScrollAnimation&) { }
</span><span class="cx">     virtual ScrollExtents scrollExtentsForAnimation(ScrollAnimation&) = 0;
</span><span class="cx"> };
</span><span class="lines">@@ -62,16 +64,43 @@
</span><span class="cx">     Type type() const { return m_animationType; }
</span><span class="cx"> 
</span><span class="cx">     virtual bool retargetActiveAnimation(const FloatPoint& newDestinationOffset) = 0;
</span><del>-    virtual void stop() = 0;
-    virtual bool isActive() const = 0;
</del><ins>+    virtual void stop()
+    {
+        if (!m_isActive)
+            return;
+        didEnd();
+    }
+    virtual bool isActive() const { return m_isActive; }
</ins><span class="cx">     virtual void updateScrollExtents() { };
</span><span class="cx">     
</span><del>-    // Returns current offset.
-    virtual FloatPoint serviceAnimation(MonotonicTime) { return { }; };
</del><ins>+    FloatPoint currentOffset() const { return m_currentOffset; }
+    
+    virtual void serviceAnimation(MonotonicTime) = 0;
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><ins>+    void didStart(MonotonicTime currentTime)
+    {
+        m_startTime = currentTime;
+        m_isActive = true;
+        m_client.scrollAnimationWillStart(*this);
+    }
+    
+    void didEnd()
+    {
+        m_isActive = false;
+        m_client.scrollAnimationDidEnd(*this);
+    }
+    
+    Seconds timeSinceStart(MonotonicTime currentTime) const
+    {
+        return currentTime - m_startTime;
+    }
+
</ins><span class="cx">     ScrollAnimationClient& m_client;
</span><span class="cx">     const Type m_animationType;
</span><ins>+    bool m_isActive { false };
+    MonotonicTime m_startTime;
+    FloatPoint m_currentOffset;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformScrollAnimationKineticcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ScrollAnimationKinetic.cpp (283067 => 283068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ScrollAnimationKinetic.cpp 2021-09-24 23:17:00 UTC (rev 283067)
+++ trunk/Source/WebCore/platform/ScrollAnimationKinetic.cpp    2021-09-24 23:49:29 UTC (rev 283068)
</span><span class="lines">@@ -29,10 +29,6 @@
</span><span class="cx"> 
</span><span class="cx"> #include "PlatformWheelEvent.h"
</span><span class="cx"> 
</span><del>-#if USE(GLIB_EVENT_LOOP)
-#include <wtf/glib/RunLoopSourcePriority.h>
-#endif
-
</del><span class="cx"> /*
</span><span class="cx">  * PerAxisData is a port of GtkKineticScrolling as of GTK+ 3.20,
</span><span class="cx">  * mimicking its API and its behavior.
</span><span class="lines">@@ -67,12 +63,9 @@
</span><span class="cx">  */
</span><span class="cx"> 
</span><span class="cx"> static constexpr double decelFriction = 4;
</span><del>-static constexpr double frameRate = 60;
</del><span class="cx"> static constexpr double velocityAccumulationFloor = 0.33;
</span><span class="cx"> static constexpr double velocityAccumulationCeil = 1.0;
</span><span class="cx"> static constexpr double velocityAccumulationMax = 6.0;
</span><del>-static constexpr Seconds tickTime = 1_s / frameRate;
-static constexpr Seconds minimumTimerInterval { 1_ms };
</del><span class="cx"> static constexpr Seconds scrollCaptureThreshold { 150_ms };
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -87,11 +80,11 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool ScrollAnimationKinetic::PerAxisData::animateScroll(Seconds timeDelta)
</del><ins>+bool ScrollAnimationKinetic::PerAxisData::animateScroll(Seconds elapsedTime)
</ins><span class="cx"> {
</span><span class="cx">     auto lastOffset = m_offset;
</span><span class="cx">     auto lastTime = m_elapsedTime;
</span><del>-    m_elapsedTime += timeDelta;
</del><ins>+    m_elapsedTime = elapsedTime;
</ins><span class="cx"> 
</span><span class="cx">     double exponentialPart = exp(-decelFriction * m_elapsedTime.value());
</span><span class="cx">     m_offset = m_coef1 + m_coef2 * exponentialPart;
</span><span class="lines">@@ -105,7 +98,7 @@
</span><span class="cx">         m_offset = m_upper;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (fabs(m_velocity) < 1 || (lastTime && fabs(m_offset - lastOffset) < 1)) {
</del><ins>+    if (fabs(m_velocity) < 1 || (lastTime > 0_s && fabs(m_offset - lastOffset) < 1)) {
</ins><span class="cx">         m_offset = round(m_offset);
</span><span class="cx">         m_velocity = 0;
</span><span class="cx">     }
</span><span class="lines">@@ -115,25 +108,11 @@
</span><span class="cx"> 
</span><span class="cx"> ScrollAnimationKinetic::ScrollAnimationKinetic(ScrollAnimationClient& client)
</span><span class="cx">     : ScrollAnimation(Type::Kinetic, client)
</span><del>-    , m_animationTimer(RunLoop::current(), this, &ScrollAnimationKinetic::animationTimerFired)
</del><span class="cx"> {
</span><del>-#if USE(GLIB_EVENT_LOOP)
-    m_animationTimer.setPriority(WTF::RunLoopSourcePriority::DisplayRefreshMonitorTimer);
-#endif
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> ScrollAnimationKinetic::~ScrollAnimationKinetic() = default;
</span><span class="cx"> 
</span><del>-void ScrollAnimationKinetic::stop()
-{
-    m_animationTimer.stop();
-}
-
-bool ScrollAnimationKinetic::isActive() const
-{
-    return m_animationTimer.isActive();
-}
-
</del><span class="cx"> void ScrollAnimationKinetic::appendToScrollHistory(const PlatformWheelEvent& event)
</span><span class="cx"> {
</span><span class="cx">     m_scrollHistory.removeAllMatching([&event] (PlatformWheelEvent& otherEvent) -> bool {
</span><span class="lines">@@ -148,7 +127,7 @@
</span><span class="cx">     m_scrollHistory.clear();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-FloatPoint ScrollAnimationKinetic::computeVelocity()
</del><ins>+FloatSize ScrollAnimationKinetic::computeVelocity()
</ins><span class="cx"> {
</span><span class="cx">     if (m_scrollHistory.isEmpty())
</span><span class="cx">         return { };
</span><span class="lines">@@ -166,25 +145,24 @@
</span><span class="cx">     // FIXME: It's odd that computeVelocity() has the side effect of clearing history.
</span><span class="cx">     m_scrollHistory.clear();
</span><span class="cx"> 
</span><del>-    return FloatPoint(accumDelta.x() * -1 / (last - first).value(), accumDelta.y() * -1 / (last - first).value());
</del><ins>+    return FloatSize(accumDelta.x() * -1 / (last - first).value(), accumDelta.y() * -1 / (last - first).value());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool ScrollAnimationKinetic::startAnimatedScrollWithInitialVelocity(const FloatPoint& initialOffset, const FloatPoint& velocity, bool mayHScroll, bool mayVScroll)
</del><ins>+bool ScrollAnimationKinetic::startAnimatedScrollWithInitialVelocity(const FloatPoint& initialOffset, const FloatSize& velocity, bool mayHScroll, bool mayVScroll)
</ins><span class="cx"> {
</span><span class="cx">     stop();
</span><span class="cx"> 
</span><del>-    if (!velocity.x() && !velocity.y()) {
-        m_offset = initialOffset;
</del><ins>+    if (velocity.isZero()) {
</ins><span class="cx">         m_horizontalData = std::nullopt;
</span><span class="cx">         m_verticalData = std::nullopt;
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    auto delta = deltaToNextFrame();
</del><ins>+    auto elapsedTime = 0_s;
</ins><span class="cx">     auto extents = m_client.scrollExtentsForAnimation(*this);
</span><span class="cx"> 
</span><span class="cx">     auto accumulateVelocity = [&](double velocity, std::optional<PerAxisData> axisData) -> double {
</span><del>-        if (axisData && axisData.value().animateScroll(delta)) {
</del><ins>+        if (axisData && axisData.value().animateScroll(elapsedTime)) {
</ins><span class="cx">             double lastVelocity = axisData.value().velocity();
</span><span class="cx">             if ((std::signbit(lastVelocity) == std::signbit(velocity))
</span><span class="cx">                 && (std::abs(velocity) >= std::abs(lastVelocity * velocityAccumulationFloor))) {
</span><span class="lines">@@ -201,7 +179,7 @@
</span><span class="cx">     if (mayHScroll) {
</span><span class="cx">         m_horizontalData = PerAxisData(extents.minimumScrollOffset().x(),
</span><span class="cx">             extents.maximumScrollOffset().x(),
</span><del>-            initialOffset.x(), accumulateVelocity(velocity.x(), m_horizontalData));
</del><ins>+            initialOffset.x(), accumulateVelocity(velocity.width(), m_horizontalData));
</ins><span class="cx">     } else
</span><span class="cx">         m_horizontalData = std::nullopt;
</span><span class="cx"> 
</span><span class="lines">@@ -208,13 +186,12 @@
</span><span class="cx">     if (mayVScroll) {
</span><span class="cx">         m_verticalData = PerAxisData(extents.minimumScrollOffset().y(),
</span><span class="cx">             extents.maximumScrollOffset().y(),
</span><del>-            initialOffset.y(), accumulateVelocity(velocity.y(), m_verticalData));
</del><ins>+            initialOffset.y(), accumulateVelocity(velocity.height(), m_verticalData));
</ins><span class="cx">     } else
</span><span class="cx">         m_verticalData = std::nullopt;
</span><span class="cx"> 
</span><del>-    m_offset = initialOffset;
-    m_startTime = MonotonicTime::now() - tickTime / 2.;
-    animationTimerFired();
</del><ins>+    m_currentOffset = initialOffset;
+    didStart(MonotonicTime::now());
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -227,30 +204,23 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ScrollAnimationKinetic::animationTimerFired()
</del><ins>+void ScrollAnimationKinetic::serviceAnimation(MonotonicTime currentTime)
</ins><span class="cx"> {
</span><del>-    auto delta = deltaToNextFrame();
</del><ins>+    auto elapsedTime = timeSinceStart(currentTime);
</ins><span class="cx"> 
</span><del>-    if (m_horizontalData && !m_horizontalData.value().animateScroll(delta))
</del><ins>+    if (m_horizontalData && !m_horizontalData.value().animateScroll(elapsedTime))
</ins><span class="cx">         m_horizontalData = std::nullopt;
</span><span class="cx"> 
</span><del>-    if (m_verticalData && !m_verticalData.value().animateScroll(delta))
</del><ins>+    if (m_verticalData && !m_verticalData.value().animateScroll(elapsedTime))
</ins><span class="cx">         m_verticalData = std::nullopt;
</span><span class="cx"> 
</span><del>-    // If one of the axes didn't finish its animation we must continue it.
-    if (m_horizontalData || m_verticalData)
-        m_animationTimer.startOneShot(std::max(minimumTimerInterval, delta));
</del><ins>+    double x = m_horizontalData ? m_horizontalData.value().offset() : m_currentOffset.x();
+    double y = m_verticalData ? m_verticalData.value().offset() : m_currentOffset.y();
+    m_currentOffset = FloatPoint(x, y);
+    m_client.scrollAnimationDidUpdate(*this, m_currentOffset);
</ins><span class="cx"> 
</span><del>-    double x = m_horizontalData ? m_horizontalData.value().offset() : m_offset.x();
-    double y = m_verticalData ? m_verticalData.value().offset() : m_offset.y();
-    m_offset = FloatPoint(x, y);
-    m_client.scrollAnimationDidUpdate(*this, m_offset);
</del><ins>+    if (!m_horizontalData && !m_verticalData)
+        didEnd();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-Seconds ScrollAnimationKinetic::deltaToNextFrame()
-{
-    MonotonicTime currentTime = MonotonicTime::now();
-    return 1_s * ceil((currentTime - m_startTime).value() * frameRate) / frameRate - (currentTime - m_startTime);
-}
-
</del><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformScrollAnimationKinetich"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ScrollAnimationKinetic.h (283067 => 283068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ScrollAnimationKinetic.h   2021-09-24 23:17:00 UTC (rev 283067)
+++ trunk/Source/WebCore/platform/ScrollAnimationKinetic.h      2021-09-24 23:49:29 UTC (rev 283068)
</span><span class="lines">@@ -28,7 +28,6 @@
</span><span class="cx"> 
</span><span class="cx"> #include "FloatPoint.h"
</span><span class="cx"> #include "ScrollAnimation.h"
</span><del>-#include <wtf/RunLoop.h>
</del><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -61,28 +60,21 @@
</span><span class="cx">     ScrollAnimationKinetic(ScrollAnimationClient&);
</span><span class="cx">     virtual ~ScrollAnimationKinetic();
</span><span class="cx"> 
</span><del>-    // FIXME: Velocity should be a FloatSize.
-    bool startAnimatedScrollWithInitialVelocity(const FloatPoint& initialOffset, const FloatPoint& velocity, bool mayHScroll, bool mayVScroll);
-
</del><ins>+    bool startAnimatedScrollWithInitialVelocity(const FloatPoint& initialOffset, const FloatSize& velocity, bool mayHScroll, bool mayVScroll);
</ins><span class="cx">     bool retargetActiveAnimation(const FloatPoint& newOffset) final;
</span><del>-    void stop() final;
-    bool isActive() const final;
</del><span class="cx"> 
</span><ins>+    // FIXME: only public for ScrollingTreeScrollingNodeDelegateNicosia.
+    void serviceAnimation(MonotonicTime) final;
+
</ins><span class="cx">     void appendToScrollHistory(const PlatformWheelEvent&);
</span><span class="cx">     void clearScrollHistory();
</span><span class="cx"> 
</span><del>-    FloatPoint computeVelocity();
</del><ins>+    FloatSize computeVelocity();
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    void animationTimerFired();
-    Seconds deltaToNextFrame();
-
</del><span class="cx">     std::optional<PerAxisData> m_horizontalData;
</span><span class="cx">     std::optional<PerAxisData> m_verticalData;
</span><span class="cx"> 
</span><del>-    MonotonicTime m_startTime;
-    RunLoop::Timer<ScrollAnimationKinetic> m_animationTimer;
-    FloatPoint m_offset;
</del><span class="cx">     Vector<PlatformWheelEvent> m_scrollHistory;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformScrollAnimationMomentumcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ScrollAnimationMomentum.cpp (283067 => 283068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ScrollAnimationMomentum.cpp        2021-09-24 23:17:00 UTC (rev 283067)
+++ trunk/Source/WebCore/platform/ScrollAnimationMomentum.cpp   2021-09-24 23:49:29 UTC (rev 283068)
</span><span class="lines">@@ -27,7 +27,6 @@
</span><span class="cx"> 
</span><span class="cx"> #include "Logging.h"
</span><span class="cx"> #include "ScrollingMomentumCalculator.h"
</span><del>-#include <wtf/text/TextStream.h>
</del><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="lines">@@ -52,23 +51,25 @@
</span><span class="cx"> 
</span><span class="cx">     if (predictedScrollOffset == initialOffset) {
</span><span class="cx">         m_momentumCalculator = nullptr;
</span><del>-        m_animationComplete = true;
</del><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    m_startTime = MonotonicTime::now();
-    m_animationComplete = false;
</del><ins>+    didStart(MonotonicTime::now());
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool ScrollAnimationMomentum::retargetActiveAnimation(const FloatPoint& newDestination)
</span><span class="cx"> {
</span><del>-    if (m_momentumCalculator) {
</del><ins>+    if (m_momentumCalculator && isActive()) {
</ins><span class="cx">         m_momentumCalculator->setRetargetedScrollOffset(newDestination);
</span><span class="cx">         auto newDuration = m_momentumCalculator->animationDuration();
</span><del>-        m_animationComplete = newDuration > 0_s;
-        return !m_animationComplete;
</del><ins>+        bool animationComplete = newDuration > 0_s;
+        if (animationComplete)
+            didEnd();
+
+        return !animationComplete;
</ins><span class="cx">     }
</span><ins>+
</ins><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -75,32 +76,24 @@
</span><span class="cx"> void ScrollAnimationMomentum::stop()
</span><span class="cx"> {
</span><span class="cx">     m_momentumCalculator = nullptr;
</span><del>-    m_animationComplete = true;
-    m_client.scrollAnimationDidEnd(*this);
</del><ins>+    ScrollAnimation::stop();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool ScrollAnimationMomentum::isActive() const
</del><ins>+void ScrollAnimationMomentum::serviceAnimation(MonotonicTime currentTime)
</ins><span class="cx"> {
</span><del>-    return !m_animationComplete;
-}
-
-FloatPoint ScrollAnimationMomentum::serviceAnimation(MonotonicTime currentTime)
-{
</del><span class="cx">     if (!m_momentumCalculator) {
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><del>-        return { };
</del><ins>+        return;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    auto elapsedTime = currentTime - m_startTime;
-    m_animationComplete = elapsedTime >= m_momentumCalculator->animationDuration();
</del><ins>+    auto elapsedTime = timeSinceStart(currentTime);
+    bool animationComplete = elapsedTime >= m_momentumCalculator->animationDuration();
</ins><span class="cx">     auto newOffset = m_momentumCalculator->scrollOffsetAfterElapsedTime(elapsedTime);
</span><span class="cx"> 
</span><span class="cx">     m_client.scrollAnimationDidUpdate(*this, newOffset);
</span><span class="cx"> 
</span><del>-    if (m_animationComplete)
-        m_client.scrollAnimationDidEnd(*this);
-    
-    return newOffset;
</del><ins>+    if (animationComplete)
+        didEnd();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ScrollAnimationMomentum::updateScrollExtents()
</span><span class="lines">@@ -108,11 +101,8 @@
</span><span class="cx">     auto extents = m_client.scrollExtentsForAnimation(*this);
</span><span class="cx">     auto predictedScrollOffset = m_momentumCalculator->predictedDestinationOffset();
</span><span class="cx">     auto constrainedOffset = predictedScrollOffset.constrainedBetween(extents.minimumScrollOffset(), extents.maximumScrollOffset());
</span><del>-    if (constrainedOffset != predictedScrollOffset) {
</del><ins>+    if (constrainedOffset != predictedScrollOffset)
</ins><span class="cx">         retargetActiveAnimation(constrainedOffset);
</span><del>-        if (m_animationComplete)
-            m_client.scrollAnimationDidEnd(*this);
-    }
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformScrollAnimationMomentumh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ScrollAnimationMomentum.h (283067 => 283068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ScrollAnimationMomentum.h  2021-09-24 23:17:00 UTC (rev 283067)
+++ trunk/Source/WebCore/platform/ScrollAnimationMomentum.h     2021-09-24 23:49:29 UTC (rev 283068)
</span><span class="lines">@@ -36,18 +36,13 @@
</span><span class="cx">     virtual ~ScrollAnimationMomentum();
</span><span class="cx"> 
</span><span class="cx">     bool startAnimatedScrollWithInitialVelocity(const FloatPoint& initialOffset, const FloatSize& initialVelocity, const FloatSize& initialDelta, const WTF::Function<FloatPoint(const FloatPoint&)>& destinationModifier);
</span><del>-
</del><span class="cx">     bool retargetActiveAnimation(const FloatPoint& newDestination) final;
</span><span class="cx">     void stop() final;
</span><del>-    bool isActive() const final;
-    FloatPoint serviceAnimation(MonotonicTime) final;
</del><ins>+    void serviceAnimation(MonotonicTime) final;
</ins><span class="cx">     void updateScrollExtents() final;
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     std::unique_ptr<ScrollingMomentumCalculator> m_momentumCalculator;
</span><del>-    
-    MonotonicTime m_startTime;
-    bool m_animationComplete { false };
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformScrollAnimationSmoothcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ScrollAnimationSmooth.cpp (283067 => 283068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ScrollAnimationSmooth.cpp  2021-09-24 23:17:00 UTC (rev 283067)
+++ trunk/Source/WebCore/platform/ScrollAnimationSmooth.cpp     2021-09-24 23:49:29 UTC (rev 283068)
</span><span class="lines">@@ -33,25 +33,15 @@
</span><span class="cx"> #include "ScrollableArea.h"
</span><span class="cx"> #include "TimingFunction.h"
</span><span class="cx"> 
</span><del>-#if USE(GLIB_EVENT_LOOP)
-#include <wtf/glib/RunLoopSourcePriority.h>
-#endif
-
</del><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-static const double frameRate = 60;
</del><span class="cx"> static const float animationSpeed { 1000.0f };
</span><del>-static constexpr Seconds minimumTimerInterval { 1_ms };
</del><span class="cx"> static const Seconds maxAnimationDuration { 200_ms };
</span><span class="cx"> 
</span><span class="cx"> ScrollAnimationSmooth::ScrollAnimationSmooth(ScrollAnimationClient& client)
</span><span class="cx">     : ScrollAnimation(Type::Smooth, client)
</span><del>-    , m_animationTimer(RunLoop::current(), this, &ScrollAnimationSmooth::animationTimerFired)
</del><span class="cx">     , m_easeInOutTimingFunction(CubicBezierTimingFunction::create(CubicBezierTimingFunction::TimingFunctionPreset::EaseInOut))
</span><span class="cx"> {
</span><del>-#if USE(GLIB_EVENT_LOOP)
-    m_animationTimer.setPriority(WTF::RunLoopSourcePriority::DisplayRefreshMonitorTimer);
-#endif
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> ScrollAnimationSmooth::~ScrollAnimationSmooth() = default;
</span><span class="lines">@@ -79,19 +69,12 @@
</span><span class="cx">     m_destinationOffset = destinationOffset.constrainedBetween(extents.minimumScrollOffset(), extents.maximumScrollOffset());
</span><span class="cx">     bool needToScroll = m_startOffset != m_destinationOffset;
</span><span class="cx"> 
</span><del>-    if (needToScroll && !isActive()) {
-        m_startTime = MonotonicTime::now();
-        animationTimerFired();
-    }
</del><ins>+    if (needToScroll && !isActive())
+        didStart(MonotonicTime::now());
+
</ins><span class="cx">     return needToScroll;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ScrollAnimationSmooth::stop()
-{
-    m_animationTimer.stop();
-    m_client.scrollAnimationDidEnd(*this);
-}
-
</del><span class="cx"> void ScrollAnimationSmooth::updateScrollExtents()
</span><span class="cx"> {
</span><span class="cx">     auto extents = m_client.scrollExtentsForAnimation(*this);
</span><span class="lines">@@ -110,6 +93,14 @@
</span><span class="cx">     return a + progress * (b - a);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ScrollAnimationSmooth::serviceAnimation(MonotonicTime currentTime)
+{
+    bool animationActive = animateScroll(currentTime);
+    m_client.scrollAnimationDidUpdate(*this, m_currentOffset);
+    if (!animationActive)
+        didEnd();
+}
+
</ins><span class="cx"> bool ScrollAnimationSmooth::animateScroll(MonotonicTime currentTime)
</span><span class="cx"> {
</span><span class="cx">     MonotonicTime endTime = m_startTime + m_duration;
</span><span class="lines">@@ -126,29 +117,4 @@
</span><span class="cx">     return currentTime < endTime;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ScrollAnimationSmooth::animationTimerFired()
-{
-    MonotonicTime currentTime = MonotonicTime::now();
-    Seconds deltaToNextFrame = 1_s * ceil((currentTime - m_startTime).value() * frameRate) / frameRate - (currentTime - m_startTime);
-    currentTime += deltaToNextFrame;
-
-    bool continueAnimation = animateScroll(currentTime);
-    if (continueAnimation)
-        startNextTimer(std::max(minimumTimerInterval, deltaToNextFrame));
-
-    m_client.scrollAnimationDidUpdate(*this, m_currentOffset);
-    if (!continueAnimation)
-        m_client.scrollAnimationDidEnd(*this);
-}
-
-void ScrollAnimationSmooth::startNextTimer(Seconds delay)
-{
-    m_animationTimer.startOneShot(delay);
-}
-
-bool ScrollAnimationSmooth::isActive() const
-{
-    return m_animationTimer.isActive();
-}
-
</del><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformScrollAnimationSmoothh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ScrollAnimationSmooth.h (283067 => 283068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ScrollAnimationSmooth.h    2021-09-24 23:17:00 UTC (rev 283067)
+++ trunk/Source/WebCore/platform/ScrollAnimationSmooth.h       2021-09-24 23:49:29 UTC (rev 283068)
</span><span class="lines">@@ -28,8 +28,6 @@
</span><span class="cx"> 
</span><span class="cx"> #include "ScrollAnimation.h"
</span><span class="cx"> 
</span><del>-#include <wtf/RunLoop.h>
-
</del><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class FloatPoint;
</span><span class="lines">@@ -41,33 +39,25 @@
</span><span class="cx">     virtual ~ScrollAnimationSmooth();
</span><span class="cx"> 
</span><span class="cx">     bool startAnimatedScrollToDestination(const FloatPoint& fromOffset, const FloatPoint& destinationOffset);
</span><ins>+    bool retargetActiveAnimation(const FloatPoint& newOffset) final;
</ins><span class="cx"> 
</span><del>-    bool retargetActiveAnimation(const FloatPoint& newOffset) final;
-    void stop() final;
</del><ins>+    // FIXME: only public for ScrollingTreeScrollingNodeDelegateNicosia.
</ins><span class="cx">     void updateScrollExtents() final;
</span><del>-    bool isActive() const final;
</del><ins>+    void serviceAnimation(MonotonicTime) final;
</ins><span class="cx"> 
</span><ins>+private:
</ins><span class="cx"> 
</span><del>-private:
</del><span class="cx">     bool startOrRetargetAnimation(const ScrollExtents&, const FloatPoint& destinationOffset);
</span><del>-
-    void requestAnimationTimerFired();
-    void startNextTimer(Seconds delay);
-    void animationTimerFired();
</del><span class="cx">     
</span><span class="cx">     Seconds durationFromDistance(const FloatSize&) const;
</span><span class="cx">     
</span><span class="cx">     bool animateScroll(MonotonicTime);
</span><span class="cx"> 
</span><del>-    MonotonicTime m_startTime;
</del><span class="cx">     Seconds m_duration;
</span><span class="cx"> 
</span><span class="cx">     FloatPoint m_startOffset;
</span><span class="cx">     FloatPoint m_destinationOffset;
</span><del>-    FloatPoint m_currentOffset;
-    
-    // FIXME: Should not have timer here, and instead use serviceAnimation().
-    RunLoop::Timer<ScrollAnimationSmooth> m_animationTimer;
</del><ins>+
</ins><span class="cx">     RefPtr<TimingFunction> m_easeInOutTimingFunction;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformScrollingEffectsControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ScrollingEffectsController.cpp (283067 => 283068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ScrollingEffectsController.cpp     2021-09-24 23:17:00 UTC (rev 283067)
+++ trunk/Source/WebCore/platform/ScrollingEffectsController.cpp        2021-09-24 23:49:29 UTC (rev 283068)
</span><span class="lines">@@ -48,14 +48,23 @@
</span><span class="cx"> {
</span><span class="cx">     LOG_WITH_STREAM(Scrolling, stream << "ScrollingEffectsController " << this << " animationCallback: isAnimatingRubberBand " << m_isAnimatingRubberBand << " isAnimatingScrollSnap " << m_isAnimatingScrollSnap << "isAnimatingKeyboardScrolling" << m_isAnimatingKeyboardScrolling);
</span><span class="cx"> 
</span><del>-    updateScrollSnapAnimatingState(currentTime);
</del><ins>+    if (m_currentAnimation) {
+        if (m_currentAnimation->isActive())
+            m_currentAnimation->serviceAnimation(currentTime);
+
+        if (m_currentAnimation && !m_currentAnimation->isActive())
+            m_currentAnimation = nullptr;
+    }
+
</ins><span class="cx">     updateRubberBandAnimatingState(currentTime);
</span><span class="cx">     updateKeyboardScrollingAnimatingState(currentTime);
</span><ins>+    
+    startOrStopAnimationCallbacks();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ScrollingEffectsController::startOrStopAnimationCallbacks()
</span><span class="cx"> {
</span><del>-    bool needsCallbacks = m_isAnimatingRubberBand || m_isAnimatingScrollSnap || m_isAnimatingKeyboardScrolling;
</del><ins>+    bool needsCallbacks = m_isAnimatingRubberBand || m_isAnimatingKeyboardScrolling || m_currentAnimation;
</ins><span class="cx">     if (needsCallbacks == m_isRunningAnimatingCallback)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -84,6 +93,8 @@
</span><span class="cx">     if (m_currentAnimation)
</span><span class="cx">         m_currentAnimation->stop();
</span><span class="cx"> 
</span><ins>+    // We always create and attempt to start the animation. If it turns out to not need animating, then the animation
+    // remains inactive, and we'll remove it on the next animationCallback().
</ins><span class="cx">     m_currentAnimation = makeUnique<ScrollAnimationSmooth>(*this);
</span><span class="cx">     return downcast<ScrollAnimationSmooth>(*m_currentAnimation).startAnimatedScrollToDestination(startOffset, destinationOffset);
</span><span class="cx"> }
</span><span class="lines">@@ -254,6 +265,35 @@
</span><span class="cx">         m_activeScrollSnapIndexDidChange = true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ScrollingEffectsController::startScrollSnapAnimation()
+{
+    if (m_isAnimatingScrollSnap)
+        return;
+
+    LOG_WITH_STREAM(ScrollSnap, stream << "ScrollingEffectsController " << this << " startScrollSnapAnimation (main thread " << isMainThread() << ")");
+
+#if PLATFORM(MAC)
+    startDeferringWheelEventTestCompletionDueToScrollSnapping();
+#endif
+    m_client.willStartScrollSnapAnimation();
+    setIsAnimatingScrollSnap(true);
+}
+
+void ScrollingEffectsController::stopScrollSnapAnimation()
+{
+    if (!m_isAnimatingScrollSnap)
+        return;
+
+    LOG_WITH_STREAM(ScrollSnap, stream << "ScrollingEffectsController " << this << " stopScrollSnapAnimation (main thread " << isMainThread() << ")");
+
+#if PLATFORM(MAC)
+    stopDeferringWheelEventTestCompletionDueToScrollSnapping();
+#endif
+    m_client.didStopScrollSnapAnimation();
+
+    setIsAnimatingScrollSnap(false);
+}
+
</ins><span class="cx"> void ScrollingEffectsController::updateKeyboardScrollingAnimatingState(MonotonicTime currentTime)
</span><span class="cx"> {
</span><span class="cx">     if (!m_isAnimatingKeyboardScrolling)
</span><span class="lines">@@ -274,9 +314,20 @@
</span><span class="cx">     scrollToOffsetForAnimation(currentOffset);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ScrollingEffectsController::scrollAnimationWillStart(ScrollAnimation&)
+{
+    startOrStopAnimationCallbacks();
+}
+
</ins><span class="cx"> void ScrollingEffectsController::scrollAnimationDidEnd(ScrollAnimation&)
</span><span class="cx"> {
</span><ins>+    if (usesScrollSnap() && m_isAnimatingScrollSnap) {
+        m_scrollSnapState->transitionToDestinationReachedState();
+        stopScrollSnapAnimation();
+    }
+
</ins><span class="cx">     m_client.setScrollBehaviorStatus(ScrollBehaviorStatus::NotInAnimation);
</span><ins>+    startOrStopAnimationCallbacks();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> ScrollExtents ScrollingEffectsController::scrollExtentsForAnimation(ScrollAnimation&)
</span><span class="lines">@@ -299,14 +350,8 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ScrollingEffectsController::updateScrollSnapAnimatingState(MonotonicTime)
-{
-
-}
-
</del><span class="cx"> void ScrollingEffectsController::updateRubberBandAnimatingState(MonotonicTime)
</span><span class="cx"> {
</span><del>-
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #endif // PLATFORM(MAC)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformScrollingEffectsControllerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ScrollingEffectsController.h (283067 => 283068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ScrollingEffectsController.h       2021-09-24 23:17:00 UTC (rev 283067)
+++ trunk/Source/WebCore/platform/ScrollingEffectsController.h  2021-09-24 23:49:29 UTC (rev 283068)
</span><span class="lines">@@ -183,7 +183,6 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    void updateScrollSnapAnimatingState(MonotonicTime);
</del><span class="cx">     void updateRubberBandAnimatingState(MonotonicTime);
</span><span class="cx">     void updateKeyboardScrollingAnimatingState(MonotonicTime);
</span><span class="cx"> 
</span><span class="lines">@@ -191,10 +190,10 @@
</span><span class="cx">     void setIsAnimatingScrollSnap(bool);
</span><span class="cx">     void setIsAnimatingKeyboardScrolling(bool);
</span><span class="cx"> 
</span><del>-#if PLATFORM(MAC)
</del><span class="cx">     void startScrollSnapAnimation();
</span><span class="cx">     void stopScrollSnapAnimation();
</span><span class="cx"> 
</span><ins>+#if PLATFORM(MAC)
</ins><span class="cx">     bool shouldOverrideMomentumScrolling() const;
</span><span class="cx">     void statelessSnapTransitionTimerFired();
</span><span class="cx">     void scheduleStatelessScrollSnap();
</span><span class="lines">@@ -217,6 +216,7 @@
</span><span class="cx"> 
</span><span class="cx">     // ScrollAnimationClient
</span><span class="cx">     void scrollAnimationDidUpdate(ScrollAnimation&, const FloatPoint& /* currentOffset */) final;
</span><ins>+    void scrollAnimationWillStart(ScrollAnimation&) final;
</ins><span class="cx">     void scrollAnimationDidEnd(ScrollAnimation&) final;
</span><span class="cx">     ScrollExtents scrollExtentsForAnimation(ScrollAnimation&)  final;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmacScrollingEffectsControllermm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mac/ScrollingEffectsController.mm (283067 => 283068)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/mac/ScrollingEffectsController.mm  2021-09-24 23:17:00 UTC (rev 283067)
+++ trunk/Source/WebCore/platform/mac/ScrollingEffectsController.mm     2021-09-24 23:49:29 UTC (rev 283068)
</span><span class="lines">@@ -690,8 +690,10 @@
</span><span class="cx">             startScrollSnapAnimation();
</span><span class="cx">         break;
</span><span class="cx">     case WheelEventStatus::MomentumScrollBegin:
</span><del>-        if (m_scrollSnapState->transitionToGlideAnimationState(m_client.scrollExtents(), m_client.pageScaleFactor(), m_client.scrollOffset(), m_dragEndedScrollingVelocity, FloatSize(-wheelEvent.deltaX(), -wheelEvent.deltaY())))
</del><ins>+        if (m_scrollSnapState->transitionToGlideAnimationState(m_client.scrollExtents(), m_client.pageScaleFactor(), m_client.scrollOffset(), m_dragEndedScrollingVelocity, FloatSize(-wheelEvent.deltaX(), -wheelEvent.deltaY()))) {
+            startScrollSnapAnimation();
</ins><span class="cx">             isMomentumScrolling = true;
</span><ins>+        }
</ins><span class="cx">         m_dragEndedScrollingVelocity = { };
</span><span class="cx">         break;
</span><span class="cx">     case WheelEventStatus::MomentumScrolling:
</span><span class="lines">@@ -720,62 +722,6 @@
</span><span class="cx">     updateRubberBandingState();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ScrollingEffectsController::startScrollSnapAnimation()
-{
-    if (m_isAnimatingScrollSnap)
-        return;
-
-    LOG_WITH_STREAM(ScrollSnap, stream << "ScrollingEffectsController " << this << " startScrollSnapAnimation (main thread " << isMainThread() << ")");
-
-    startDeferringWheelEventTestCompletionDueToScrollSnapping();
-    m_client.willStartScrollSnapAnimation();
-    setIsAnimatingScrollSnap(true);
-}
-
-void ScrollingEffectsController::stopScrollSnapAnimation()
-{
-    if (!m_isAnimatingScrollSnap)
-        return;
-
-    LOG_WITH_STREAM(ScrollSnap, stream << "ScrollingEffectsController " << this << " stopScrollSnapAnimation (main thread " << isMainThread() << ")");
-
-    stopDeferringWheelEventTestCompletionDueToScrollSnapping();
-    m_client.didStopScrollSnapAnimation();
-
-    setIsAnimatingScrollSnap(false);
-}
-
-void ScrollingEffectsController::updateScrollSnapAnimatingState(MonotonicTime currentTime)
-{
-    if (!m_isAnimatingScrollSnap)
-        return;
-
-    if (!usesScrollSnap()) {
-        ASSERT_NOT_REACHED();
-        return;
-    }
-
-    if (!is<ScrollAnimationMomentum>(m_currentAnimation.get())) {
-        m_scrollSnapState->transitionToDestinationReachedState();
-        stopScrollSnapAnimation();
-        return;
-    }
-
-    auto& momentumScrollAnimation = downcast<ScrollAnimationMomentum>(*m_currentAnimation);
-
-    auto animationOffset = momentumScrollAnimation.serviceAnimation(currentTime);
-    bool isAnimationComplete = !momentumScrollAnimation.isActive();
-
-    LOG_WITH_STREAM(ScrollSnap, stream << "ScrollingEffectsController " << this << " updateScrollSnapAnimatingState - isAnimationComplete " << isAnimationComplete << " animationOffset " << animationOffset << " (main thread " << isMainThread() << ")");
-
-    scrollToOffsetForAnimation(animationOffset);
-
-    if (isAnimationComplete) {
-        m_scrollSnapState->transitionToDestinationReachedState();
-        stopScrollSnapAnimation();
-    }
-}
-
</del><span class="cx"> } // namespace WebCore
</span><span class="cx"> 
</span><span class="cx"> #endif // PLATFORM(MAC)
</span></span></pre>
</div>
</div>

</body>
</html>