WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
Bug 233653
Add a momentum event synthesizer
https://bugs.webkit.org/show_bug.cgi?id=233653
Summary
Add a momentum event synthesizer
Tim Horton
Reported
2021-11-30 12:09:54 PST
Add a momentum event synthesizer
Attachments
Patch
(79.62 KB, patch)
2021-11-30 12:11 PST
,
Tim Horton
ews-feeder
: commit-queue-
Details
Formatted Diff
Diff
Patch
(79.77 KB, patch)
2021-11-30 12:59 PST
,
Tim Horton
no flags
Details
Formatted Diff
Diff
Patch
(79.84 KB, patch)
2021-11-30 13:03 PST
,
Tim Horton
no flags
Details
Formatted Diff
Diff
Patch
(81.56 KB, patch)
2021-11-30 15:37 PST
,
Tim Horton
no flags
Details
Formatted Diff
Diff
Patch
(82.49 KB, patch)
2021-11-30 17:21 PST
,
Tim Horton
no flags
Details
Formatted Diff
Diff
Show Obsolete
(4)
View All
Add attachment
proposed patch, testcase, etc.
Tim Horton
Comment 1
2021-11-30 12:11:59 PST
Created
attachment 445452
[details]
Patch
Tim Horton
Comment 2
2021-11-30 12:12:02 PST
<
rdar://problem/85571258
>
Tim Horton
Comment 3
2021-11-30 12:59:44 PST
Created
attachment 445458
[details]
Patch
Tim Horton
Comment 4
2021-11-30 13:03:23 PST
Created
attachment 445459
[details]
Patch
Simon Fraser (smfr)
Comment 5
2021-11-30 13:58:57 PST
Comment on
attachment 445459
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=445459&action=review
> Source/WebKit/Shared/ScrollingAccelerationCurve.cpp:76 > + return (4 * std::pow(x, 3) * std::pow(m_gainQuartic, 4)) + (3 * std::pow(x, 2) * std::pow(m_gainCubic, 3)) + (2 * x * std::pow(m_gainParabolic, 2)) + m_gainLinear;
This calls std::pow(m_gainQuartic, 4) and std::pow(m_gainCubic, 3) on each call, but that probably doesn't matter.
> Source/WebKit/Shared/ScrollingAccelerationCurve.cpp:107 > + constexpr float cursorScale = 96.f / frameRate;
Any idea where the 96 comes from? The word "cursor" here is confusing.
> Source/WebKit/Shared/ScrollingAccelerationCurve.h:42 > +class ScrollingAccelerationCurve {
AccelerationCurve or DecelerationCurve?
> Source/WebKit/Shared/ScrollingAccelerationCurve.h:50 > + float accelerationFactor(float);
const
> Source/WebKit/Shared/ScrollingAccelerationCurve.h:73 > + float evaluateQuartic(float);
const
> Source/WebKit/Shared/ScrollingAccelerationCurve.h:91 > + // Input parameters. > + float m_gainLinear { 0 }; > + float m_gainParabolic { 0 }; > + float m_gainCubic { 0 }; > + float m_gainQuartic { 0 }; > + float m_tangentSpeedLinear { 0 }; > + float m_tangentSpeedParabolicRoot { 0 }; > + float m_resolution { 0 }; > + > + // Computed intermediate values. > + bool m_hasComputedIntermediateValues { false }; > + float m_tangentStartX { 0 }; > + float m_tangentSlope { 0 }; > + float m_tangentIntercept { 0 }; > + float m_falloffStartX { 0 }; > + float m_falloffSlope { 0 }; > + float m_falloffIntercept { 0 };
You could group these into structs to make the comments obsolete.
> Source/WebKit/Shared/mac/ScrollingAccelerationCurveMac.mm:60 > +static ScrollingAccelerationCurve fromIOHIDCurveArrayWithAcceleration(NSArray *ioHIDCurves, float desiredAcceleration, float resolution)
Can the NSArray * be typed?
> Source/WebKit/Shared/mac/ScrollingAccelerationCurveMac.mm:86 > +std::optional<ScrollingAccelerationCurve> ScrollingAccelerationCurve::fromNativeWheelEvent(const NativeWebWheelEvent& nativeWebWheelEvent)
It's a bit weird to say that you're getting a curve from an event. I guess you're really getting a curve from the device associated with the event, so maybe split this into two functions?
> Source/WebKit/Shared/mac/ScrollingAccelerationCurveMac.mm:93 > + auto hidEvent = adoptCF(CGEventCopyIOHIDEvent(event.CGEvent));
Is CGEventCopyIOHIDEvent OK with a null CGEvent?
> Source/WebKit/UIProcess/WebPageProxy.h:3167 > +#if ENABLE(MOMENTUM_EVENT_DISPATCHER) > + std::optional<ScrollingAccelerationCurve> m_scrollingAccelerationCurve; > + std::optional<ScrollingAccelerationCurve> m_lastSentScrollingAccelerationCurve; > +#endif
Maybe we should bundle these up with: std::unique_ptr<WebWheelEventCoalescer> m_wheelEventCoalescer; PAL::HysteresisActivity m_wheelEventActivityHysteresis; into a wheel-event-related helper class.
> Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.cpp:50 > + stopDisplayLink();
You're sure this gets hit (no retain cycles?)
> Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.cpp:108 > + return isMomentumEventDuringSyntheticGesture;
I wish we used an enum value for "did this function handle the event" return values.
> Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.cpp:138 > + WebWheelEvent syntheticEvent(WebEvent::Wheel, m_currentGesture.initiatingEvent->position(), m_currentGesture.initiatingEvent->globalPosition(), appKitAcceleratedDelta, wheelTicks, WebWheelEvent::ScrollByPixelWheelEvent, m_currentGesture.initiatingEvent->directionInvertedFromDevice(), WebWheelEvent::PhaseNone, phase, true, m_currentGesture.initiatingEvent->scrollCount(), delta, m_lastIncomingEvent->modifiers(), time, time, { });
I would be inclined to put one arg on each line
> Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.cpp:172 > + RELEASE_LOG(ScrollAnimations, "MomentumEventDispatcher saw momentum end phase with total offset %f %f, duration %f (event offset would have been %f %f)", m_currentGesture.currentOffset.width(), m_currentGesture.currentOffset.height(), (WallTime::now() - m_currentGesture.startTime).seconds(), m_currentGesture.accumulatedEventOffset.width(), m_currentGesture.accumulatedEventOffset.height());
Maybe %.1f since they are all integral right?
> Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.cpp:174 > + stopDisplayLink();
Is mismatched start/stop a problem, if that ever happens?
> Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.cpp:184 > + WTF::TextStream stream(WTF::TextStream::LineMode::SingleLine); > + stream << curve;
Should remove this at some point. Maybe a TEMPORARY_LOGGING ifdef or something?
> Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.cpp:222 > +void MomentumEventDispatcher::windowScreenDidChange(WebCore::PageIdentifier pageID, WebCore::PlatformDisplayID displayID)
A bit odd that no argument references a window.
> Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.cpp:415 > + constexpr float velocityGainA = 2.f / 65536.0f; > + constexpr float velocityGainB = 955.f / 65536.0f; > + constexpr float velocityConstant = 98369.f / 65536.0f; > + constexpr float minimumVelocity = 1.f / 65536.0f;
Use fromFixedPoint()?
> Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.h:84 > + void didScrollWithInterval(FloatSize, Seconds); > + void didScroll(const WebWheelEvent&);
These aren't about scrolling (we have no idea if a scroll happened). They are about event processing I think?
> Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.h:93 > + typedef Deque<Delta, deltaHistoryQueueSize> HistoricalDeltas; > + HistoricalDeltas m_deltaHistoryX; > + HistoricalDeltas m_deltaHistoryY;
Can we use one deque of struct { FloatSize, Seconds }?
Tim Horton
Comment 6
2021-11-30 14:06:50 PST
(In reply to Simon Fraser (smfr) from
comment #5
)
> Comment on
attachment 445459
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=445459&action=review
> > > Source/WebKit/Shared/ScrollingAccelerationCurve.cpp:76 > > + return (4 * std::pow(x, 3) * std::pow(m_gainQuartic, 4)) + (3 * std::pow(x, 2) * std::pow(m_gainCubic, 3)) + (2 * x * std::pow(m_gainParabolic, 2)) + m_gainLinear; > > This calls std::pow(m_gainQuartic, 4) and std::pow(m_gainCubic, 3) on each > call, but that probably doesn't matter. > > > Source/WebKit/Shared/ScrollingAccelerationCurve.cpp:107 > > + constexpr float cursorScale = 96.f / frameRate; > > Any idea where the 96 comes from? The word "cursor" here is confusing.
Not yet.
> > Source/WebKit/Shared/ScrollingAccelerationCurve.h:42 > > +class ScrollingAccelerationCurve { > > AccelerationCurve or DecelerationCurve?
Acceleration (this is "how scroll events are accelerated from physical motion", NOT "how to decelerate for momentum")
> > Source/WebKit/Shared/ScrollingAccelerationCurve.h:91 > > + // Input parameters. > > + float m_gainLinear { 0 }; > > + float m_gainParabolic { 0 }; > > + float m_gainCubic { 0 }; > > + float m_gainQuartic { 0 }; > > + float m_tangentSpeedLinear { 0 }; > > + float m_tangentSpeedParabolicRoot { 0 }; > > + float m_resolution { 0 }; > > + > > + // Computed intermediate values. > > + bool m_hasComputedIntermediateValues { false }; > > + float m_tangentStartX { 0 }; > > + float m_tangentSlope { 0 }; > > + float m_tangentIntercept { 0 }; > > + float m_falloffStartX { 0 }; > > + float m_falloffSlope { 0 }; > > + float m_falloffIntercept { 0 }; > > You could group these into structs to make the comments obsolete.
True, I didn't pick up the inline struct thing when I wrote this, but did use it in MomentumEventDispatcher :)
> > Source/WebKit/Shared/mac/ScrollingAccelerationCurveMac.mm:60 > > +static ScrollingAccelerationCurve fromIOHIDCurveArrayWithAcceleration(NSArray *ioHIDCurves, float desiredAcceleration, float resolution) > > Can the NSArray * be typed?
NSArray<NSDictionary *> *, sure.
> > Source/WebKit/Shared/mac/ScrollingAccelerationCurveMac.mm:86 > > +std::optional<ScrollingAccelerationCurve> ScrollingAccelerationCurve::fromNativeWheelEvent(const NativeWebWheelEvent& nativeWebWheelEvent) > > It's a bit weird to say that you're getting a curve from an event. I guess > you're really getting a curve from the device associated with the event, so > maybe split this into two functions?
Heh, it used to be separate! I will put it back, I think it was better that way indeed.
> > Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.cpp:174 > > + stopDisplayLink(); > > Is mismatched start/stop a problem, if that ever happens?
It seems to be OK, but I will double check.
> > Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.cpp:222 > > +void MomentumEventDispatcher::windowScreenDidChange(WebCore::PageIdentifier pageID, WebCore::PlatformDisplayID displayID) > > A bit odd that no argument references a window.
Propagating existing odd naming, yes.
> > Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.h:93 > > + typedef Deque<Delta, deltaHistoryQueueSize> HistoricalDeltas; > > + HistoricalDeltas m_deltaHistoryX; > > + HistoricalDeltas m_deltaHistoryY; > > Can we use one deque of struct { FloatSize, Seconds }?
We cannot, because we clear it if direction changes, which is a per-axis thing (I have made this mistake at least twice now :))
Tim Horton
Comment 7
2021-11-30 14:46:59 PST
(In reply to Simon Fraser (smfr) from
comment #5
)
> Comment on
attachment 445459
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=445459&action=review
> > > Source/WebKit/Shared/ScrollingAccelerationCurve.cpp:76 > > + return (4 * std::pow(x, 3) * std::pow(m_gainQuartic, 4)) + (3 * std::pow(x, 2) * std::pow(m_gainCubic, 3)) + (2 * x * std::pow(m_gainParabolic, 2)) + m_gainLinear; > > This calls std::pow(m_gainQuartic, 4) and std::pow(m_gainCubic, 3) on each > call, but that probably doesn't matter.
It's only called once :) just shared between two branches.
Tim Horton
Comment 8
2021-11-30 15:37:28 PST
Created
attachment 445480
[details]
Patch
Tim Horton
Comment 9
2021-11-30 17:21:15 PST
Created
attachment 445492
[details]
Patch
EWS
Comment 10
2021-11-30 18:56:34 PST
Committed
r286346
(
244705@main
): <
https://commits.webkit.org/244705@main
> All reviewed patches have been landed. Closing bug and clearing flags on
attachment 445492
[details]
.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug