Title: [282697] trunk/Source/WebCore
Revision
282697
Author
[email protected]
Date
2021-09-17 14:43:47 -0700 (Fri, 17 Sep 2021)

Log Message

Make ScrollAnimation a little more generic
https://bugs.webkit.org/show_bug.cgi?id=230385

Reviewed by Tim Horton.

Prepare for new ScrollAnimation subclasses by making it a little more generic. Rather
than the function callbacks, use a virtual client class, implemented by ScrollAnimator
and ScrollingTreeScrollingNodeDelegateNicosia. Remove the generic 'scroll' methods
from the base class, since they only apply to ScrollAnimationSmooth (clients need
to keep derived class pointers, and most already do).

Remove ambiguity around the currentPosition by requiring it for every 'start' call.
Remove ambiguity around setCurrentPosition() by removing it. Clients just call stop().
Remove ambiguity around retargeting by making it explicit.

Do per-axis setup when starting animations, not when creating one, so the animation starts
out stateless.

* Sources.txt: Build platform/ScrollAnimationKinetic.cpp for macOS, mostly to catch
build errors (it's currently unused).
* WebCore.xcodeproj/project.pbxproj:
* page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.cpp:
(WebCore::ScrollingTreeScrollingNodeDelegateNicosia::resetCurrentPosition):
(WebCore::ScrollingTreeScrollingNodeDelegateNicosia::ensureScrollAnimationKinetic):
(WebCore::ScrollingTreeScrollingNodeDelegateNicosia::ensureScrollAnimationSmooth):
(WebCore::ScrollingTreeScrollingNodeDelegateNicosia::handleWheelEvent):
(WebCore::ScrollingTreeScrollingNodeDelegateNicosia::scrollAnimationDidUpdate):
(WebCore::ScrollingTreeScrollingNodeDelegateNicosia::scrollAnimationDidEnd):
(WebCore::ScrollingTreeScrollingNodeDelegateNicosia::scrollExtentsForAnimation):
* page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.h:
* platform/ScrollAnimation.h:
(WebCore::ScrollAnimation::ScrollAnimation):
(WebCore::ScrollAnimation::updateScrollExtents):
(WebCore::ScrollAnimation::serviceAnimation):
(WebCore::ScrollAnimation::~ScrollAnimation): Deleted.
(WebCore::ScrollAnimation::scroll): Deleted.
(WebCore::ScrollAnimation::updateVisibleLengths): Deleted.
(WebCore::ScrollAnimation::setCurrentPosition): Deleted.
* platform/ScrollAnimationKinetic.cpp:
(WebCore::ScrollAnimationKinetic::ScrollAnimationKinetic):
(WebCore::ScrollAnimationKinetic::startAnimatedScrollWithInitialVelocity):
(WebCore::ScrollAnimationKinetic::animationTimerFired):
(WebCore::ScrollAnimationKinetic::start): Deleted.
* platform/ScrollAnimationKinetic.h:
* platform/ScrollAnimationSmooth.cpp:
(WebCore::ScrollAnimationSmooth::ScrollAnimationSmooth):
(WebCore::ScrollAnimationSmooth::startAnimatedScroll):
(WebCore::ScrollAnimationSmooth::startAnimatedScrollToDestination):
(WebCore::ScrollAnimationSmooth::stop):
(WebCore::ScrollAnimationSmooth::updateScrollExtents):
(WebCore::ScrollAnimationSmooth::initializeAxesData):
(WebCore::ScrollAnimationSmooth::animationTimerFired):
(WebCore::ScrollAnimationSmooth::PerAxisData::PerAxisData): Deleted.
(WebCore::ScrollAnimationSmooth::scroll): Deleted.
(WebCore::ScrollAnimationSmooth::updateVisibleLengths): Deleted.
(WebCore::ScrollAnimationSmooth::setCurrentPosition): Deleted.
* platform/ScrollAnimationSmooth.h: Rename some "time" variables to "duration" for clarity
* platform/ScrollAnimator.cpp:
(WebCore::ScrollAnimator::ScrollAnimator):
(WebCore::ScrollAnimator::scroll):
(WebCore::ScrollAnimator::scrollToPositionWithoutAnimation):
(WebCore::ScrollAnimator::scrollToPositionWithAnimation):
(WebCore::ScrollAnimator::retargetRunningAnimation):
(WebCore::ScrollAnimator::contentsResized const):
(WebCore::ScrollAnimator::willEndLiveResize):
(WebCore::ScrollAnimator::didAddVerticalScrollbar):
(WebCore::ScrollAnimator::didAddHorizontalScrollbar):
(WebCore::ScrollAnimator::scrollAnimationDidUpdate):
(WebCore::ScrollAnimator::scrollAnimationDidEnd):
(WebCore::ScrollAnimator::scrollExtentsForAnimation):
(): Deleted.
(WebCore::m_keyboardScrollingAnimator): Deleted.
* platform/ScrollAnimator.h:
* platform/generic/ScrollAnimatorGeneric.cpp:
(WebCore::ScrollAnimatorGeneric::ScrollAnimatorGeneric):
(WebCore::ScrollAnimatorGeneric::handleWheelEvent):
(WebCore::ScrollAnimatorGeneric::updatePosition):
(WebCore::ScrollAnimatorGeneric::scrollAnimationDidUpdate):
* platform/generic/ScrollAnimatorGeneric.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (282696 => 282697)


--- trunk/Source/WebCore/ChangeLog	2021-09-17 21:42:50 UTC (rev 282696)
+++ trunk/Source/WebCore/ChangeLog	2021-09-17 21:43:47 UTC (rev 282697)
@@ -1,3 +1,85 @@
+2021-09-17  Simon Fraser  <[email protected]>
+
+        Make ScrollAnimation a little more generic
+        https://bugs.webkit.org/show_bug.cgi?id=230385
+
+        Reviewed by Tim Horton.
+
+        Prepare for new ScrollAnimation subclasses by making it a little more generic. Rather
+        than the function callbacks, use a virtual client class, implemented by ScrollAnimator
+        and ScrollingTreeScrollingNodeDelegateNicosia. Remove the generic 'scroll' methods
+        from the base class, since they only apply to ScrollAnimationSmooth (clients need
+        to keep derived class pointers, and most already do).
+        
+        Remove ambiguity around the currentPosition by requiring it for every 'start' call.
+        Remove ambiguity around setCurrentPosition() by removing it. Clients just call stop().
+        Remove ambiguity around retargeting by making it explicit.
+        
+        Do per-axis setup when starting animations, not when creating one, so the animation starts
+        out stateless.
+
+        * Sources.txt: Build platform/ScrollAnimationKinetic.cpp for macOS, mostly to catch
+        build errors (it's currently unused).
+        * WebCore.xcodeproj/project.pbxproj:
+        * page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.cpp:
+        (WebCore::ScrollingTreeScrollingNodeDelegateNicosia::resetCurrentPosition):
+        (WebCore::ScrollingTreeScrollingNodeDelegateNicosia::ensureScrollAnimationKinetic):
+        (WebCore::ScrollingTreeScrollingNodeDelegateNicosia::ensureScrollAnimationSmooth):
+        (WebCore::ScrollingTreeScrollingNodeDelegateNicosia::handleWheelEvent):
+        (WebCore::ScrollingTreeScrollingNodeDelegateNicosia::scrollAnimationDidUpdate):
+        (WebCore::ScrollingTreeScrollingNodeDelegateNicosia::scrollAnimationDidEnd):
+        (WebCore::ScrollingTreeScrollingNodeDelegateNicosia::scrollExtentsForAnimation):
+        * page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.h:
+        * platform/ScrollAnimation.h:
+        (WebCore::ScrollAnimation::ScrollAnimation):
+        (WebCore::ScrollAnimation::updateScrollExtents):
+        (WebCore::ScrollAnimation::serviceAnimation):
+        (WebCore::ScrollAnimation::~ScrollAnimation): Deleted.
+        (WebCore::ScrollAnimation::scroll): Deleted.
+        (WebCore::ScrollAnimation::updateVisibleLengths): Deleted.
+        (WebCore::ScrollAnimation::setCurrentPosition): Deleted.
+        * platform/ScrollAnimationKinetic.cpp:
+        (WebCore::ScrollAnimationKinetic::ScrollAnimationKinetic):
+        (WebCore::ScrollAnimationKinetic::startAnimatedScrollWithInitialVelocity):
+        (WebCore::ScrollAnimationKinetic::animationTimerFired):
+        (WebCore::ScrollAnimationKinetic::start): Deleted.
+        * platform/ScrollAnimationKinetic.h:
+        * platform/ScrollAnimationSmooth.cpp:
+        (WebCore::ScrollAnimationSmooth::ScrollAnimationSmooth):
+        (WebCore::ScrollAnimationSmooth::startAnimatedScroll):
+        (WebCore::ScrollAnimationSmooth::startAnimatedScrollToDestination):
+        (WebCore::ScrollAnimationSmooth::stop):
+        (WebCore::ScrollAnimationSmooth::updateScrollExtents):
+        (WebCore::ScrollAnimationSmooth::initializeAxesData):
+        (WebCore::ScrollAnimationSmooth::animationTimerFired):
+        (WebCore::ScrollAnimationSmooth::PerAxisData::PerAxisData): Deleted.
+        (WebCore::ScrollAnimationSmooth::scroll): Deleted.
+        (WebCore::ScrollAnimationSmooth::updateVisibleLengths): Deleted.
+        (WebCore::ScrollAnimationSmooth::setCurrentPosition): Deleted.
+        * platform/ScrollAnimationSmooth.h: Rename some "time" variables to "duration" for clarity
+        * platform/ScrollAnimator.cpp:
+        (WebCore::ScrollAnimator::ScrollAnimator):
+        (WebCore::ScrollAnimator::scroll):
+        (WebCore::ScrollAnimator::scrollToPositionWithoutAnimation):
+        (WebCore::ScrollAnimator::scrollToPositionWithAnimation):
+        (WebCore::ScrollAnimator::retargetRunningAnimation):
+        (WebCore::ScrollAnimator::contentsResized const):
+        (WebCore::ScrollAnimator::willEndLiveResize):
+        (WebCore::ScrollAnimator::didAddVerticalScrollbar):
+        (WebCore::ScrollAnimator::didAddHorizontalScrollbar):
+        (WebCore::ScrollAnimator::scrollAnimationDidUpdate):
+        (WebCore::ScrollAnimator::scrollAnimationDidEnd):
+        (WebCore::ScrollAnimator::scrollExtentsForAnimation):
+        (): Deleted.
+        (WebCore::m_keyboardScrollingAnimator): Deleted.
+        * platform/ScrollAnimator.h:
+        * platform/generic/ScrollAnimatorGeneric.cpp:
+        (WebCore::ScrollAnimatorGeneric::ScrollAnimatorGeneric):
+        (WebCore::ScrollAnimatorGeneric::handleWheelEvent):
+        (WebCore::ScrollAnimatorGeneric::updatePosition):
+        (WebCore::ScrollAnimatorGeneric::scrollAnimationDidUpdate):
+        * platform/generic/ScrollAnimatorGeneric.h:
+
 2021-09-17  Cameron McCormack  <[email protected]>
 
         Preserve color space when creating ImageBuffers for ImageBitmaps

Modified: trunk/Source/WebCore/Sources.txt (282696 => 282697)


--- trunk/Source/WebCore/Sources.txt	2021-09-17 21:42:50 UTC (rev 282696)
+++ trunk/Source/WebCore/Sources.txt	2021-09-17 21:43:47 UTC (rev 282697)
@@ -1811,6 +1811,7 @@
 platform/RemoteCommandListener.cpp
 platform/RuntimeApplicationChecks.cpp
 platform/SSLKeyGenerator.cpp
+platform/ScrollAnimationKinetic.cpp
 platform/ScrollAnimationSmooth.cpp
 platform/ScrollAnimator.cpp
 platform/ScrollingEffectsController.cpp

Modified: trunk/Source/WebCore/SourcesGTK.txt (282696 => 282697)


--- trunk/Source/WebCore/SourcesGTK.txt	2021-09-17 21:42:50 UTC (rev 282696)
+++ trunk/Source/WebCore/SourcesGTK.txt	2021-09-17 21:43:47 UTC (rev 282697)
@@ -69,7 +69,6 @@
 page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.cpp
 page/scrolling/nicosia/ScrollingTreeStickyNode.cpp
 
-platform/ScrollAnimationKinetic.cpp
 platform/UserAgentQuirks.cpp
 
 platform/adwaita/ScrollbarThemeAdwaita.cpp

Modified: trunk/Source/WebCore/SourcesWPE.txt (282696 => 282697)


--- trunk/Source/WebCore/SourcesWPE.txt	2021-09-17 21:42:50 UTC (rev 282696)
+++ trunk/Source/WebCore/SourcesWPE.txt	2021-09-17 21:43:47 UTC (rev 282697)
@@ -58,7 +58,6 @@
 page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.cpp
 page/scrolling/nicosia/ScrollingTreeStickyNode.cpp
 
-platform/ScrollAnimationKinetic.cpp
 platform/UserAgentQuirks.cpp
 
 platform/adwaita/ScrollbarThemeAdwaita.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (282696 => 282697)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2021-09-17 21:42:50 UTC (rev 282696)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2021-09-17 21:43:47 UTC (rev 282697)
@@ -352,6 +352,7 @@
 		0F94F37E23661626003AA5C7 /* StyleRuleType.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F94F37C23661131003AA5C7 /* StyleRuleType.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F9DAA0F1FD1C66A0079C5B2 /* DOMGCOutputConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9DAA0E1FD1C6640079C5B2 /* DOMGCOutputConstraint.h */; };
 		0FA24D7A162DF91900A3F4C0 /* GraphicsLayerUpdater.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA24D78162DF91900A3F4C0 /* GraphicsLayerUpdater.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0FA61B0E26F43213001AADB6 /* ScrollAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FA61B0C26F43212001AADB6 /* ScrollAnimation.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0FB6252F18DE1B1500A07C05 /* GeometryUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB6252D18DE1B1500A07C05 /* GeometryUtilities.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0FB8890F167D30160010CDA5 /* ScrollingStateStickyNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FB8890D167D30160010CDA5 /* ScrollingStateStickyNode.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0FBB5FBE260991D20054572C /* DisplayRefreshMonitorFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FBB5FBD26095A9C0054572C /* DisplayRefreshMonitorFactory.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -6324,6 +6325,7 @@
 		0FA0A0E523AEAA35000EEB94 /* dialog.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = dialog.css; sourceTree = "<group>"; };
 		0FA24D77162DF91900A3F4C0 /* GraphicsLayerUpdater.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GraphicsLayerUpdater.cpp; sourceTree = "<group>"; };
 		0FA24D78162DF91900A3F4C0 /* GraphicsLayerUpdater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GraphicsLayerUpdater.h; sourceTree = "<group>"; };
+		0FA61B0C26F43212001AADB6 /* ScrollAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollAnimation.h; sourceTree = "<group>"; };
 		0FB0689425243B90001E8E75 /* DisplayTextBox.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DisplayTextBox.cpp; sourceTree = "<group>"; };
 		0FB0689625243B90001E8E75 /* DisplayTextBox.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DisplayTextBox.h; sourceTree = "<group>"; };
 		0FB6252C18DE1B1500A07C05 /* GeometryUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GeometryUtilities.cpp; sourceTree = "<group>"; };
@@ -28043,6 +28045,7 @@
 				411223B8260244FE00B0A0B6 /* ScriptExecutionContextIdentifier.h */,
 				BC8AE34C12EA096A00EB3AE6 /* ScrollableArea.cpp */,
 				BC8AE34D12EA096A00EB3AE6 /* ScrollableArea.h */,
+				0FA61B0C26F43212001AADB6 /* ScrollAnimation.h */,
 				0FC692BC257C0F410098E3F9 /* ScrollAnimationKinetic.cpp */,
 				0FC692BA257C0F400098E3F9 /* ScrollAnimationKinetic.h */,
 				0FC692BD257C0F410098E3F9 /* ScrollAnimationSmooth.cpp */,
@@ -33132,7 +33135,6 @@
 				BC6932740D7E293900AE44D1 /* JSDOMWindowBase.h in Headers */,
 				652FBBBC0DE27CB60001D386 /* JSDOMWindowCustom.h in Headers */,
 				460CBF361D4BCD0E0092E88E /* JSDOMWindowProperties.h in Headers */,
-				410BCF5626F0CD8C0040B124 /* RTCLocalSessionDescriptionInit.h in Headers */,
 				65E0E9441133C89F00B4CB10 /* JSDOMWrapper.h in Headers */,
 				7C45C9D31E3FCBD700AAB558 /* JSDOMWrapperCache.h in Headers */,
 				93A8061E1E03B585008A1F26 /* JSDoubleRange.h in Headers */,
@@ -34742,6 +34744,7 @@
 				07AB996B18DA3C010018771E /* RTCIceServer.h in Headers */,
 				313591081E7DDC7300F30630 /* RTCIceTransportPolicy.h in Headers */,
 				313591091E7DDC7300F30630 /* RTCIceTransportState.h in Headers */,
+				410BCF5626F0CD8C0040B124 /* RTCLocalSessionDescriptionInit.h in Headers */,
 				41C14BC626DE6DE800685BF5 /* RTCNetworkManager.h in Headers */,
 				073794FE19F5864E00E5A045 /* RTCNotifiersMock.h in Headers */,
 				073794DE19EE2C5200E5A045 /* RTCOfferAnswerOptions.h in Headers */,
@@ -34814,6 +34817,7 @@
 				1400D7A817136EA70077CE05 /* ScriptWrappableInlines.h in Headers */,
 				BC8AE34F12EA096A00EB3AE6 /* ScrollableArea.h in Headers */,
 				5D925B680F64D4DD00B847F0 /* ScrollAlignment.h in Headers */,
+				0FA61B0E26F43213001AADB6 /* ScrollAnimation.h in Headers */,
 				CA3BF67E10D99BAE00E6CE53 /* ScrollAnimator.h in Headers */,
 				0F1774801378B772009DA76A /* ScrollAnimatorIOS.h in Headers */,
 				BCAE1FA712939DB7004CB026 /* ScrollAnimatorMac.h in Headers */,

Modified: trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.cpp (282696 => 282697)


--- trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.cpp	2021-09-17 21:42:50 UTC (rev 282696)
+++ trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.cpp	2021-09-17 21:43:47 UTC (rev 282697)
@@ -61,7 +61,7 @@
 {
 #if ENABLE(SMOOTH_SCROLLING)
     if (m_smoothAnimation)
-        m_smoothAnimation->setCurrentPosition(scrollingNode().currentScrollPosition());
+        m_smoothAnimation->stop();
 #endif
 }
 
@@ -69,7 +69,7 @@
 {
 #if ENABLE(SMOOTH_SCROLLING)
     if (m_smoothAnimation)
-        m_smoothAnimation->updateVisibleLengths();
+        m_smoothAnimation->updateScrollExtents();
 #endif
 }
 
@@ -79,18 +79,7 @@
     if (m_kineticAnimation)
         return;
 
-    m_kineticAnimation = makeUnique<ScrollAnimationKinetic>(
-        [this]() -> ScrollExtents {
-            return { IntPoint(minimumScrollPosition()), IntPoint(maximumScrollPosition()), IntSize(scrollableAreaSize()) };
-        },
-        [this](FloatPoint&& position) {
-#if ENABLE(SMOOTH_SCROLLING)
-            if (m_smoothAnimation)
-                m_smoothAnimation->setCurrentPosition(position);
-#endif
-            auto updateScope = createUpdateScope();
-            scrollingNode().scrollTo(position);
-        });
+    m_kineticAnimation = makeUnique<ScrollAnimationKinetic>(*this);
 }
 #endif
 
@@ -100,16 +89,7 @@
     if (m_smoothAnimation)
         return;
 
-    m_smoothAnimation = makeUnique<ScrollAnimationSmooth>(
-        [this]() -> ScrollExtents {
-            return { IntPoint(minimumScrollPosition()), IntPoint(maximumScrollPosition()), IntSize(scrollableAreaSize()) };
-        },
-        currentScrollPosition(),
-        [this](FloatPoint&& position) {
-            auto updateScope = createUpdateScope();
-            scrollingNode().scrollTo(position);
-        },
-        [] { });
+    m_smoothAnimation = makeUnique<ScrollAnimationSmooth>(*this);
 }
 #endif
 
@@ -125,12 +105,12 @@
     m_kineticAnimation->appendToScrollHistory(wheelEvent);
     m_kineticAnimation->stop();
     if (wheelEvent.isEndOfNonMomentumScroll()) {
-        m_kineticAnimation->start(currentScrollPosition(), m_kineticAnimation->computeVelocity(), canHaveHorizontalScrollbar, canHaveVerticalScrollbar);
+        m_kineticAnimation->startAnimatedScrollWithInitialVelocity(currentScrollPosition(), m_kineticAnimation->computeVelocity(), canHaveHorizontalScrollbar, canHaveVerticalScrollbar);
         m_kineticAnimation->clearScrollHistory();
         return WheelEventHandlingResult::handled();
     }
     if (wheelEvent.isTransitioningToMomentumScroll()) {
-        m_kineticAnimation->start(currentScrollPosition(), wheelEvent.swipeVelocity(), canHaveHorizontalScrollbar, canHaveVerticalScrollbar);
+        m_kineticAnimation->startAnimatedScrollWithInitialVelocity(currentScrollPosition(), wheelEvent.swipeVelocity(), canHaveHorizontalScrollbar, canHaveVerticalScrollbar);
         m_kineticAnimation->clearScrollHistory();
         return WheelEventHandlingResult::handled();
     }
@@ -182,8 +162,8 @@
 #if ENABLE(SMOOTH_SCROLLING)
     if (m_scrollAnimatorEnabled && !wheelEvent.hasPreciseScrollingDeltas()) {
         ensureScrollAnimationSmooth();
-        m_smoothAnimation->scroll(HorizontalScrollbar, ScrollByPixel, 1, deltaX);
-        m_smoothAnimation->scroll(VerticalScrollbar, ScrollByPixel, 1, deltaY);
+        m_smoothAnimation->startAnimatedScroll(HorizontalScrollbar, ScrollByPixel, currentScrollPosition(), 1, deltaX);
+        m_smoothAnimation->startAnimatedScroll(VerticalScrollbar, ScrollByPixel, currentScrollPosition(), 1, deltaY);
         return WheelEventHandlingResult::handled();
     }
 #endif
@@ -216,6 +196,31 @@
         downcast<ScrollingTreeFrameScrollingNode>(scrollingNode()).frameScaleFactor() : 1.;
 }
 
+void ScrollingTreeScrollingNodeDelegateNicosia::scrollAnimationDidUpdate(ScrollAnimation& animation, const FloatPoint& position)
+{
+#if ENABLE(SMOOTH_SCROLLING)
+    if (&animation == m_kineticAnimation.get()) {
+        if (m_smoothAnimation)
+            m_smoothAnimation->stop();
+    }
+#endif
+    auto updateScope = createUpdateScope();
+    scrollingNode().scrollTo(position);
+}
+
+void ScrollingTreeScrollingNodeDelegateNicosia::scrollAnimationDidEnd(ScrollAnimation&)
+{
+}
+
+ScrollExtents ScrollingTreeScrollingNodeDelegateNicosia::scrollExtentsForAnimation(ScrollAnimation&)
+{
+    return {
+        IntPoint(minimumScrollPosition()),
+        IntPoint(maximumScrollPosition()),
+        IntSize(scrollableAreaSize())
+    };
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(ASYNC_SCROLLING) && USE(NICOSIA)

Modified: trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.h (282696 => 282697)


--- trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.h	2021-09-17 21:42:50 UTC (rev 282696)
+++ trunk/Source/WebCore/page/scrolling/nicosia/ScrollingTreeScrollingNodeDelegateNicosia.h	2021-09-17 21:43:47 UTC (rev 282697)
@@ -31,6 +31,7 @@
 #if ENABLE(ASYNC_SCROLLING) && USE(NICOSIA)
 
 #include "NicosiaPlatformLayer.h"
+#include "ScrollAnimation.h"
 #include "ScrollingStateOverflowScrollingNode.h"
 #include "ThreadedScrollingTree.h"
 
@@ -44,7 +45,7 @@
 
 namespace WebCore {
 
-class ScrollingTreeScrollingNodeDelegateNicosia : public ScrollingTreeScrollingNodeDelegate {
+class ScrollingTreeScrollingNodeDelegateNicosia : public ScrollingTreeScrollingNodeDelegate, public ScrollAnimationClient {
 public:
     explicit ScrollingTreeScrollingNodeDelegateNicosia(ScrollingTreeScrollingNode&, bool scrollAnimatorEnabled);
     virtual ~ScrollingTreeScrollingNodeDelegateNicosia();
@@ -66,11 +67,16 @@
     void ensureScrollAnimationSmooth();
 #endif
 
+    // ScrollAnimationClient
+    void scrollAnimationDidUpdate(ScrollAnimation&, const FloatPoint& currentPosition) final;
+    void scrollAnimationDidEnd(ScrollAnimation&) final;
+    ScrollExtents scrollExtentsForAnimation(ScrollAnimation&) final;
+
 #if ENABLE(KINETIC_SCROLLING)
     std::unique_ptr<ScrollAnimationKinetic> m_kineticAnimation;
 #endif
 #if ENABLE(SMOOTH_SCROLLING)
-    std::unique_ptr<ScrollAnimation> m_smoothAnimation;
+    std::unique_ptr<ScrollAnimationSmooth> m_smoothAnimation;
 #endif
 };
 

Modified: trunk/Source/WebCore/platform/ScrollAnimation.h (282696 => 282697)


--- trunk/Source/WebCore/platform/ScrollAnimation.h	2021-09-17 21:42:50 UTC (rev 282696)
+++ trunk/Source/WebCore/platform/ScrollAnimation.h	2021-09-17 21:43:47 UTC (rev 282697)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2016 Igalia S.L.
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -23,16 +24,15 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef ScrollAnimation_h
-#define ScrollAnimation_h
+#pragma once
 
 #include "ScrollTypes.h"
+#include <wtf/FastMalloc.h>
 
 namespace WebCore {
 
 class FloatPoint;
-class ScrollableArea;
-enum class ScrollClamping : bool;
+class ScrollAnimation;
 
 struct ScrollExtents {
     ScrollPosition minimumScrollPosition;
@@ -40,19 +40,33 @@
     IntSize visibleSize;
 };
 
+class ScrollAnimationClient {
+public:
+    virtual ~ScrollAnimationClient() = default;
+
+    virtual void scrollAnimationDidUpdate(ScrollAnimation&, const FloatPoint& currentPosition) = 0;
+    virtual void scrollAnimationDidEnd(ScrollAnimation&) = 0;
+    virtual ScrollExtents scrollExtentsForAnimation(ScrollAnimation&) = 0;
+};
+
 class ScrollAnimation {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    virtual ~ScrollAnimation() { };
-    virtual bool scroll(ScrollbarOrientation, ScrollGranularity, float /* step */, float /* multiplier */) { return true; };
-    virtual void scroll(const FloatPoint&) { };
+    ScrollAnimation(ScrollAnimationClient& client)
+        : m_client(client)
+    { }
+    virtual ~ScrollAnimation() = default;
+
+    virtual bool retargetActiveAnimation(const FloatPoint& newDestination) = 0;
     virtual void stop() = 0;
-    virtual void updateVisibleLengths() { };
-    virtual void setCurrentPosition(const FloatPoint&) { };
+    virtual bool isActive() const = 0;
+    virtual void updateScrollExtents() { };
+    
+    // FIXME: No-op. Need to use this instead of subclasses having timers.
     virtual void serviceAnimation() { };
-    virtual bool isActive() const = 0;
+
+protected:
+    ScrollAnimationClient& m_client;
 };
 
 } // namespace WebCore
-
-#endif // ScrollAnimation_h

Modified: trunk/Source/WebCore/platform/ScrollAnimationKinetic.cpp (282696 => 282697)


--- trunk/Source/WebCore/platform/ScrollAnimationKinetic.cpp	2021-09-17 21:42:50 UTC (rev 282696)
+++ trunk/Source/WebCore/platform/ScrollAnimationKinetic.cpp	2021-09-17 21:43:47 UTC (rev 282697)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2016 Igalia S.L.
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -112,9 +113,8 @@
     return m_velocity;
 }
 
-ScrollAnimationKinetic::ScrollAnimationKinetic(ScrollExtentsCallback&& scrollExtentsFunction, NotifyPositionChangedCallback&& notifyPositionChangedFunction)
-    : m_scrollExtentsFunction(WTFMove(scrollExtentsFunction))
-    , m_notifyPositionChangedFunction(WTFMove(notifyPositionChangedFunction))
+ScrollAnimationKinetic::ScrollAnimationKinetic(ScrollAnimationClient& client)
+    : ScrollAnimation(client)
     , m_animationTimer(RunLoop::current(), this, &ScrollAnimationKinetic::animationTimerFired)
 {
 #if USE(GLIB_EVENT_LOOP)
@@ -163,12 +163,13 @@
     for (const auto& scrollEvent : m_scrollHistory)
         accumDelta += FloatPoint(scrollEvent.deltaX(), scrollEvent.deltaY());
 
+    // FIXME: It's odd that computeVelocity() has the side effect of clearing history.
     m_scrollHistory.clear();
 
     return FloatPoint(accumDelta.x() * -1 / (last - first).value(), accumDelta.y() * -1 / (last - first).value());
 }
 
-void ScrollAnimationKinetic::start(const FloatPoint& initialPosition, const FloatPoint& velocity, bool mayHScroll, bool mayVScroll)
+bool ScrollAnimationKinetic::startAnimatedScrollWithInitialVelocity(const FloatPoint& initialPosition, const FloatPoint& velocity, bool mayHScroll, bool mayVScroll)
 {
     stop();
 
@@ -176,11 +177,11 @@
         m_position = initialPosition;
         m_horizontalData = std::nullopt;
         m_verticalData = std::nullopt;
-        return;
+        return false;
     }
 
     auto delta = deltaToNextFrame();
-    auto extents = m_scrollExtentsFunction();
+    auto extents = m_client.scrollExtentsForAnimation(*this);
 
     auto accumulateVelocity = [&](double velocity, std::optional<PerAxisData> axisData) -> double {
         if (axisData && axisData.value().animateScroll(delta)) {
@@ -214,8 +215,18 @@
     m_position = initialPosition;
     m_startTime = MonotonicTime::now() - tickTime / 2.;
     animationTimerFired();
+    return true;
 }
 
+bool ScrollAnimationKinetic::retargetActiveAnimation(const FloatPoint&)
+{
+    if (!isActive())
+        return false;
+    
+    // FIXME: Implement retargeting.
+    return false;
+}
+
 void ScrollAnimationKinetic::animationTimerFired()
 {
     auto delta = deltaToNextFrame();
@@ -233,7 +244,7 @@
     double x = m_horizontalData ? m_horizontalData.value().position() : m_position.x();
     double y = m_verticalData ? m_verticalData.value().position() : m_position.y();
     m_position = FloatPoint(x, y);
-    m_notifyPositionChangedFunction(FloatPoint(m_position));
+    m_client.scrollAnimationDidUpdate(*this, FloatPoint(m_position));
 }
 
 Seconds ScrollAnimationKinetic::deltaToNextFrame()

Modified: trunk/Source/WebCore/platform/ScrollAnimationKinetic.h (282696 => 282697)


--- trunk/Source/WebCore/platform/ScrollAnimationKinetic.h	2021-09-17 21:42:50 UTC (rev 282696)
+++ trunk/Source/WebCore/platform/ScrollAnimationKinetic.h	2021-09-17 21:43:47 UTC (rev 282697)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2016 Igalia S.L.
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -57,27 +58,24 @@
     };
 
 public:
-    using ScrollExtentsCallback = WTF::Function<ScrollExtents(void)>;
-    using NotifyPositionChangedCallback = WTF::Function<void(FloatPoint&&)>;
-
-    ScrollAnimationKinetic(ScrollExtentsCallback&&, NotifyPositionChangedCallback&&);
+    ScrollAnimationKinetic(ScrollAnimationClient&);
     virtual ~ScrollAnimationKinetic();
 
+    bool startAnimatedScrollWithInitialVelocity(const FloatPoint& initialPosition, const FloatPoint& velocity, bool mayHScroll, bool mayVScroll);
+
+    bool retargetActiveAnimation(const FloatPoint& newDestination) final;
+    void stop() final;
+    bool isActive() const final;
+
     void appendToScrollHistory(const PlatformWheelEvent&);
     void clearScrollHistory();
+
     FloatPoint computeVelocity();
 
-    void start(const FloatPoint& initialPosition, const FloatPoint& velocity, bool mayHScroll, bool mayVScroll);
-    void stop() override;
-    bool isActive() const override;
-
 private:
     void animationTimerFired();
     Seconds deltaToNextFrame();
 
-    ScrollExtentsCallback m_scrollExtentsFunction;
-    NotifyPositionChangedCallback m_notifyPositionChangedFunction;
-
     std::optional<PerAxisData> m_horizontalData;
     std::optional<PerAxisData> m_verticalData;
 

Modified: trunk/Source/WebCore/platform/ScrollAnimationSmooth.cpp (282696 => 282697)


--- trunk/Source/WebCore/platform/ScrollAnimationSmooth.cpp	2021-09-17 21:42:50 UTC (rev 282696)
+++ trunk/Source/WebCore/platform/ScrollAnimationSmooth.cpp	2021-09-17 21:43:47 UTC (rev 282697)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2016 Igalia S.L.
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2021 Apple Inc. All rights reserved.
  * Copyright (c) 2011, Google Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -42,29 +42,8 @@
 static const Seconds minimumTimerInterval { 1_ms };
 static const double smoothFactorForProgrammaticScroll = 1;
 
-ScrollAnimationSmooth::PerAxisData::PerAxisData(ScrollbarOrientation orientation, const FloatPoint& position, ScrollExtentsCallback& extentsCallback)
-{
-    auto extents = extentsCallback();
-    switch (orientation) {
-    case HorizontalScrollbar:
-        currentPosition = position.x();
-        visibleLength = extents.visibleSize.width();
-        break;
-    case VerticalScrollbar:
-        currentPosition = position.y();
-        visibleLength = extents.visibleSize.height();
-        break;
-    }
-
-    desiredPosition = currentPosition;
-}
-
-ScrollAnimationSmooth::ScrollAnimationSmooth(ScrollExtentsCallback&& scrollExtentsFunction, const FloatPoint& position, NotifyPositionChangedCallback&& notifyPositionChangedFunction, NotifyAnimationStoppedCallback&& notifyAnimationStoppedFunction)
-    : m_scrollExtentsFunction(WTFMove(scrollExtentsFunction))
-    , m_notifyPositionChangedFunction(WTFMove(notifyPositionChangedFunction))
-    , m_notifyAnimationStoppedFunction(WTFMove(notifyAnimationStoppedFunction))
-    , m_horizontalData(HorizontalScrollbar, position, m_scrollExtentsFunction)
-    , m_verticalData(VerticalScrollbar, position, m_scrollExtentsFunction)
+ScrollAnimationSmooth::ScrollAnimationSmooth(ScrollAnimationClient& client)
+    : ScrollAnimation(client)
     , m_animationTimer(RunLoop::current(), this, &ScrollAnimationSmooth::animationTimerFired)
 {
 #if USE(GLIB_EVENT_LOOP)
@@ -72,11 +51,15 @@
 #endif
 }
 
-bool ScrollAnimationSmooth::scroll(ScrollbarOrientation orientation, ScrollGranularity granularity, float step, float multiplier)
+ScrollAnimationSmooth::~ScrollAnimationSmooth() = default;
+
+bool ScrollAnimationSmooth::startAnimatedScroll(ScrollbarOrientation orientation, ScrollGranularity granularity, const FloatPoint& fromPosition, float step, float multiplier)
 {
     float minScrollPosition;
     float maxScrollPosition;
-    auto extents = m_scrollExtentsFunction();
+    auto extents = m_client.scrollExtentsForAnimation(*this);
+    initializeAxesData(extents, fromPosition);
+
     if (orientation == HorizontalScrollbar) {
         minScrollPosition = extents.minimumScrollPosition.x();
         maxScrollPosition = extents.maximumScrollPosition.x();
@@ -93,41 +76,55 @@
     return needToScroll;
 }
 
-void ScrollAnimationSmooth::scroll(const FloatPoint& position)
+bool ScrollAnimationSmooth::startAnimatedScrollToDestination(const FloatPoint& fromPosition, const FloatPoint& destinationPosition)
 {
-    ScrollGranularity granularity = ScrollByPage;
-    auto extents = m_scrollExtentsFunction();
-    bool needToScroll = updatePerAxisData(m_horizontalData, granularity, position.x(), extents.minimumScrollPosition.x(), extents.maximumScrollPosition.x(), smoothFactorForProgrammaticScroll);
+    auto extents = m_client.scrollExtentsForAnimation(*this);
+    initializeAxesData(extents, fromPosition);
+    
+    return startOrRetargetAnimation(extents, destinationPosition);
+}
+
+bool ScrollAnimationSmooth::retargetActiveAnimation(const FloatPoint& newDestination)
+{
+    if (!isActive())
+        return false;
+
+    auto extents = m_client.scrollExtentsForAnimation(*this);
+    return startOrRetargetAnimation(extents, newDestination);
+}
+
+bool ScrollAnimationSmooth::startOrRetargetAnimation(const ScrollExtents& extents, const FloatPoint& destinationPosition)
+{
+    auto granularity = ScrollByPage;
+    bool needToScroll = updatePerAxisData(m_horizontalData, granularity, destinationPosition.x(), extents.minimumScrollPosition.x(), extents.maximumScrollPosition.x(), smoothFactorForProgrammaticScroll);
     needToScroll |=
-        updatePerAxisData(m_verticalData, granularity, position.y(), extents.minimumScrollPosition.y(), extents.maximumScrollPosition.y(), smoothFactorForProgrammaticScroll);
+        updatePerAxisData(m_verticalData, granularity, destinationPosition.y(), extents.minimumScrollPosition.y(), extents.maximumScrollPosition.y(), smoothFactorForProgrammaticScroll);
     if (needToScroll && !isActive()) {
-        m_startTime = m_horizontalData.startTime;
+        m_startTime = m_verticalData.startTime;
         animationTimerFired();
     }
-};
+    return needToScroll;
+}
 
 void ScrollAnimationSmooth::stop()
 {
     m_animationTimer.stop();
-    m_notifyAnimationStoppedFunction();
+    m_client.scrollAnimationDidEnd(*this);
 }
 
-void ScrollAnimationSmooth::updateVisibleLengths()
+void ScrollAnimationSmooth::updateScrollExtents()
 {
-    auto extents = m_scrollExtentsFunction();
+    auto extents = m_client.scrollExtentsForAnimation(*this);
     m_horizontalData.visibleLength = extents.visibleSize.width();
     m_verticalData.visibleLength = extents.visibleSize.height();
 }
 
-void ScrollAnimationSmooth::setCurrentPosition(const FloatPoint& position)
+void ScrollAnimationSmooth::initializeAxesData(const ScrollExtents& extents, const FloatPoint& startPosition)
 {
-    stop();
-    m_horizontalData = PerAxisData(position.x(), m_horizontalData.visibleLength);
-    m_verticalData = PerAxisData(position.y(), m_verticalData.visibleLength);
+    m_horizontalData = PerAxisData(startPosition.x(), extents.visibleSize.width());
+    m_verticalData = PerAxisData(startPosition.y(), extents.visibleSize.height());
 }
 
-ScrollAnimationSmooth::~ScrollAnimationSmooth() = default;
-
 static inline double curveAt(ScrollAnimationSmooth::Curve curve, double t)
 {
     switch (curve) {
@@ -248,38 +245,38 @@
     return endValue - startValue;
 }
 
-static inline void getAnimationParametersForGranularity(ScrollGranularity granularity, Seconds& animationTime, Seconds& repeatMinimumSustainTime, Seconds& attackTime, Seconds& releaseTime, ScrollAnimationSmooth::Curve& coastTimeCurve, Seconds& maximumCoastTime)
+static inline void getAnimationParametersForGranularity(ScrollGranularity granularity, Seconds& animationDuration, Seconds& repeatMinimumSustainTime, Seconds& attackDuration, Seconds& releaseDuration, ScrollAnimationSmooth::Curve& coastTimeCurve, Seconds& maximumCoastTime)
 {
     switch (granularity) {
     case ScrollByDocument:
-        animationTime = tickTime * 10;
+        animationDuration = tickTime * 10;
         repeatMinimumSustainTime = tickTime * 10;
-        attackTime = tickTime * 10;
-        releaseTime = tickTime * 10;
+        attackDuration = tickTime * 10;
+        releaseDuration = tickTime * 10;
         coastTimeCurve = ScrollAnimationSmooth::Curve::Linear;
         maximumCoastTime = 1_s;
         break;
     case ScrollByLine:
-        animationTime = tickTime * 10;
+        animationDuration = tickTime * 10;
         repeatMinimumSustainTime = tickTime * 7;
-        attackTime = tickTime * 3;
-        releaseTime = tickTime * 3;
+        attackDuration = tickTime * 3;
+        releaseDuration = tickTime * 3;
         coastTimeCurve = ScrollAnimationSmooth::Curve::Linear;
         maximumCoastTime = 1_s;
         break;
     case ScrollByPage:
-        animationTime = tickTime * 15;
+        animationDuration = tickTime * 15;
         repeatMinimumSustainTime = tickTime * 10;
-        attackTime = tickTime * 5;
-        releaseTime = tickTime * 5;
+        attackDuration = tickTime * 5;
+        releaseDuration = tickTime * 5;
         coastTimeCurve = ScrollAnimationSmooth::Curve::Linear;
         maximumCoastTime = 1_s;
         break;
     case ScrollByPixel:
-        animationTime = tickTime * 11;
+        animationDuration = tickTime * 11;
         repeatMinimumSustainTime = tickTime * 2;
-        attackTime = tickTime * 3;
-        releaseTime = tickTime * 3;
+        attackDuration = tickTime * 3;
+        releaseDuration = tickTime * 3;
         coastTimeCurve = ScrollAnimationSmooth::Curve::Quadratic;
         maximumCoastTime = 1250_ms;
         break;
@@ -299,27 +296,27 @@
     if (newPosition == data.desiredPosition)
         return false;
 
-    Seconds animationTime, repeatMinimumSustainTime, attackTime, releaseTime, maximumCoastTime;
+    Seconds animationDuration, repeatMinimumSustainTime, attackDuration, releaseDuration, maximumCoastTime;
     Curve coastTimeCurve;
-    getAnimationParametersForGranularity(granularity, animationTime, repeatMinimumSustainTime, attackTime, releaseTime, coastTimeCurve, maximumCoastTime);
+    getAnimationParametersForGranularity(granularity, animationDuration, repeatMinimumSustainTime, attackDuration, releaseDuration, coastTimeCurve, maximumCoastTime);
 
-    animationTime *= smoothFactor;
+    animationDuration *= smoothFactor;
     repeatMinimumSustainTime *= smoothFactor;
-    attackTime *= smoothFactor;
-    releaseTime *= smoothFactor;
+    attackDuration *= smoothFactor;
+    releaseDuration *= smoothFactor;
     maximumCoastTime *= smoothFactor;
 
     data.desiredPosition = newPosition;
     if (!data.startTime)
-        data.attackTime = attackTime;
-    data.animationTime = animationTime;
-    data.releaseTime = releaseTime;
+        data.attackDuration = attackDuration;
+    data.animationDuration = animationDuration;
+    data.releaseDuration = releaseDuration;
 
     // Prioritize our way out of over constraint.
-    if (data.attackTime + data.releaseTime > data.animationTime) {
-        if (data.releaseTime > data.animationTime)
-            data.releaseTime = data.animationTime;
-        data.attackTime = data.animationTime - data.releaseTime;
+    if (data.attackDuration + data.releaseDuration > data.animationDuration) {
+        if (data.releaseDuration > data.animationDuration)
+            data.releaseDuration = data.animationDuration;
+        data.attackDuration = data.animationDuration - data.releaseDuration;
     }
 
     if (!data.startTime) {
@@ -333,15 +330,15 @@
     double remainingDelta = data.desiredPosition - data.currentPosition;
     double attackAreaLeft = 0;
     Seconds deltaTime = data.lastAnimationTime - data.startTime;
-    Seconds attackTimeLeft = std::max(0_s, data.attackTime - deltaTime);
-    Seconds timeLeft = data.animationTime - deltaTime;
-    Seconds minTimeLeft = data.releaseTime + std::min(repeatMinimumSustainTime, data.animationTime - data.releaseTime - attackTimeLeft);
+    Seconds attackTimeLeft = std::max(0_s, data.attackDuration - deltaTime);
+    Seconds timeLeft = data.animationDuration - deltaTime;
+    Seconds minTimeLeft = data.releaseDuration + std::min(repeatMinimumSustainTime, data.animationDuration - data.releaseDuration - attackTimeLeft);
     if (timeLeft < minTimeLeft) {
-        data.animationTime = deltaTime + minTimeLeft;
+        data.animationDuration = deltaTime + minTimeLeft;
         timeLeft = minTimeLeft;
     }
 
-    if (maximumCoastTime > (repeatMinimumSustainTime + releaseTime)) {
+    if (maximumCoastTime > (repeatMinimumSustainTime + releaseDuration)) {
         double targetMaxCoastVelocity = data.visibleLength * .25 * frameRate;
         // This needs to be as minimal as possible while not being intrusive to page up/down.
         double minCoastDelta = data.visibleLength;
@@ -354,23 +351,23 @@
             Seconds coastMinTimeLeft = std::min(maximumCoastTime, minTimeLeft + (maximumCoastTime - minTimeLeft) * coastCurve(coastTimeCurve, coastFactor));
 
             if (Seconds additionalTime = std::max(0_s, coastMinTimeLeft - minTimeLeft)) {
-                Seconds additionalReleaseTime = std::min(additionalTime, additionalTime * (releaseTime / (releaseTime + repeatMinimumSustainTime)));
-                data.releaseTime = releaseTime + additionalReleaseTime;
-                data.animationTime = deltaTime + coastMinTimeLeft;
+                Seconds additionalReleaseTime = std::min(additionalTime, additionalTime * (releaseDuration / (releaseDuration + repeatMinimumSustainTime)));
+                data.releaseDuration = releaseDuration + additionalReleaseTime;
+                data.animationDuration = deltaTime + coastMinTimeLeft;
                 timeLeft = coastMinTimeLeft;
             }
         }
     }
 
-    Seconds releaseTimeLeft = std::min(timeLeft, data.releaseTime);
+    Seconds releaseTimeLeft = std::min(timeLeft, data.releaseDuration);
     Seconds sustainTimeLeft = std::max(0_s, timeLeft - releaseTimeLeft - attackTimeLeft);
     if (attackTimeLeft) {
-        double attackSpot = deltaTime / data.attackTime;
-        attackAreaLeft = attackArea(Curve::Cubic, attackSpot, 1) * data.attackTime.value();
+        double attackSpot = deltaTime / data.attackDuration;
+        attackAreaLeft = attackArea(Curve::Cubic, attackSpot, 1) * data.attackDuration.value();
     }
 
-    double releaseSpot = (data.releaseTime - releaseTimeLeft) / data.releaseTime;
-    double releaseAreaLeft = releaseArea(Curve::Cubic, releaseSpot, 1) * data.releaseTime.value();
+    double releaseSpot = (data.releaseDuration - releaseTimeLeft) / data.releaseDuration;
+    double releaseAreaLeft = releaseArea(Curve::Cubic, releaseSpot, 1) * data.releaseDuration.value();
 
     data.desiredVelocity = remainingDelta / (attackAreaLeft + sustainTimeLeft.value() + releaseAreaLeft);
     data.releasePosition = data.desiredPosition - data.desiredVelocity * releaseAreaLeft;
@@ -377,7 +374,7 @@
     if (attackAreaLeft)
         data.attackPosition = data.startPosition + data.desiredVelocity * attackAreaLeft;
     else
-        data.attackPosition = data.releasePosition - (data.animationTime - data.releaseTime - data.attackTime).value() * data.desiredVelocity;
+        data.attackPosition = data.releasePosition - (data.animationDuration - data.releaseDuration - data.attackDuration).value() * data.desiredVelocity;
 
     if (sustainTimeLeft) {
         double roundOff = data.releasePosition - ((attackAreaLeft ? data.attackPosition : data.currentPosition) + data.desiredVelocity * sustainTimeLeft.value());
@@ -401,18 +398,18 @@
     Seconds deltaTime = currentTime - data.startTime;
     double newPosition = data.currentPosition;
 
-    if (deltaTime > data.animationTime) {
+    if (deltaTime > data.animationDuration) {
         data = "" data.visibleLength);
         return false;
     }
-    if (deltaTime < data.attackTime)
-        newPosition = attackCurve(Curve::Cubic, deltaTime.value(), data.attackTime.value(), data.startPosition, data.attackPosition);
-    else if (deltaTime < (data.animationTime - data.releaseTime))
-        newPosition = data.attackPosition + (deltaTime - data.attackTime).value() * data.desiredVelocity;
+    if (deltaTime < data.attackDuration)
+        newPosition = attackCurve(Curve::Cubic, deltaTime.value(), data.attackDuration.value(), data.startPosition, data.attackPosition);
+    else if (deltaTime < (data.animationDuration - data.releaseDuration))
+        newPosition = data.attackPosition + (deltaTime - data.attackDuration).value() * data.desiredVelocity;
     else {
         // release is based on targeting the exact final position.
-        Seconds releaseDeltaT = deltaTime - (data.animationTime - data.releaseTime);
-        newPosition = releaseCurve(Curve::Cubic, releaseDeltaT.value(), data.releaseTime.value(), data.releasePosition, data.desiredPosition);
+        Seconds releaseDeltaT = deltaTime - (data.animationDuration - data.releaseDuration);
+        newPosition = releaseCurve(Curve::Cubic, releaseDeltaT.value(), data.releaseDuration.value(), data.releasePosition, data.desiredPosition);
     }
 
     // Normalize velocity to a per second amount. Could be used to check for jank.
@@ -437,10 +434,10 @@
 
     if (continueAnimation)
         startNextTimer(std::max(minimumTimerInterval, deltaToNextFrame));
-    else
-        m_notifyAnimationStoppedFunction();
 
-    m_notifyPositionChangedFunction(FloatPoint(m_horizontalData.currentPosition, m_verticalData.currentPosition));
+    m_client.scrollAnimationDidUpdate(*this, { m_horizontalData.currentPosition, m_verticalData.currentPosition });
+    if (!continueAnimation)
+        m_client.scrollAnimationDidEnd(*this);
 }
 
 void ScrollAnimationSmooth::startNextTimer(Seconds delay)

Modified: trunk/Source/WebCore/platform/ScrollAnimationSmooth.h (282696 => 282697)


--- trunk/Source/WebCore/platform/ScrollAnimationSmooth.h	2021-09-17 21:42:50 UTC (rev 282696)
+++ trunk/Source/WebCore/platform/ScrollAnimationSmooth.h	2021-09-17 21:43:47 UTC (rev 282697)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2016 Igalia S.L.
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -32,16 +33,11 @@
 namespace WebCore {
 
 class FloatPoint;
-class ScrollableArea;
 enum class ScrollClamping : bool;
 
 class ScrollAnimationSmooth final: public ScrollAnimation {
 public:
-    using ScrollExtentsCallback = WTF::Function<ScrollExtents(void)>;
-    using NotifyPositionChangedCallback = WTF::Function<void(FloatPoint&&)>;
-    using NotifyAnimationStoppedCallback = WTF::Function<void(void)>;
-
-    ScrollAnimationSmooth(ScrollExtentsCallback&&, const FloatPoint& position, NotifyPositionChangedCallback&&, NotifyAnimationStoppedCallback&&);
+    ScrollAnimationSmooth(ScrollAnimationClient&);
     virtual ~ScrollAnimationSmooth();
 
     enum class Curve {
@@ -52,19 +48,17 @@
         Bounce
     };
 
+    bool startAnimatedScroll(ScrollbarOrientation, ScrollGranularity, const FloatPoint& fromPosition, float step, float multiplier);
+    bool startAnimatedScrollToDestination(const FloatPoint& fromPosition, const FloatPoint& destinationPosition);
+
+    bool retargetActiveAnimation(const FloatPoint& newDestination) final;
+    void stop() final;
+    void updateScrollExtents() final;
+    bool isActive() const final;
+
 private:
-    bool scroll(ScrollbarOrientation, ScrollGranularity, float step, float multiplier) override;
-    void scroll(const FloatPoint&) override;
-    void stop() override;
-    void updateVisibleLengths() override;
-    void setCurrentPosition(const FloatPoint&) override;
-    bool isActive() const override;
-
     struct PerAxisData {
-        PerAxisData() = delete;
-
-        PerAxisData(ScrollbarOrientation, const FloatPoint& position, ScrollExtentsCallback&);
-
+        PerAxisData() = default;
         PerAxisData(float position, int length)
             : currentPosition(position)
             , desiredPosition(position)
@@ -82,35 +76,36 @@
         MonotonicTime startTime;
         double startVelocity { 0 };
 
-        Seconds animationTime;
+        Seconds animationDuration;
         MonotonicTime lastAnimationTime;
 
         double attackPosition { 0 };
-        Seconds attackTime;
+        Seconds attackDuration;
         Curve attackCurve { Curve::Quadratic };
 
         double releasePosition { 0 };
-        Seconds releaseTime;
+        Seconds releaseDuration;
         Curve releaseCurve { Curve::Quadratic };
 
         int visibleLength { 0 };
     };
 
+    bool startOrRetargetAnimation(const ScrollExtents&, const FloatPoint& destination);
+
     bool updatePerAxisData(PerAxisData&, ScrollGranularity, float newPosition, float minScrollPosition, float maxScrollPosition, double smoothFactor = 1);
     bool animateScroll(PerAxisData&, MonotonicTime currentTime);
+    
+    void initializeAxesData(const ScrollExtents&, const FloatPoint& startPosition);
 
     void requestAnimationTimerFired();
     void startNextTimer(Seconds delay);
     void animationTimerFired();
 
-    ScrollExtentsCallback m_scrollExtentsFunction;
-    NotifyPositionChangedCallback m_notifyPositionChangedFunction;
-    NotifyAnimationStoppedCallback m_notifyAnimationStoppedFunction;
-
     PerAxisData m_horizontalData;
     PerAxisData m_verticalData;
 
     MonotonicTime m_startTime;
+    // FIXME: Should not have timer here, and instead use serviceAnimation().
     RunLoop::Timer<ScrollAnimationSmooth> m_animationTimer;
 };
 

Modified: trunk/Source/WebCore/platform/ScrollAnimator.cpp (282696 => 282697)


--- trunk/Source/WebCore/platform/ScrollAnimator.cpp	2021-09-17 21:42:50 UTC (rev 282696)
+++ trunk/Source/WebCore/platform/ScrollAnimator.cpp	2021-09-17 21:43:47 UTC (rev 282697)
@@ -54,20 +54,7 @@
     : m_scrollableArea(scrollableArea)
     , m_scrollController(*this)
     , m_scrollControllerAnimationTimer(*this, &ScrollAnimator::scrollControllerAnimationTimerFired)
-    , m_scrollAnimation(makeUnique<ScrollAnimationSmooth>(
-        [this]() -> ScrollExtents {
-            return { m_scrollableArea.minimumScrollPosition(), m_scrollableArea.maximumScrollPosition(), m_scrollableArea.visibleSize() };
-        },
-        m_currentPosition,
-        [this](FloatPoint&& position) {
-            FloatSize delta = position - m_currentPosition;
-            m_currentPosition = WTFMove(position);
-            notifyPositionChanged(delta);
-            updateActiveScrollSnapIndexForOffset();
-        },
-        [this] {
-            m_scrollableArea.setScrollBehaviorStatus(ScrollBehaviorStatus::NotInAnimation);
-        }))
+    , m_scrollAnimation(makeUnique<ScrollAnimationSmooth>(*this))
     , m_keyboardScrollingAnimator(makeUnique<KeyboardScrollingAnimator>(*this, m_scrollController))
 {
 }
@@ -99,11 +86,8 @@
     }
 
 #if ENABLE(SMOOTH_SCROLLING) && !PLATFORM(IOS_FAMILY)
-    if (m_scrollableArea.scrollAnimatorEnabled() && !behavior.contains(ScrollBehavior::NeverAnimate)) {
-        if (!m_scrollAnimation->isActive())
-            m_scrollAnimation->setCurrentPosition(m_currentPosition);
-        return m_scrollAnimation->scroll(orientation, granularity, step, multiplier);
-    }
+    if (m_scrollableArea.scrollAnimatorEnabled() && !behavior.contains(ScrollBehavior::NeverAnimate))
+        return m_scrollAnimation->startAnimatedScroll(orientation, granularity, m_currentPosition, step, multiplier);
 #endif
 
     return scrollToPositionWithoutAnimation(currentPosition() + delta);
@@ -124,7 +108,7 @@
     if (adjustedPosition == currentPosition && adjustedPosition == scrollableArea().scrollPosition() && !scrollableArea().scrollOriginChanged())
         return false;
 
-    m_scrollAnimation->setCurrentPosition(adjustedPosition);
+    m_scrollAnimation->stop();
     m_currentPosition = adjustedPosition;
     notifyPositionChanged(adjustedPosition - currentPosition);
     updateActiveScrollSnapIndexForOffset();
@@ -142,8 +126,7 @@
     if (!positionChanged && !scrollableArea().scrollOriginChanged())
         return false;
 
-    m_scrollAnimation->setCurrentPosition(m_currentPosition);
-    m_scrollAnimation->scroll(newPosition);
+    m_scrollAnimation->startAnimatedScrollToDestination(m_currentPosition, newPosition);
     scrollableArea().setScrollBehaviorStatus(ScrollBehaviorStatus::InNonNativeAnimation);
     return true;
 }
@@ -152,7 +135,7 @@
 {
     ASSERT(scrollableArea().currentScrollBehaviorStatus() == ScrollBehaviorStatus::InNonNativeAnimation);
     ASSERT(m_scrollAnimation->isActive());
-    m_scrollAnimation->scroll(newPosition);
+    m_scrollAnimation->retargetActiveAnimation(newPosition);
 }
 
 FloatPoint ScrollAnimator::offsetFromPosition(const FloatPoint& position)
@@ -375,22 +358,22 @@
 
 void ScrollAnimator::contentsResized() const
 {
-    m_scrollAnimation->updateVisibleLengths();
+    m_scrollAnimation->updateScrollExtents();
 }
 
 void ScrollAnimator::willEndLiveResize()
 {
-    m_scrollAnimation->updateVisibleLengths();
+    m_scrollAnimation->updateScrollExtents();
 }
 
 void ScrollAnimator::didAddVerticalScrollbar(Scrollbar*)
 {
-    m_scrollAnimation->updateVisibleLengths();
+    m_scrollAnimation->updateScrollExtents();
 }
 
 void ScrollAnimator::didAddHorizontalScrollbar(Scrollbar*)
 {
-    m_scrollAnimation->updateVisibleLengths();
+    m_scrollAnimation->updateScrollExtents();
 }
 
 FloatPoint ScrollAnimator::adjustScrollOffsetForSnappingIfNeeded(const FloatPoint& offset, ScrollSnapPointSelectionMethod method)
@@ -422,5 +405,27 @@
     return m_scrollController.adjustScrollDestination(axis, newOffset, velocityInScrollAxis, originalOffset);
 }
 
+void ScrollAnimator::scrollAnimationDidUpdate(ScrollAnimation&, const FloatPoint& position)
+{
+    FloatSize delta = position - m_currentPosition;
+    m_currentPosition = position;
+    notifyPositionChanged(delta);
+    updateActiveScrollSnapIndexForOffset();
+}
 
+void ScrollAnimator::scrollAnimationDidEnd(ScrollAnimation&)
+{
+    m_scrollableArea.setScrollBehaviorStatus(ScrollBehaviorStatus::NotInAnimation);
+}
+
+ScrollExtents ScrollAnimator::scrollExtentsForAnimation(ScrollAnimation&)
+{
+    return {
+        m_scrollableArea.minimumScrollPosition(),
+        m_scrollableArea.maximumScrollPosition(),
+        m_scrollableArea.visibleSize()
+    };
+}
+
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/ScrollAnimator.h (282696 => 282697)


--- trunk/Source/WebCore/platform/ScrollAnimator.h	2021-09-17 21:42:50 UTC (rev 282696)
+++ trunk/Source/WebCore/platform/ScrollAnimator.h	2021-09-17 21:43:47 UTC (rev 282697)
@@ -33,6 +33,7 @@
 
 #include "FloatPoint.h"
 #include "PlatformWheelEvent.h"
+#include "ScrollAnimation.h"
 #include "ScrollingEffectsController.h"
 #include "Timer.h"
 #include "WheelEventTestMonitor.h"
@@ -44,7 +45,7 @@
 class FloatPoint;
 class KeyboardScrollingAnimator;
 class PlatformTouchEvent;
-class ScrollAnimation;
+class ScrollAnimationSmooth;
 class ScrollableArea;
 class Scrollbar;
 class WheelEventTestMonitor;
@@ -51,7 +52,7 @@
 
 class ScrollingEffectsControllerTimer;
 
-class ScrollAnimator : private ScrollingEffectsControllerClient {
+class ScrollAnimator : private ScrollingEffectsControllerClient, public ScrollAnimationClient {
     WTF_MAKE_FAST_ALLOCATED;
 public:
     static std::unique_ptr<ScrollAnimator> create(ScrollableArea&);
@@ -133,6 +134,11 @@
     virtual String horizontalScrollbarStateForTesting() const { return emptyString(); }
     virtual String verticalScrollbarStateForTesting() const { return emptyString(); }
 
+    // ScrollAnimationClient
+    void scrollAnimationDidUpdate(ScrollAnimation&, const FloatPoint& currentPosition) override;
+    void scrollAnimationDidEnd(ScrollAnimation&) override;
+    ScrollExtents scrollExtentsForAnimation(ScrollAnimation&) override;
+
     void setWheelEventTestMonitor(RefPtr<WheelEventTestMonitor>&& testMonitor) { m_wheelEventTestMonitor = testMonitor; }
 
     FloatPoint adjustScrollOffsetForSnappingIfNeeded(const FloatPoint& offset, ScrollSnapPointSelectionMethod);
@@ -179,7 +185,7 @@
     Timer m_scrollControllerAnimationTimer;
     FloatPoint m_currentPosition;
 
-    std::unique_ptr<ScrollAnimation> m_scrollAnimation;
+    std::unique_ptr<ScrollAnimationSmooth> m_scrollAnimation;
     std::unique_ptr<KeyboardScrollingAnimator> m_keyboardScrollingAnimator;
 };
 

Modified: trunk/Source/WebCore/platform/generic/ScrollAnimatorGeneric.cpp (282696 => 282697)


--- trunk/Source/WebCore/platform/generic/ScrollAnimatorGeneric.cpp	2021-09-17 21:42:50 UTC (rev 282696)
+++ trunk/Source/WebCore/platform/generic/ScrollAnimatorGeneric.cpp	2021-09-17 21:43:47 UTC (rev 282697)
@@ -48,16 +48,9 @@
 
 ScrollAnimatorGeneric::ScrollAnimatorGeneric(ScrollableArea& scrollableArea)
     : ScrollAnimator(scrollableArea)
+    , m_kineticAnimation(makeUnique<ScrollAnimationKinetic>(*this))
     , m_overlayScrollbarAnimationTimer(*this, &ScrollAnimatorGeneric::overlayScrollbarAnimationTimerFired)
 {
-    m_kineticAnimation = makeUnique<ScrollAnimationKinetic>(
-        [this]() -> ScrollExtents {
-            return { m_scrollableArea.minimumScrollPosition(), m_scrollableArea.maximumScrollPosition(), m_scrollableArea.visibleSize() };
-        },
-        [this](FloatPoint&& position) {
-            m_scrollAnimation->setCurrentPosition(position);
-            updatePosition(WTFMove(position));
-        });
 }
 
 ScrollAnimatorGeneric::~ScrollAnimatorGeneric() = default;
@@ -76,12 +69,12 @@
     m_kineticAnimation->appendToScrollHistory(event);
 
     if (event.isEndOfNonMomentumScroll()) {
-        m_kineticAnimation->start(m_currentPosition, m_kineticAnimation->computeVelocity(), m_scrollableArea.horizontalScrollbar(), m_scrollableArea.verticalScrollbar());
+        m_kineticAnimation->startAnimatedScrollWithInitialVelocity(m_currentPosition, m_kineticAnimation->computeVelocity(), m_scrollableArea.horizontalScrollbar(), m_scrollableArea.verticalScrollbar());
         return true;
     }
     if (event.isTransitioningToMomentumScroll()) {
         m_kineticAnimation->clearScrollHistory();
-        m_kineticAnimation->start(m_currentPosition, event.swipeVelocity(), m_scrollableArea.horizontalScrollbar(), m_scrollableArea.verticalScrollbar());
+        m_kineticAnimation->startAnimatedScrollWithInitialVelocity(m_currentPosition, event.swipeVelocity(), m_scrollableArea.horizontalScrollbar(), m_scrollableArea.verticalScrollbar());
         return true;
     }
 #endif
@@ -89,10 +82,10 @@
     return ScrollAnimator::handleWheelEvent(event);
 }
 
-void ScrollAnimatorGeneric::updatePosition(FloatPoint&& position)
+void ScrollAnimatorGeneric::updatePosition(const FloatPoint& position)
 {
     FloatSize delta = position - m_currentPosition;
-    m_currentPosition = WTFMove(position);
+    m_currentPosition = position;
     notifyPositionChanged(delta);
     updateActiveScrollSnapIndexForOffset();
 }
@@ -288,5 +281,18 @@
     }
 }
 
+// FIXME: Can we just use the base class implementation?
+void ScrollAnimatorGeneric::scrollAnimationDidUpdate(ScrollAnimation& animation, const FloatPoint& position)
+{
+    if (&animation == m_kineticAnimation.get()) {
+        // FIXME: Clarify how animations interact. There should never be more than one active at a time.
+        m_scrollAnimation->stop();
+        updatePosition(position);
+        return;
+    }
+
+    ScrollAnimator::scrollAnimationDidUpdate(animation, position);
+}
+
 } // namespace WebCore
 

Modified: trunk/Source/WebCore/platform/generic/ScrollAnimatorGeneric.h (282696 => 282697)


--- trunk/Source/WebCore/platform/generic/ScrollAnimatorGeneric.h	2021-09-17 21:42:50 UTC (rev 282696)
+++ trunk/Source/WebCore/platform/generic/ScrollAnimatorGeneric.h	2021-09-17 21:43:47 UTC (rev 282697)
@@ -61,8 +61,11 @@
     void notifyContentAreaScrolled(const FloatSize& delta) override;
     void lockOverlayScrollbarStateToHidden(bool) override;
 
-    void updatePosition(FloatPoint&&);
+    // ScrollAnimationClient
+    void scrollAnimationDidUpdate(ScrollAnimation&, const FloatPoint& currentPosition) override;
 
+    void updatePosition(const FloatPoint&);
+
     void overlayScrollbarAnimationTimerFired();
     void showOverlayScrollbars();
     void hideOverlayScrollbars();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to