Title: [286483] trunk/Source/WebKit
Revision
286483
Author
timothy_hor...@apple.com
Date
2021-12-02 23:25:20 -0800 (Thu, 02 Dec 2021)

Log Message

MomentumEventDispatcher curve sometimes doesn't match the system curve
https://bugs.webkit.org/show_bug.cgi?id=233801
<rdar://problem/85870287>

Reviewed by Simon Fraser.

Three small changes to get us closer to the system curve:

1) Fetch the momentum event dispatch interval from the system, and use
it to scale the momentum start event's delta (which we use as our
initial velocity) into the "ideal" curve's frame rate (which is always
60fps regardless).

2) Back-date the animation start time to the fingers-down phase end event,
so that the momentum start phase has a delta. This seems to match what
the system does.

3) Switch to MonotonicTime for the animation time, since it doesn't need
to be in the same timebase as events (which are oddly in WallTime), and
certainly should be monotonic.

* Shared/ScrollingAccelerationCurve.cpp:
(WebKit::ScrollingAccelerationCurve::ScrollingAccelerationCurve):
(WebKit::ScrollingAccelerationCurve::interpolate):
(WebKit::ScrollingAccelerationCurve::encode const):
(WebKit::ScrollingAccelerationCurve::decode):
(WebKit::operator<<):
* Shared/ScrollingAccelerationCurve.h:
(WebKit::ScrollingAccelerationCurve::frameRate):
(WebKit::ScrollingAccelerationCurve::operator== const):
* Shared/mac/ScrollingAccelerationCurveMac.mm:
(WebKit::fromIOHIDCurve):
(WebKit::fromIOHIDCurveArrayWithAcceleration):
(WebKit::fromIOHIDDevice):
Fetch and propagate the dispatch frame rate. This isn't *really* a
ScrollingAccelerationCurve property, but neither is `resolution`;
this is just currently the only place we look up HID properties
and push them to the Web Content process; some re-architecture is
warranted here in the future.

* WebProcess/WebPage/MomentumEventDispatcher.cpp:
(WebKit::MomentumEventDispatcher::handleWheelEvent):
Keep track of the last fingers-down phase ended event timestamp.

(WebKit::MomentumEventDispatcher::didStartMomentumPhase):
Backdate the start time so that the first event has the appropriate delta.
Divide out the dispatch frame rate so that the initial velocity is
as if the curve were running at 60fps (since we *will* run it at 60fps and interpolate).

(WebKit::MomentumEventDispatcher::didEndMomentumPhase):
(WebKit::MomentumEventDispatcher::consumeDeltaForTime):
(WebKit::MomentumEventDispatcher::displayWasRefreshed):
Factor the consume-a-delta-from-the-ideal-curve code out from displayWasRefreshed
so we can use it in the start phase too.

(WebKit::MomentumEventDispatcher::offsetAtTime):
(WebKit::MomentumEventDispatcher::computeNextDelta):
Rename idealCurveFrameRate->idealCurveFrameInterval for accuracy.

* WebProcess/WebPage/MomentumEventDispatcher.h:

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (286482 => 286483)


--- trunk/Source/WebKit/ChangeLog	2021-12-03 06:39:14 UTC (rev 286482)
+++ trunk/Source/WebKit/ChangeLog	2021-12-03 07:25:20 UTC (rev 286483)
@@ -1,3 +1,66 @@
+2021-12-02  Tim Horton  <timothy_hor...@apple.com>
+
+        MomentumEventDispatcher curve sometimes doesn't match the system curve
+        https://bugs.webkit.org/show_bug.cgi?id=233801
+        <rdar://problem/85870287>
+
+        Reviewed by Simon Fraser.
+
+        Three small changes to get us closer to the system curve:
+
+        1) Fetch the momentum event dispatch interval from the system, and use
+        it to scale the momentum start event's delta (which we use as our
+        initial velocity) into the "ideal" curve's frame rate (which is always
+        60fps regardless).
+
+        2) Back-date the animation start time to the fingers-down phase end event,
+        so that the momentum start phase has a delta. This seems to match what
+        the system does.
+
+        3) Switch to MonotonicTime for the animation time, since it doesn't need
+        to be in the same timebase as events (which are oddly in WallTime), and
+        certainly should be monotonic.
+
+        * Shared/ScrollingAccelerationCurve.cpp:
+        (WebKit::ScrollingAccelerationCurve::ScrollingAccelerationCurve):
+        (WebKit::ScrollingAccelerationCurve::interpolate):
+        (WebKit::ScrollingAccelerationCurve::encode const):
+        (WebKit::ScrollingAccelerationCurve::decode):
+        (WebKit::operator<<):
+        * Shared/ScrollingAccelerationCurve.h:
+        (WebKit::ScrollingAccelerationCurve::frameRate):
+        (WebKit::ScrollingAccelerationCurve::operator== const):
+        * Shared/mac/ScrollingAccelerationCurveMac.mm:
+        (WebKit::fromIOHIDCurve):
+        (WebKit::fromIOHIDCurveArrayWithAcceleration):
+        (WebKit::fromIOHIDDevice):
+        Fetch and propagate the dispatch frame rate. This isn't *really* a
+        ScrollingAccelerationCurve property, but neither is `resolution`;
+        this is just currently the only place we look up HID properties
+        and push them to the Web Content process; some re-architecture is
+        warranted here in the future.
+
+        * WebProcess/WebPage/MomentumEventDispatcher.cpp:
+        (WebKit::MomentumEventDispatcher::handleWheelEvent):
+        Keep track of the last fingers-down phase ended event timestamp.
+
+        (WebKit::MomentumEventDispatcher::didStartMomentumPhase):
+        Backdate the start time so that the first event has the appropriate delta.
+        Divide out the dispatch frame rate so that the initial velocity is
+        as if the curve were running at 60fps (since we *will* run it at 60fps and interpolate).
+
+        (WebKit::MomentumEventDispatcher::didEndMomentumPhase):
+        (WebKit::MomentumEventDispatcher::consumeDeltaForTime):
+        (WebKit::MomentumEventDispatcher::displayWasRefreshed):
+        Factor the consume-a-delta-from-the-ideal-curve code out from displayWasRefreshed
+        so we can use it in the start phase too.
+
+        (WebKit::MomentumEventDispatcher::offsetAtTime):
+        (WebKit::MomentumEventDispatcher::computeNextDelta):
+        Rename idealCurveFrameRate->idealCurveFrameInterval for accuracy.
+
+        * WebProcess/WebPage/MomentumEventDispatcher.h:
+
 2021-12-02  Simon Fraser  <simon.fra...@apple.com>
 
         A Safari tab can rarely get stuck in a state where rendering updates stop happening

Modified: trunk/Source/WebKit/Shared/ScrollingAccelerationCurve.cpp (286482 => 286483)


--- trunk/Source/WebKit/Shared/ScrollingAccelerationCurve.cpp	2021-12-03 06:39:14 UTC (rev 286482)
+++ trunk/Source/WebKit/Shared/ScrollingAccelerationCurve.cpp	2021-12-03 07:25:20 UTC (rev 286483)
@@ -34,8 +34,8 @@
 
 namespace WebKit {
 
-ScrollingAccelerationCurve::ScrollingAccelerationCurve(float gainLinear, float gainParabolic, float gainCubic, float gainQuartic, float tangentSpeedLinear, float tangentSpeedParabolicRoot, float resolution)
-    : m_parameters { gainLinear, gainParabolic, gainCubic, gainQuartic, tangentSpeedLinear, tangentSpeedParabolicRoot, resolution }
+ScrollingAccelerationCurve::ScrollingAccelerationCurve(float gainLinear, float gainParabolic, float gainCubic, float gainQuartic, float tangentSpeedLinear, float tangentSpeedParabolicRoot, float resolution, float frameRate)
+    : m_parameters { gainLinear, gainParabolic, gainCubic, gainQuartic, tangentSpeedLinear, tangentSpeedParabolicRoot, resolution, frameRate }
 {
 }
 
@@ -53,7 +53,7 @@
     auto tangentSpeedLinear = interpolate(from.m_parameters.tangentSpeedLinear, to.m_parameters.tangentSpeedLinear);
     auto tangentSpeedParabolicRoot = interpolate(from.m_parameters.tangentSpeedParabolicRoot, to.m_parameters.tangentSpeedParabolicRoot);
 
-    return { gainLinear, gainParabolic, gainCubic, gainQuartic, tangentSpeedLinear, tangentSpeedParabolicRoot, from.m_parameters.resolution };
+    return { gainLinear, gainParabolic, gainCubic, gainQuartic, tangentSpeedLinear, tangentSpeedParabolicRoot, from.m_parameters.resolution, from.m_parameters.frameRate };
 }
 
 void ScrollingAccelerationCurve::computeIntermediateValuesIfNeeded()
@@ -127,6 +127,7 @@
     encoder << m_parameters.tangentSpeedParabolicRoot;
 
     encoder << m_parameters.resolution;
+    encoder << m_parameters.frameRate;
 }
 
 std::optional<ScrollingAccelerationCurve> ScrollingAccelerationCurve::decode(IPC::Decoder& decoder)
@@ -154,8 +155,11 @@
     float resolution;
     if (!decoder.decode(resolution))
         return std::nullopt;
+    float frameRate;
+    if (!decoder.decode(frameRate))
+        return std::nullopt;
 
-    return { { gainLinear, gainParabolic, gainCubic, gainQuartic, tangentSpeedLinear, tangentSpeedParabolicRoot, resolution } };
+    return { { gainLinear, gainParabolic, gainCubic, gainQuartic, tangentSpeedLinear, tangentSpeedParabolicRoot, resolution, frameRate } };
 }
 
 TextStream& operator<<(TextStream& ts, const ScrollingAccelerationCurve& curve)
@@ -171,6 +175,7 @@
     ts.dumpProperty("tangentSpeedLinear", curve.m_parameters.tangentSpeedLinear);
     ts.dumpProperty("tangentSpeedParabolicRoot", curve.m_parameters.tangentSpeedParabolicRoot);
     ts.dumpProperty("resolution", curve.m_parameters.resolution);
+    ts.dumpProperty("frameRate", curve.m_parameters.frameRate);
 
     return ts;
 }

Modified: trunk/Source/WebKit/Shared/ScrollingAccelerationCurve.h (286482 => 286483)


--- trunk/Source/WebKit/Shared/ScrollingAccelerationCurve.h	2021-12-03 06:39:14 UTC (rev 286482)
+++ trunk/Source/WebKit/Shared/ScrollingAccelerationCurve.h	2021-12-03 07:25:20 UTC (rev 286483)
@@ -41,7 +41,7 @@
 
 class ScrollingAccelerationCurve {
 public:
-    ScrollingAccelerationCurve(float gainLinear, float gainParabolic, float gainCubic, float gainQuartic, float tangentSpeedLinear, float tangentSpeedParabolicRoot, float resolution);
+    ScrollingAccelerationCurve(float gainLinear, float gainParabolic, float gainCubic, float gainQuartic, float tangentSpeedLinear, float tangentSpeedParabolicRoot, float resolution, float frameRate);
 
     static std::optional<ScrollingAccelerationCurve> fromNativeWheelEvent(const NativeWebWheelEvent&);
 
@@ -48,6 +48,7 @@
     static ScrollingAccelerationCurve interpolate(const ScrollingAccelerationCurve& from, const ScrollingAccelerationCurve& to, float amount);
 
     float accelerationFactor(float);
+    float frameRate() const { return m_parameters.frameRate; }
 
     void encode(IPC::Encoder&) const;
     static std::optional<ScrollingAccelerationCurve> decode(IPC::Decoder&);
@@ -60,7 +61,8 @@
             && m_parameters.gainQuartic == other.m_parameters.gainQuartic
             && m_parameters.tangentSpeedLinear == other.m_parameters.tangentSpeedLinear
             && m_parameters.tangentSpeedParabolicRoot == other.m_parameters.tangentSpeedParabolicRoot
-            && m_parameters.resolution == other.m_parameters.resolution;
+            && m_parameters.resolution == other.m_parameters.resolution
+            && m_parameters.frameRate == other.m_parameters.frameRate;
     }
 
     bool operator!=(const ScrollingAccelerationCurve& other) const { return !(*this == other); }
@@ -79,7 +81,11 @@
         float gainQuartic { 0 };
         float tangentSpeedLinear { 0 };
         float tangentSpeedParabolicRoot { 0 };
+
+        // FIXME: Resolution and frame rate are not technically properties
+        // of the curve, just required to use it; they should be plumbed separately.
         float resolution { 0 };
+        float frameRate { 0 };
     } m_parameters;
 
     struct ComputedIntermediateValues {

Modified: trunk/Source/WebKit/Shared/mac/ScrollingAccelerationCurveMac.mm (286482 => 286483)


--- trunk/Source/WebKit/Shared/mac/ScrollingAccelerationCurveMac.mm	2021-12-03 06:39:14 UTC (rev 286482)
+++ trunk/Source/WebKit/Shared/mac/ScrollingAccelerationCurveMac.mm	2021-12-03 07:25:20 UTC (rev 286483)
@@ -39,12 +39,19 @@
     return value / 65536.0f;
 }
 
+static float fromCFNumber(CFNumberRef number)
+{
+    float value;
+    CFNumberGetValue(number, kCFNumberFloatType, &value);
+    return value;
+}
+
 static float readFixedPointParameter(NSDictionary *parameters, const char *key)
 {
     return fromFixedPoint([[parameters objectForKey:@(key)] floatValue]);
 }
 
-static ScrollingAccelerationCurve fromIOHIDCurve(NSDictionary *parameters, float resolution)
+static ScrollingAccelerationCurve fromIOHIDCurve(NSDictionary *parameters, float resolution, float frameRate)
 {
     auto gainLinear = readFixedPointParameter(parameters, kHIDAccelGainLinearKey);
     auto gainParabolic = readFixedPointParameter(parameters, kHIDAccelGainParabolicKey);
@@ -54,10 +61,10 @@
     auto tangentSpeedLinear = readFixedPointParameter(parameters, kHIDAccelTangentSpeedLinearKey);
     auto tangentSpeedParabolicRoot = readFixedPointParameter(parameters, kHIDAccelTangentSpeedParabolicRootKey);
 
-    return { gainLinear, gainParabolic, gainCubic, gainQuartic, tangentSpeedLinear, tangentSpeedParabolicRoot, resolution };
+    return { gainLinear, gainParabolic, gainCubic, gainQuartic, tangentSpeedLinear, tangentSpeedParabolicRoot, resolution, frameRate };
 }
 
-static ScrollingAccelerationCurve fromIOHIDCurveArrayWithAcceleration(NSArray<NSDictionary *> *ioHIDCurves, float desiredAcceleration, float resolution)
+static ScrollingAccelerationCurve fromIOHIDCurveArrayWithAcceleration(NSArray<NSDictionary *> *ioHIDCurves, float desiredAcceleration, float resolution, float frameRate)
 {
     __block size_t currentIndex = 0;
     __block Vector<std::pair<float, ScrollingAccelerationCurve>> curves;
@@ -64,7 +71,7 @@
 
     [ioHIDCurves enumerateObjectsUsingBlock:^(NSDictionary *parameters, NSUInteger i, BOOL *) {
         auto curveAcceleration = readFixedPointParameter(parameters, kHIDAccelIndexKey);
-        auto curve = fromIOHIDCurve(parameters, resolution);
+        auto curve = fromIOHIDCurve(parameters, resolution, frameRate);
 
         if (desiredAcceleration > curveAcceleration)
             currentIndex = i;
@@ -116,19 +123,26 @@
         return std::nullopt;
     }
 
-    auto scrollAcceleration = adoptCF(dynamic_cf_cast<CFNumberRef>(IOHIDServiceClientCopyProperty(ioHIDService.get(), scrollAccelerationType.get())));
-    if (!scrollAcceleration) {
+    auto scrollAccelerationCF = adoptCF(dynamic_cf_cast<CFNumberRef>(IOHIDServiceClientCopyProperty(ioHIDService.get(), scrollAccelerationType.get())));
+    if (!scrollAccelerationCF) {
         RELEASE_LOG(ScrollAnimations, "ScrollingAccelerationCurve::fromIOHIDDevice failed to look up acceleration value");
         return std::nullopt;
     }
+    auto scrollAcceleration = fromFixedPoint(fromCFNumber(scrollAccelerationCF.get()));
 
-    auto resolution = adoptCF(dynamic_cf_cast<CFNumberRef>(IOHIDServiceClientCopyProperty(ioHIDService.get(), CFSTR(kIOHIDScrollResolutionKey))));
-    if (!resolution) {
+    auto resolutionCF = adoptCF(dynamic_cf_cast<CFNumberRef>(IOHIDServiceClientCopyProperty(ioHIDService.get(), CFSTR(kIOHIDScrollResolutionKey))));
+    if (!resolutionCF) {
         RELEASE_LOG(ScrollAnimations, "ScrollingAccelerationCurve::fromIOHIDDevice failed to look up resolution");
         return std::nullopt;
     }
+    auto resolution = fromFixedPoint([(NSNumber *)resolutionCF.get() floatValue]);
 
-    return fromIOHIDCurveArrayWithAcceleration((NSArray *)curves.get(), fromFixedPoint([(NSNumber *)scrollAcceleration.get() floatValue]), fromFixedPoint([(NSNumber *)resolution.get() floatValue]));
+    static CFStringRef dispatchFrameRateKey = CFSTR("ScrollMomentumDispatchRate");
+    static constexpr float defaultDispatchFrameRate = 60;
+    auto frameRateCF = adoptCF(dynamic_cf_cast<CFNumberRef>(IOHIDServiceClientCopyProperty(ioHIDService.get(), dispatchFrameRateKey)));
+    float frameRate = frameRateCF ? fromCFNumber(frameRateCF.get()) : defaultDispatchFrameRate;
+
+    return fromIOHIDCurveArrayWithAcceleration((NSArray *)curves.get(), scrollAcceleration, resolution, frameRate);
 }
 
 std::optional<ScrollingAccelerationCurve> ScrollingAccelerationCurve::fromNativeWheelEvent(const NativeWebWheelEvent& nativeWebWheelEvent)

Modified: trunk/Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.cpp (286482 => 286483)


--- trunk/Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.cpp	2021-12-03 06:39:14 UTC (rev 286482)
+++ trunk/Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.cpp	2021-12-03 07:25:20 UTC (rev 286483)
@@ -39,7 +39,8 @@
 
 static constexpr Seconds deltaHistoryMaximumAge = 500_ms;
 static constexpr Seconds deltaHistoryMaximumInterval = 150_ms;
-static constexpr Seconds idealCurveFrameRate = 1_s / 60;
+static constexpr float idealCurveFrameRate = 60;
+static constexpr Seconds idealCurveFrameInterval = 1_s / idealCurveFrameRate;
 
 MomentumEventDispatcher::MomentumEventDispatcher(EventDispatcher& dispatcher)
     : m_observerID(DisplayLinkObserverID::generate())
@@ -96,6 +97,9 @@
             m_lastActivePhaseDelta = *lastActivePhaseDelta;
     }
 
+    if (event.phase() == WebWheelEvent::PhaseEnded)
+        m_lastEndedEventTimestamp = event.ioHIDEventTimestamp();
+
     if (eventShouldStartSyntheticMomentumPhase(pageIdentifier, event))
         didStartMomentumPhase(pageIdentifier, event);
 
@@ -159,11 +163,13 @@
 
 void MomentumEventDispatcher::didStartMomentumPhase(WebCore::PageIdentifier pageIdentifier, const WebWheelEvent& event)
 {
+    auto momentumStartInterval = event.ioHIDEventTimestamp() - m_lastEndedEventTimestamp;
+
     m_currentGesture.active = true;
     m_currentGesture.pageIdentifier = pageIdentifier;
     m_currentGesture.initiatingEvent = event;
     m_currentGesture.currentOffset = { };
-    m_currentGesture.startTime = WallTime::now();
+    m_currentGesture.startTime = MonotonicTime::now() - momentumStartInterval;
     m_currentGesture.accelerationCurve = [&] () -> std::optional<ScrollingAccelerationCurve> {
         auto curveIterator = m_accelerationCurves.find(m_currentGesture.pageIdentifier);
         if (curveIterator == m_accelerationCurves.end())
@@ -176,9 +182,10 @@
     // FIXME: The system falls back from the table to just generating deltas
     // directly when the frame interval is within 20fps of idealCurveFrameRate;
     // we should perhaps do the same.
-    buildOffsetTableWithInitialDelta(*event.rawPlatformDelta());
+    float idealCurveMultiplier = m_currentGesture.accelerationCurve->frameRate() / idealCurveFrameRate;
+    buildOffsetTableWithInitialDelta(*event.rawPlatformDelta() * idealCurveMultiplier);
 
-    dispatchSyntheticMomentumEvent(WebWheelEvent::PhaseBegan, { });
+    dispatchSyntheticMomentumEvent(WebWheelEvent::PhaseBegan, consumeDeltaForCurrentTime());
 }
 
 void MomentumEventDispatcher::didEndMomentumPhase()
@@ -187,7 +194,7 @@
 
     dispatchSyntheticMomentumEvent(WebWheelEvent::PhaseEnded, { });
 
-    RELEASE_LOG(ScrollAnimations, "MomentumEventDispatcher saw momentum end phase with total offset %.1f %.1f, duration %f (event offset would have been %.1f %.1f)", m_currentGesture.currentOffset.width(), m_currentGesture.currentOffset.height(), (WallTime::now() - m_currentGesture.startTime).seconds(), m_currentGesture.accumulatedEventOffset.width(), m_currentGesture.accumulatedEventOffset.height());
+    RELEASE_LOG(ScrollAnimations, "MomentumEventDispatcher saw momentum end phase with total offset %.1f %.1f, duration %f (event offset would have been %.1f %.1f)", m_currentGesture.currentOffset.width(), m_currentGesture.currentOffset.height(), (MonotonicTime::now() - m_currentGesture.startTime).seconds(), m_currentGesture.accumulatedEventOffset.width(), m_currentGesture.accumulatedEventOffset.height());
 
     stopDisplayLink();
 
@@ -251,15 +258,9 @@
         startDisplayLink();
 }
 
-void MomentumEventDispatcher::displayWasRefreshed(WebCore::PlatformDisplayID displayID, const WebCore::DisplayUpdate&)
+WebCore::FloatSize MomentumEventDispatcher::consumeDeltaForCurrentTime()
 {
-    if (!m_currentGesture.active)
-        return;
-
-    if (displayID != this->displayID())
-        return;
-
-    auto animationTime = WallTime::now() - m_currentGesture.startTime;
+    auto animationTime = MonotonicTime::now() - m_currentGesture.startTime;
     auto desiredOffset = offsetAtTime(animationTime);
 
 #if !USE(MOMENTUM_EVENT_DISPATCHER_PREMATURE_ROUNDING)
@@ -269,11 +270,22 @@
     WebCore::FloatSize delta = desiredOffset - m_currentGesture.currentOffset;
 #endif
 
-    dispatchSyntheticMomentumEvent(WebWheelEvent::PhaseChanged, -delta);
+    m_currentGesture.currentOffset += delta;
 
-    m_currentGesture.currentOffset += delta;
+    return -delta;
 }
 
+void MomentumEventDispatcher::displayWasRefreshed(WebCore::PlatformDisplayID displayID, const WebCore::DisplayUpdate&)
+{
+    if (!m_currentGesture.active)
+        return;
+
+    if (displayID != this->displayID())
+        return;
+
+    dispatchSyntheticMomentumEvent(WebWheelEvent::PhaseChanged, consumeDeltaForCurrentTime());
+}
+
 void MomentumEventDispatcher::didReceiveScrollEventWithInterval(WebCore::FloatSize size, Seconds frameInterval)
 {
     auto push = [](HistoricalDeltas& deltas, Delta newDelta) {
@@ -343,7 +355,7 @@
     if (!m_currentGesture.offsetTable.size())
         return { };
 
-    float fractionalFrameNumber = time.seconds() / idealCurveFrameRate.seconds();
+    float fractionalFrameNumber = time.seconds() / idealCurveFrameInterval.seconds();
     unsigned long lowerFrameNumber = std::min<unsigned long>(m_currentGesture.offsetTable.size() - 1, floor(fractionalFrameNumber));
     unsigned long upperFrameNumber = std::min<unsigned long>(m_currentGesture.offsetTable.size() - 1, lowerFrameNumber + 1);
     float amount = fractionalFrameNumber - lowerFrameNumber;
@@ -379,7 +391,7 @@
 {
     WebCore::FloatSize unacceleratedDelta = currentUnacceleratedDelta;
 
-    float decayRate = momentumDecayRate(unacceleratedDelta, idealCurveFrameRate);
+    float decayRate = momentumDecayRate(unacceleratedDelta, idealCurveFrameInterval);
     unacceleratedDelta.scale(decayRate);
 
     auto quantizedUnacceleratedDelta = unacceleratedDelta;
@@ -403,7 +415,7 @@
 #endif
 
     // The delta queue operates on pre-acceleration deltas, so insert the new event *before* accelerating.
-    didReceiveScrollEventWithInterval(quantizedUnacceleratedDelta, idealCurveFrameRate);
+    didReceiveScrollEventWithInterval(quantizedUnacceleratedDelta, idealCurveFrameInterval);
 
     auto accelerateAxis = [&] (HistoricalDeltas& deltas, float value) {
         float totalDelta = 0;

Modified: trunk/Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.h (286482 => 286483)


--- trunk/Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.h	2021-12-03 06:39:14 UTC (rev 286482)
+++ trunk/Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.h	2021-12-03 07:25:20 UTC (rev 286483)
@@ -39,6 +39,7 @@
 #include <WebCore/RectEdges.h>
 #include <memory>
 #include <wtf/Deque.h>
+#include <wtf/MonotonicTime.h>
 #include <wtf/Noncopyable.h>
 
 namespace WebCore {
@@ -80,6 +81,9 @@
 
     void buildOffsetTableWithInitialDelta(WebCore::FloatSize);
 
+    // Once consumed, this delta *must* be dispatched in an event.
+    WebCore::FloatSize consumeDeltaForCurrentTime();
+
     WebCore::FloatSize offsetAtTime(Seconds);
     std::pair<WebCore::FloatSize, WebCore::FloatSize> computeNextDelta(WebCore::FloatSize currentUnacceleratedDelta);
 
@@ -96,6 +100,7 @@
     HistoricalDeltas m_deltaHistoryY;
 
     std::optional<WallTime> m_lastScrollTimestamp;
+    WallTime m_lastEndedEventTimestamp;
     std::optional<WebWheelEvent> m_lastIncomingEvent;
     WebCore::RectEdges<bool> m_lastRubberBandableEdges;
 #if !RELEASE_LOG_DISABLED
@@ -110,7 +115,7 @@
         std::optional<WebWheelEvent> initiatingEvent;
 
         WebCore::FloatSize currentOffset;
-        WallTime startTime;
+        MonotonicTime startTime;
 
         Vector<WebCore::FloatSize> offsetTable;
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to