⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 286991 in webkit


Ignore:
Timestamp:
Dec 13, 2021, 3:49:02 PM (5 years ago)
Author:
Alan Coon
Message:

Cherry-pick r286919. rdar://problem/86247557

Momentum Event Dispatcher: Tail frames are the wrong velocity if momentum event dispatch rate doesn't match screen refresh rate
https://bugs.webkit.org/show_bug.cgi?id=234168
<rdar://problem/86247557>

Reviewed by Simon Fraser.

In r286671, I scaled the tail frames into the momentum event disaptch
rate, but they are actually always dispatched at display refresh
frequency. In many cases these things are the same, but in some
cases can differ (most commonly a 120Hz display with 60Hz event dispatch),
so to always have the tail move at the right rate, scale into the display
refresh rate instead).

  • UIProcess/WebPageProxy.cpp: (WebKit::WebPageProxy::windowScreenDidChange):
  • WebProcess/WebPage/EventDispatcher.cpp: (WebKit::EventDispatcher::pageScreenDidChange):
  • WebProcess/WebPage/EventDispatcher.h:
  • WebProcess/WebPage/EventDispatcher.messages.in:
  • WebProcess/WebPage/MomentumEventDispatcher.cpp: (WebKit::MomentumEventDispatcher::didStartMomentumPhase): (WebKit::MomentumEventDispatcher::displayProperties const): (WebKit::MomentumEventDispatcher::startDisplayLink): (WebKit::MomentumEventDispatcher::stopDisplayLink): (WebKit::MomentumEventDispatcher::pageScreenDidChange): (WebKit::MomentumEventDispatcher::displayWasRefreshed): (WebKit::MomentumEventDispatcher::displayID const): Deleted.
  • WebProcess/WebPage/MomentumEventDispatcher.h: Plumb and store the nominal display refresh rate.

(WebKit::MomentumEventDispatcher::buildOffsetTableWithInitialDelta):
Scale the tail frames from the 60Hz ideal rate into the display refresh
rate, instead of the event dispatch rate.

Incoming events still scale *in* from the event dispatch rate, since
that's... the rate they come at.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@286919 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Location:
branches/safari-612-branch/Source/WebKit
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • branches/safari-612-branch/Source/WebKit/ChangeLog

    r286977 r286991  
     12021-12-13  Alan Coon  <alancoon@apple.com>
     2
     3        Cherry-pick r286919. rdar://problem/86247557
     4
     5    Momentum Event Dispatcher: Tail frames are the wrong velocity if momentum event dispatch rate doesn't match screen refresh rate
     6    https://bugs.webkit.org/show_bug.cgi?id=234168
     7    <rdar://problem/86247557>
     8   
     9    Reviewed by Simon Fraser.
     10   
     11    In r286671, I scaled the tail frames into the momentum event disaptch
     12    rate, but they are actually always dispatched at display refresh
     13    frequency. In many cases these things are the same, but in some
     14    cases can differ (most commonly a 120Hz display with 60Hz event dispatch),
     15    so to always have the tail move at the right rate, scale into the display
     16    refresh rate instead).
     17   
     18    * UIProcess/WebPageProxy.cpp:
     19    (WebKit::WebPageProxy::windowScreenDidChange):
     20    * WebProcess/WebPage/EventDispatcher.cpp:
     21    (WebKit::EventDispatcher::pageScreenDidChange):
     22    * WebProcess/WebPage/EventDispatcher.h:
     23    * WebProcess/WebPage/EventDispatcher.messages.in:
     24    * WebProcess/WebPage/MomentumEventDispatcher.cpp:
     25    (WebKit::MomentumEventDispatcher::didStartMomentumPhase):
     26    (WebKit::MomentumEventDispatcher::displayProperties const):
     27    (WebKit::MomentumEventDispatcher::startDisplayLink):
     28    (WebKit::MomentumEventDispatcher::stopDisplayLink):
     29    (WebKit::MomentumEventDispatcher::pageScreenDidChange):
     30    (WebKit::MomentumEventDispatcher::displayWasRefreshed):
     31    (WebKit::MomentumEventDispatcher::displayID const): Deleted.
     32    * WebProcess/WebPage/MomentumEventDispatcher.h:
     33    Plumb and store the nominal display refresh rate.
     34   
     35    (WebKit::MomentumEventDispatcher::buildOffsetTableWithInitialDelta):
     36    Scale the tail frames from the 60Hz ideal rate into the display refresh
     37    rate, instead of the event dispatch rate.
     38   
     39    Incoming events still scale *in* from the event dispatch rate, since
     40    that's... the rate they come at.
     41   
     42   
     43    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@286919 268f45cc-cd09-0410-ab3c-d52691b4dbfc
     44
     45    2021-12-11  Tim Horton  <timothy_horton@apple.com>
     46
     47            Momentum Event Dispatcher: Tail frames are the wrong velocity if momentum event dispatch rate doesn't match screen refresh rate
     48            https://bugs.webkit.org/show_bug.cgi?id=234168
     49            <rdar://problem/86247557>
     50
     51            Reviewed by Simon Fraser.
     52
     53            In r286671, I scaled the tail frames into the momentum event disaptch
     54            rate, but they are actually always dispatched at display refresh
     55            frequency. In many cases these things are the same, but in some
     56            cases can differ (most commonly a 120Hz display with 60Hz event dispatch),
     57            so to always have the tail move at the right rate, scale into the display
     58            refresh rate instead).
     59
     60            * UIProcess/WebPageProxy.cpp:
     61            (WebKit::WebPageProxy::windowScreenDidChange):
     62            * WebProcess/WebPage/EventDispatcher.cpp:
     63            (WebKit::EventDispatcher::pageScreenDidChange):
     64            * WebProcess/WebPage/EventDispatcher.h:
     65            * WebProcess/WebPage/EventDispatcher.messages.in:
     66            * WebProcess/WebPage/MomentumEventDispatcher.cpp:
     67            (WebKit::MomentumEventDispatcher::didStartMomentumPhase):
     68            (WebKit::MomentumEventDispatcher::displayProperties const):
     69            (WebKit::MomentumEventDispatcher::startDisplayLink):
     70            (WebKit::MomentumEventDispatcher::stopDisplayLink):
     71            (WebKit::MomentumEventDispatcher::pageScreenDidChange):
     72            (WebKit::MomentumEventDispatcher::displayWasRefreshed):
     73            (WebKit::MomentumEventDispatcher::displayID const): Deleted.
     74            * WebProcess/WebPage/MomentumEventDispatcher.h:
     75            Plumb and store the nominal display refresh rate.
     76
     77            (WebKit::MomentumEventDispatcher::buildOffsetTableWithInitialDelta):
     78            Scale the tail frames from the 60Hz ideal rate into the display refresh
     79            rate, instead of the event dispatch rate.
     80
     81            Incoming events still scale *in* from the event dispatch rate, since
     82            that's... the rate they come at.
     83
    1842021-12-13  Alan Coon  <alancoon@apple.com>
    285
  • branches/safari-612-branch/Source/WebKit/UIProcess/WebPageProxy.cpp

    r286973 r286991  
    40174017        return;
    40184018
    4019     send(Messages::EventDispatcher::PageScreenDidChange(m_webPageID, displayID));
     4019    send(Messages::EventDispatcher::PageScreenDidChange(m_webPageID, displayID, nominalFramesPerSecond));
    40204020    send(Messages::WebPage::WindowScreenDidChange(displayID, nominalFramesPerSecond));
    40214021#if HAVE(CVDISPLAYLINK)
  • branches/safari-612-branch/Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp

    r286683 r286991  
    331331#endif
    332332
    333 void EventDispatcher::pageScreenDidChange(PageIdentifier pageID, PlatformDisplayID displayID)
    334 {
    335 #if ENABLE(MOMENTUM_EVENT_DISPATCHER)
    336     m_momentumEventDispatcher->pageScreenDidChange(pageID, displayID);
     333void EventDispatcher::pageScreenDidChange(PageIdentifier pageID, PlatformDisplayID displayID, std::optional<unsigned> nominalFramesPerSecond)
     334{
     335#if ENABLE(MOMENTUM_EVENT_DISPATCHER)
     336    m_momentumEventDispatcher->pageScreenDidChange(pageID, displayID, nominalFramesPerSecond);
    337337#else
    338338    UNUSED_PARAM(pageID);
  • branches/safari-612-branch/Source/WebKit/WebProcess/WebPage/EventDispatcher.h

    r286694 r286991  
    127127#endif
    128128
    129     void pageScreenDidChange(WebCore::PageIdentifier, WebCore::PlatformDisplayID);
     129    void pageScreenDidChange(WebCore::PageIdentifier, WebCore::PlatformDisplayID, std::optional<unsigned> nominalFramesPerSecond);
    130130
    131131    Ref<WorkQueue> m_queue;
  • branches/safari-612-branch/Source/WebKit/WebProcess/WebPage/EventDispatcher.messages.in

    r286683 r286991  
    3737    SetScrollingAccelerationCurve(WebCore::PageIdentifier pageID, std::optional<WebKit::ScrollingAccelerationCurve> curve)
    3838#endif
    39     PageScreenDidChange(WebCore::PageIdentifier pageID, uint32_t displayID)
     39    PageScreenDidChange(WebCore::PageIdentifier pageID, uint32_t displayID, std::optional<unsigned> nominalFramesPerSecond)
    4040}
  • branches/safari-612-branch/Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.cpp

    r286974 r286991  
    4141static constexpr Seconds deltaHistoryMaximumAge = 500_ms;
    4242static constexpr Seconds deltaHistoryMaximumInterval = 150_ms;
    43 static constexpr float idealCurveFrameRate = 60;
     43static constexpr WebCore::FramesPerSecond idealCurveFrameRate = 60;
    4444static constexpr Seconds idealCurveFrameInterval = 1_s / idealCurveFrameRate;
    4545
     
    185185void MomentumEventDispatcher::didStartMomentumPhase(WebCore::PageIdentifier pageIdentifier, const WebWheelEvent& event)
    186186{
     187    auto displayProperties = this->displayProperties(pageIdentifier);
     188    if (!displayProperties)
     189        return;
     190
    187191    tracePoint(SyntheticMomentumStart);
    188192
     
    194198    m_currentGesture.currentOffset = { };
    195199    m_currentGesture.startTime = MonotonicTime::now() - momentumStartInterval;
     200    m_currentGesture.displayNominalFrameRate = displayProperties->nominalFrameRate;
    196201    m_currentGesture.accelerationCurve = [&] () -> std::optional<ScrollingAccelerationCurve> {
    197202        auto curveIterator = m_accelerationCurves.find(m_currentGesture.pageIdentifier);
     
    242247}
    243248
    244 WebCore::PlatformDisplayID MomentumEventDispatcher::displayID() const
    245 {
    246     ASSERT(m_currentGesture.pageIdentifier);
    247     auto displayIDIterator = m_displayIDs.find(m_currentGesture.pageIdentifier);
    248     if (displayIDIterator == m_displayIDs.end())
    249         return { };
    250     return displayIDIterator->value;
     249std::optional<MomentumEventDispatcher::DisplayProperties> MomentumEventDispatcher::displayProperties(WebCore::PageIdentifier pageIdentifier) const
     250{
     251    ASSERT(pageIdentifier);
     252    auto displayPropertiesIterator = m_displayProperties.find(pageIdentifier);
     253    if (displayPropertiesIterator == m_displayProperties.end())
     254        return std::nullopt;
     255    return { displayPropertiesIterator->value };
    251256}
    252257
    253258void MomentumEventDispatcher::startDisplayLink()
    254259{
    255     auto displayID = this->displayID();
    256     if (!displayID) {
     260    auto displayProperties = this->displayProperties(m_currentGesture.pageIdentifier);
     261    if (!displayProperties) {
    257262        RELEASE_LOG(ScrollAnimations, "MomentumEventDispatcher failed to start display link");
    258263        return;
     
    260265
    261266    // FIXME: Switch down to lower-than-full-speed frame rates for the tail end of the curve.
    262     WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessProxy::StartDisplayLink(m_observerID, displayID, WebCore::FullSpeedFramesPerSecond), 0);
    263 #if ENABLE(MOMENTUM_EVENT_DISPATCHER_TEMPORARY_LOGGING)
    264     RELEASE_LOG(ScrollAnimations, "MomentumEventDispatcher starting display link for display %d", displayID);
     267    WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessProxy::StartDisplayLink(m_observerID, displayProperties->displayID, WebCore::FullSpeedFramesPerSecond), 0);
     268#if ENABLE(MOMENTUM_EVENT_DISPATCHER_TEMPORARY_LOGGING)
     269    RELEASE_LOG(ScrollAnimations, "MomentumEventDispatcher starting display link for display %d", displayProperties->displayID);
    265270#endif
    266271}
     
    268273void MomentumEventDispatcher::stopDisplayLink()
    269274{
    270     auto displayID = this->displayID();
    271     if (!displayID) {
     275    auto displayProperties = this->displayProperties(m_currentGesture.pageIdentifier);
     276    if (!displayProperties) {
    272277        RELEASE_LOG(ScrollAnimations, "MomentumEventDispatcher failed to stop display link");
    273278        return;
    274279    }
    275280
    276     WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessProxy::StopDisplayLink(m_observerID, displayID), 0);
    277 #if ENABLE(MOMENTUM_EVENT_DISPATCHER_TEMPORARY_LOGGING)
    278     RELEASE_LOG(ScrollAnimations, "MomentumEventDispatcher stopping display link for display %d", displayID);
    279 #endif
    280 }
    281 
    282 void MomentumEventDispatcher::pageScreenDidChange(WebCore::PageIdentifier pageID, WebCore::PlatformDisplayID displayID)
     281    WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessProxy::StopDisplayLink(m_observerID, displayProperties->displayID), 0);
     282#if ENABLE(MOMENTUM_EVENT_DISPATCHER_TEMPORARY_LOGGING)
     283    RELEASE_LOG(ScrollAnimations, "MomentumEventDispatcher stopping display link for display %d", displayProperties->displayID);
     284#endif
     285}
     286
     287void MomentumEventDispatcher::pageScreenDidChange(WebCore::PageIdentifier pageID, WebCore::PlatformDisplayID displayID, std::optional<unsigned> nominalFramesPerSecond)
    283288{
    284289    bool affectsCurrentGesture = (pageID == m_currentGesture.pageIdentifier);
     
    286291        stopDisplayLink();
    287292
    288     m_displayIDs.set(pageID, displayID);
     293    DisplayProperties properties;
     294    properties.displayID = displayID;
     295    properties.nominalFrameRate = nominalFramesPerSecond.value_or(WebCore::FullSpeedFramesPerSecond);
     296    m_displayProperties.set(pageID, WTFMove(properties));
    289297
    290298    if (affectsCurrentGesture)
     
    320328        return;
    321329
    322     if (displayID != this->displayID())
     330    auto displayProperties = this->displayProperties(m_currentGesture.pageIdentifier);
     331    if (!displayProperties || displayID != displayProperties->displayID)
    323332        return;
    324333
     
    371380    WebCore::FloatSize unacceleratedDelta = initialUnacceleratedDelta;
    372381
    373     float physicalCurveMultiplier = idealCurveFrameRate / m_currentGesture.accelerationCurve->frameRate();
     382    // Tail deltas will be dispatched at the screen refresh rate, not the momentum
     383    // dispatch rate, so we need to scale from 60Hz into screen refresh rate.
     384    float tailCurveMultiplier = static_cast<float>(idealCurveFrameRate) / m_currentGesture.displayNominalFrameRate;
    374385    bool inTail = false;
    375386    WebCore::FloatSize tailCarry;
     
    386397
    387398        if (inTail) {
    388             auto tailDelta = acceleratedDelta * physicalCurveMultiplier;
     399            auto tailDelta = acceleratedDelta * tailCurveMultiplier;
    389400            auto deltaWithCarry = tailDelta + tailCarry;
    390401            auto quantizedDelta = roundedIntSize(deltaWithCarry);
  • branches/safari-612-branch/Source/WebKit/WebProcess/WebPage/MomentumEventDispatcher.h

    r286701 r286991  
    4343namespace WebCore {
    4444struct DisplayUpdate;
     45using FramesPerSecond = unsigned;
    4546using PlatformDisplayID = uint32_t;
    4647}
     
    6364    void displayWasRefreshed(WebCore::PlatformDisplayID, const WebCore::DisplayUpdate&);
    6465
    65     void pageScreenDidChange(WebCore::PageIdentifier, WebCore::PlatformDisplayID);
     66    void pageScreenDidChange(WebCore::PageIdentifier, WebCore::PlatformDisplayID, std::optional<unsigned> nominalFramesPerSecond);
    6667
    6768private:
     
    7475    void stopDisplayLink();
    7576
    76     WebCore::PlatformDisplayID displayID() const;
     77    struct DisplayProperties {
     78        WebCore::PlatformDisplayID displayID;
     79        WebCore::FramesPerSecond nominalFrameRate;
     80    };
     81    std::optional<DisplayProperties> displayProperties(WebCore::PageIdentifier) const;
    7782
    7883    void dispatchSyntheticMomentumEvent(WebWheelEvent::Phase, WebCore::FloatSize delta);
     
    138143        unsigned currentTailDeltaIndex { 0 };
    139144
     145        WebCore::FramesPerSecond displayNominalFrameRate { 0 };
     146
    140147#if ENABLE(MOMENTUM_EVENT_DISPATCHER_TEMPORARY_LOGGING)
    141148        WebCore::FloatSize accumulatedEventOffset;
     
    149156
    150157    DisplayLinkObserverID m_observerID;
    151     HashMap<WebCore::PageIdentifier, WebCore::PlatformDisplayID> m_displayIDs;
     158
     159    HashMap<WebCore::PageIdentifier, DisplayProperties> m_displayProperties;
    152160    HashMap<WebCore::PageIdentifier, std::optional<ScrollingAccelerationCurve>> m_accelerationCurves;
    153161    EventDispatcher& m_dispatcher;
Note: See TracChangeset for help on using the changeset viewer.