Title: [290045] trunk/Source/WebCore
Revision
290045
Author
[email protected]
Date
2022-02-17 12:02:04 -0800 (Thu, 17 Feb 2022)

Log Message

[GTK] REGRESSION: Cumulative velocity for scrolling doesn't work
https://bugs.webkit.org/show_bug.cgi?id=235507

Reviewed by Chris Lord.

ScrollAnimationKinetic can accumulate velocity from the previous scroll
animation. This relies on reusing the same animation every time, so it can
pick up the previous scroll data.

However, ScrollingEffectsController now creates and destroys ScrollAnimationKinetic
every time now, we can't rely on that.

Instead, save and propagate the data manually, same as the macOS port.

* platform/ScrollAnimationKinetic.cpp:
(WebCore::ScrollAnimationKinetic::startAnimatedScrollWithInitialVelocity):
(WebCore::ScrollAnimationKinetic::accumulateVelocityFromPreviousGesture):
* platform/ScrollAnimationKinetic.h:
* platform/ScrollingEffectsController.cpp:
(WebCore::ScrollingEffectsController::processWheelEventForKineticScrolling):
* platform/ScrollingEffectsController.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (290044 => 290045)


--- trunk/Source/WebCore/ChangeLog	2022-02-17 19:59:25 UTC (rev 290044)
+++ trunk/Source/WebCore/ChangeLog	2022-02-17 20:02:04 UTC (rev 290045)
@@ -1,3 +1,27 @@
+2022-02-17  Alexander Mikhaylenko  <[email protected]>
+
+        [GTK] REGRESSION: Cumulative velocity for scrolling doesn't work
+        https://bugs.webkit.org/show_bug.cgi?id=235507
+
+        Reviewed by Chris Lord.
+
+        ScrollAnimationKinetic can accumulate velocity from the previous scroll
+        animation. This relies on reusing the same animation every time, so it can
+        pick up the previous scroll data.
+
+        However, ScrollingEffectsController now creates and destroys ScrollAnimationKinetic
+        every time now, we can't rely on that.
+
+        Instead, save and propagate the data manually, same as the macOS port.
+
+        * platform/ScrollAnimationKinetic.cpp:
+        (WebCore::ScrollAnimationKinetic::startAnimatedScrollWithInitialVelocity):
+        (WebCore::ScrollAnimationKinetic::accumulateVelocityFromPreviousGesture):
+        * platform/ScrollAnimationKinetic.h:
+        * platform/ScrollingEffectsController.cpp:
+        (WebCore::ScrollingEffectsController::processWheelEventForKineticScrolling):
+        * platform/ScrollingEffectsController.h:
+
 2022-02-17  Antti Koivisto  <[email protected]>
 
         [CSS Container Queries] Support full range notation in size queries

Modified: trunk/Source/WebCore/platform/ScrollAnimationKinetic.cpp (290044 => 290045)


--- trunk/Source/WebCore/platform/ScrollAnimationKinetic.cpp	2022-02-17 19:59:25 UTC (rev 290044)
+++ trunk/Source/WebCore/platform/ScrollAnimationKinetic.cpp	2022-02-17 20:02:04 UTC (rev 290045)
@@ -150,8 +150,11 @@
     return FloatSize(accumDelta.x() * -1 / (last - first).value(), accumDelta.y() * -1 / (last - first).value());
 }
 
-bool ScrollAnimationKinetic::startAnimatedScrollWithInitialVelocity(const FloatPoint& initialOffset, const FloatSize& velocity, bool mayHScroll, bool mayVScroll)
+bool ScrollAnimationKinetic::startAnimatedScrollWithInitialVelocity(const FloatPoint& initialOffset, const FloatSize& velocity, const FloatSize& previousVelocity, bool mayHScroll, bool mayVScroll)
 {
+    m_initialOffset = initialOffset;
+    m_initialVelocity = velocity;
+
     stop();
 
     if (velocity.isZero()) {
@@ -160,19 +163,15 @@
         return false;
     }
 
-    auto elapsedTime = 0_s;
     auto extents = m_client.scrollExtentsForAnimation(*this);
 
-    auto accumulateVelocity = [&](double velocity, std::optional<PerAxisData> axisData) -> double {
-        if (axisData && axisData.value().animateScroll(elapsedTime)) {
-            double lastVelocity = axisData.value().velocity();
-            if ((std::signbit(lastVelocity) == std::signbit(velocity))
-                && (std::abs(velocity) >= std::abs(lastVelocity * velocityAccumulationFloor))) {
-                double minVelocity = lastVelocity * velocityAccumulationFloor;
-                double maxVelocity = lastVelocity * velocityAccumulationCeil;
-                double accumulationMultiplier = (velocity - minVelocity) / (maxVelocity - minVelocity);
-                velocity += lastVelocity * std::min(accumulationMultiplier, velocityAccumulationMax);
-            }
+    auto accumulateVelocity = [&](double velocity, double previousVelocity) -> double {
+        if ((std::signbit(previousVelocity) == std::signbit(velocity))
+            && (std::abs(velocity) >= std::abs(previousVelocity * velocityAccumulationFloor))) {
+            double minVelocity = previousVelocity * velocityAccumulationFloor;
+            double maxVelocity = previousVelocity * velocityAccumulationCeil;
+            double accumulationMultiplier = (velocity - minVelocity) / (maxVelocity - minVelocity);
+            velocity += previousVelocity * std::min(accumulationMultiplier, velocityAccumulationMax);
         }
 
         return velocity;
@@ -181,7 +180,7 @@
     if (mayHScroll) {
         m_horizontalData = PerAxisData(extents.minimumScrollOffset().x(),
             extents.maximumScrollOffset().x(),
-            initialOffset.x(), accumulateVelocity(velocity.width(), m_horizontalData));
+            initialOffset.x(), accumulateVelocity(velocity.width(), previousVelocity.width()));
     } else
         m_horizontalData = std::nullopt;
 
@@ -188,7 +187,7 @@
     if (mayVScroll) {
         m_verticalData = PerAxisData(extents.minimumScrollOffset().y(),
             extents.maximumScrollOffset().y(),
-            initialOffset.y(), accumulateVelocity(velocity.height(), m_verticalData));
+            initialOffset.y(), accumulateVelocity(velocity.height(), previousVelocity.height()));
     } else
         m_verticalData = std::nullopt;
 
@@ -232,5 +231,23 @@
     return textStream.release();
 }
 
+FloatSize ScrollAnimationKinetic::accumulateVelocityFromPreviousGesture(const MonotonicTime lastStartTime, const FloatPoint& lastInitialOffset, const FloatSize& lastInitialVelocity)
+{
+    auto elapsedTime = MonotonicTime::now() - lastStartTime;
+    auto extents = m_client.scrollExtentsForAnimation(*this);
 
+    auto horizontalData = PerAxisData(extents.minimumScrollOffset().x(),
+        extents.maximumScrollOffset().x(),
+        lastInitialOffset.x(), lastInitialVelocity.width());
+
+    auto verticalData = PerAxisData(extents.minimumScrollOffset().y(),
+        extents.maximumScrollOffset().y(),
+        lastInitialOffset.y(), lastInitialVelocity.height());
+
+    horizontalData.animateScroll(elapsedTime);
+    verticalData.animateScroll(elapsedTime);
+
+    return FloatSize(horizontalData.velocity(), verticalData.velocity());
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/ScrollAnimationKinetic.h (290044 => 290045)


--- trunk/Source/WebCore/platform/ScrollAnimationKinetic.h	2022-02-17 19:59:25 UTC (rev 290044)
+++ trunk/Source/WebCore/platform/ScrollAnimationKinetic.h	2022-02-17 20:02:04 UTC (rev 290045)
@@ -60,7 +60,7 @@
     ScrollAnimationKinetic(ScrollAnimationClient&);
     virtual ~ScrollAnimationKinetic();
 
-    bool startAnimatedScrollWithInitialVelocity(const FloatPoint& initialOffset, const FloatSize& velocity, bool mayHScroll, bool mayVScroll);
+    bool startAnimatedScrollWithInitialVelocity(const FloatPoint& initialOffset, const FloatSize& velocity, const FloatSize& previousVelocity, bool mayHScroll, bool mayVScroll);
     bool retargetActiveAnimation(const FloatPoint& newOffset) final;
 
     void appendToScrollHistory(const PlatformWheelEvent&);
@@ -68,6 +68,12 @@
 
     FloatSize computeVelocity();
 
+    MonotonicTime startTime() { return m_startTime; }
+    FloatSize initialVelocity() { return m_initialVelocity; }
+    FloatPoint initialOffset() { return m_initialOffset; }
+
+    FloatSize accumulateVelocityFromPreviousGesture(const MonotonicTime, const FloatPoint&, const FloatSize&);
+
 private:
     void serviceAnimation(MonotonicTime) final;
     String debugDescription() const final;
@@ -76,6 +82,8 @@
     std::optional<PerAxisData> m_verticalData;
 
     Vector<PlatformWheelEvent> m_scrollHistory;
+    FloatPoint m_initialOffset;
+    FloatSize m_initialVelocity;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/ScrollingEffectsController.cpp (290044 => 290045)


--- trunk/Source/WebCore/platform/ScrollingEffectsController.cpp	2022-02-17 19:59:25 UTC (rev 290044)
+++ trunk/Source/WebCore/platform/ScrollingEffectsController.cpp	2022-02-17 20:02:04 UTC (rev 290045)
@@ -276,11 +276,19 @@
 #if ENABLE(KINETIC_SCROLLING)
 bool ScrollingEffectsController::processWheelEventForKineticScrolling(const PlatformWheelEvent& event)
 {
-    if (is<ScrollAnimationKinetic>(m_currentAnimation.get()))
+    if (is<ScrollAnimationKinetic>(m_currentAnimation.get())) {
+        auto& kineticAnimation = downcast<ScrollAnimationKinetic>(*m_currentAnimation);
+
+        m_previousKineticAnimationInfo.startTime = kineticAnimation.startTime();
+        m_previousKineticAnimationInfo.initialOffset = kineticAnimation.initialOffset();
+        m_previousKineticAnimationInfo.initialVelocity = kineticAnimation.initialVelocity();
+
         m_currentAnimation->stop();
+    }
 
     if (!event.hasPreciseScrollingDeltas()) {
         m_scrollHistory.clear();
+        m_previousKineticAnimationInfo.initialVelocity = FloatSize();
         return false;
     }
 
@@ -294,6 +302,7 @@
     if (m_currentAnimation && !is<ScrollAnimationKinetic>(m_currentAnimation.get())) {
         m_currentAnimation->stop();
         m_currentAnimation = nullptr;
+        m_previousKineticAnimationInfo.initialVelocity = FloatSize();
     }
 
     if (usesScrollSnap())
@@ -306,13 +315,20 @@
     while (!m_scrollHistory.isEmpty())
         kineticAnimation.appendToScrollHistory(m_scrollHistory.takeFirst());
 
+    FloatSize previousVelocity;
+    if (!m_previousKineticAnimationInfo.initialVelocity.isZero()) {
+        previousVelocity = kineticAnimation.accumulateVelocityFromPreviousGesture(m_previousKineticAnimationInfo.startTime,
+            m_previousKineticAnimationInfo.initialOffset, m_previousKineticAnimationInfo.initialVelocity);
+        m_previousKineticAnimationInfo.initialVelocity = FloatSize();
+    }
+
     if (event.isEndOfNonMomentumScroll()) {
-        kineticAnimation.startAnimatedScrollWithInitialVelocity(m_client.scrollOffset(), kineticAnimation.computeVelocity(), m_client.allowsHorizontalScrolling(), m_client.allowsVerticalScrolling());
+        kineticAnimation.startAnimatedScrollWithInitialVelocity(m_client.scrollOffset(), kineticAnimation.computeVelocity(), previousVelocity, m_client.allowsHorizontalScrolling(), m_client.allowsVerticalScrolling());
         return true;
     }
     if (event.isTransitioningToMomentumScroll()) {
         kineticAnimation.clearScrollHistory();
-        kineticAnimation.startAnimatedScrollWithInitialVelocity(m_client.scrollOffset(), event.swipeVelocity(), m_client.allowsHorizontalScrolling(), m_client.allowsVerticalScrolling());
+        kineticAnimation.startAnimatedScrollWithInitialVelocity(m_client.scrollOffset(), event.swipeVelocity(), previousVelocity, m_client.allowsHorizontalScrolling(), m_client.allowsVerticalScrolling());
         return true;
     }
 

Modified: trunk/Source/WebCore/platform/ScrollingEffectsController.h (290044 => 290045)


--- trunk/Source/WebCore/platform/ScrollingEffectsController.h	2022-02-17 19:59:25 UTC (rev 290044)
+++ trunk/Source/WebCore/platform/ScrollingEffectsController.h	2022-02-17 20:02:04 UTC (rev 290045)
@@ -237,6 +237,12 @@
     bool processWheelEventForKineticScrolling(const PlatformWheelEvent&);
 
     Deque<PlatformWheelEvent> m_scrollHistory;
+
+    struct {
+        MonotonicTime startTime;
+        FloatPoint initialOffset;
+        FloatSize initialVelocity;
+    } m_previousKineticAnimationInfo;
 #endif
 
     ScrollingEffectsControllerClient& m_client;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to