Changeset 275440 in webkit


Ignore:
Timestamp:
Apr 2, 2021 2:29:13 PM (16 months ago)
Author:
Simon Fraser
Message:

Allow wheel events to trigger high frequency DisplayLinks
https://bugs.webkit.org/show_bug.cgi?id=224095

Reviewed by Sam Weinig.

Source/WebCore:

Adjust some logging so it's clear which process code is running in.

  • platform/graphics/DisplayRefreshMonitor.cpp:

(WebCore::DisplayRefreshMonitor::displayLinkFired):

  • platform/graphics/DisplayRefreshMonitorManager.cpp:

(WebCore::DisplayRefreshMonitorManager::ensureMonitorForDisplayID):

Source/WebKit:

When scrolling via wheel events, we may want to drive scrolling tree updates
(which are driven by EventDispatcher::displayWasRefreshed()) at a higher rate
than the main thread does rendering updates.

To support this, give DisplayLink a count of "full speed" clients, and when this count is
greater than zero, have DisplayLink::notifyObserversDisplayWasRefreshed() send
EventDispatcher IPC at full framerate, while passing a flag based on the usual
relevantForUpdateFrequency() about whether to update the main thread for a given update.

Allow DisplayLink connection info objects with non-zero fullSpeedUpdatesClientCount
to stick around, because that fullSpeedUpdatesClientCount needs to be stored for
connections that may not yet have observers.

Since DisplayLink might have info for connections with no observers, adjust the logic in
DisplayLink::notifyObserversDisplayWasRefreshed() to do the CVDisplayLinkStop
after traversing the observers.

The "full speed" client count is maintained by a HysteresisActivity on WebPageProxy,
whose impulse is wheel events. This replaces a singleton HysteresisActivity which
was used to determine whether IPC goes to EventDispatcher or the main thread of
the web process.

WebPageProxy needs to track the PlatformDisplayID for the screen that its view is on,
so it knows which DisplayLink to message.

  • UIProcess/Cocoa/WebProcessPoolCocoa.mm:

(WebKit::WebProcessPool::setDisplayLinkForDisplayWantsFullSpeedUpdates):

  • UIProcess/WebPageProxy.cpp:

(WebKit::m_wheelEventActivityHysteresis):
(WebKit::WebPageProxy::wheelEventHysteresisUpdated):
(WebKit::WebPageProxy::sendWheelEvent):
(WebKit::WebPageProxy::windowScreenDidChange):
(WebKit::ScrollingObserver::willSendWheelEvent): Deleted.
(WebKit::ScrollingObserver::ScrollingObserver): Deleted.
(WebKit::ScrollingObserver::singleton): Deleted.

  • UIProcess/WebPageProxy.h:
  • UIProcess/WebProcessPool.h:
  • UIProcess/mac/DisplayLink.cpp:

(WebKit::DisplayLink::DisplayLink):
(WebKit::DisplayLink::~DisplayLink):
(WebKit::DisplayLink::addObserver):
(WebKit::DisplayLink::removeObserver):
(WebKit::DisplayLink::removeInfoForConnectionIfPossible):
(WebKit::DisplayLink::incrementFullSpeedRequestClientCount):
(WebKit::DisplayLink::decrementFullSpeedRequestClientCount):
(WebKit::DisplayLink::setPreferredFramesPerSecond):
(WebKit::DisplayLink::notifyObserversDisplayWasRefreshed):

  • UIProcess/mac/DisplayLink.h:
  • WebProcess/WebPage/EventDispatcher.cpp:

(WebKit::EventDispatcher::displayWasRefreshed):

  • WebProcess/WebPage/EventDispatcher.h:
  • WebProcess/WebPage/EventDispatcher.messages.in:
  • WebProcess/WebPage/mac/DisplayRefreshMonitorMac.cpp:

(WebKit::DisplayRefreshMonitorMac::startNotificationMechanism):
(WebKit::DisplayRefreshMonitorMac::adjustPreferredFramesPerSecond):

Location:
trunk/Source
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r275436 r275440  
     12021-04-02  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Allow wheel events to trigger high frequency DisplayLinks
     4        https://bugs.webkit.org/show_bug.cgi?id=224095
     5
     6        Reviewed by Sam Weinig.
     7
     8        Adjust some logging so it's clear which process code is running in.
     9
     10        * platform/graphics/DisplayRefreshMonitor.cpp:
     11        (WebCore::DisplayRefreshMonitor::displayLinkFired):
     12        * platform/graphics/DisplayRefreshMonitorManager.cpp:
     13        (WebCore::DisplayRefreshMonitorManager::ensureMonitorForDisplayID):
     14
    1152021-04-02  David Kilzer  <ddkilzer@apple.com>
    216
  • trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitor.cpp

    r275345 r275440  
    173173            return;
    174174
    175         LOG_WITH_STREAM(DisplayLink, stream << "DisplayRefreshMonitor::displayLinkFired for display " << displayID() << " - scheduled " << isScheduled() << " unscheduledFireCount " << m_unscheduledFireCount << " of " << m_maxUnscheduledFireCount);
     175        LOG_WITH_STREAM(DisplayLink, stream << "[Web] DisplayRefreshMonitor::displayLinkFired for display " << displayID() << " - scheduled " << isScheduled() << " unscheduledFireCount " << m_unscheduledFireCount << " of " << m_maxUnscheduledFireCount);
    176176        if (firedAndReachedMaxUnscheduledFireCount()) {
    177177            stopNotificationMechanism();
  • trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitorManager.cpp

    r275345 r275440  
    5151        return nullptr;
    5252
    53     LOG_WITH_STREAM(DisplayLink, stream << "DisplayRefreshMonitorManager::ensureMonitorForDisplayID() - created monitor " << monitor.get() << " for display " << displayID);
     53    LOG_WITH_STREAM(DisplayLink, stream << "[Web] DisplayRefreshMonitorManager::ensureMonitorForDisplayID() - created monitor " << monitor.get() << " for display " << displayID);
    5454    DisplayRefreshMonitor* result = monitor.get();
    5555    m_monitors.append({ WTFMove(monitor) });
  • trunk/Source/WebKit/ChangeLog

    r275434 r275440  
     12021-04-01  Simon Fraser  <simon.fraser@apple.com>
     2
     3        Allow wheel events to trigger high frequency DisplayLinks
     4        https://bugs.webkit.org/show_bug.cgi?id=224095
     5
     6        Reviewed by Sam Weinig.
     7
     8        When scrolling via wheel events, we may want to drive scrolling tree updates
     9        (which are driven by EventDispatcher::displayWasRefreshed()) at a higher rate
     10        than the main thread does rendering updates.
     11
     12        To support this, give DisplayLink a count of "full speed" clients, and when this count is
     13        greater than zero, have DisplayLink::notifyObserversDisplayWasRefreshed() send
     14        EventDispatcher IPC at full framerate, while passing a flag based on the usual
     15        relevantForUpdateFrequency() about whether to update the main thread for a given update.
     16
     17        Allow DisplayLink connection info objects with non-zero fullSpeedUpdatesClientCount
     18        to stick around, because that fullSpeedUpdatesClientCount needs to be stored for
     19        connections that may not yet have observers.
     20
     21        Since DisplayLink might have info for connections with no observers, adjust the logic in
     22        DisplayLink::notifyObserversDisplayWasRefreshed() to do the CVDisplayLinkStop
     23        after traversing the observers.
     24
     25        The "full speed" client count is maintained by a HysteresisActivity on WebPageProxy,
     26        whose impulse is wheel events. This replaces a singleton HysteresisActivity which
     27        was used to determine whether IPC goes to EventDispatcher or the main thread of
     28        the web process.
     29
     30        WebPageProxy needs to track the PlatformDisplayID for the screen that its view is on,
     31        so it knows which DisplayLink to message.
     32
     33        * UIProcess/Cocoa/WebProcessPoolCocoa.mm:
     34        (WebKit::WebProcessPool::setDisplayLinkForDisplayWantsFullSpeedUpdates):
     35        * UIProcess/WebPageProxy.cpp:
     36        (WebKit::m_wheelEventActivityHysteresis):
     37        (WebKit::WebPageProxy::wheelEventHysteresisUpdated):
     38        (WebKit::WebPageProxy::sendWheelEvent):
     39        (WebKit::WebPageProxy::windowScreenDidChange):
     40        (WebKit::ScrollingObserver::willSendWheelEvent): Deleted.
     41        (WebKit::ScrollingObserver::ScrollingObserver): Deleted.
     42        (WebKit::ScrollingObserver::singleton): Deleted.
     43        * UIProcess/WebPageProxy.h:
     44        * UIProcess/WebProcessPool.h:
     45        * UIProcess/mac/DisplayLink.cpp:
     46        (WebKit::DisplayLink::DisplayLink):
     47        (WebKit::DisplayLink::~DisplayLink):
     48        (WebKit::DisplayLink::addObserver):
     49        (WebKit::DisplayLink::removeObserver):
     50        (WebKit::DisplayLink::removeInfoForConnectionIfPossible):
     51        (WebKit::DisplayLink::incrementFullSpeedRequestClientCount):
     52        (WebKit::DisplayLink::decrementFullSpeedRequestClientCount):
     53        (WebKit::DisplayLink::setPreferredFramesPerSecond):
     54        (WebKit::DisplayLink::notifyObserversDisplayWasRefreshed):
     55        * UIProcess/mac/DisplayLink.h:
     56        * WebProcess/WebPage/EventDispatcher.cpp:
     57        (WebKit::EventDispatcher::displayWasRefreshed):
     58        * WebProcess/WebPage/EventDispatcher.h:
     59        * WebProcess/WebPage/EventDispatcher.messages.in:
     60        * WebProcess/WebPage/mac/DisplayRefreshMonitorMac.cpp:
     61        (WebKit::DisplayRefreshMonitorMac::startNotificationMechanism):
     62        (WebKit::DisplayRefreshMonitorMac::adjustPreferredFramesPerSecond):
     63
    1642021-04-02  Chris Dumez  <cdumez@apple.com>
    265
  • trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm

    r275345 r275440  
    821821    }
    822822}
     823
     824void WebProcessPool::setDisplayLinkForDisplayWantsFullSpeedUpdates(IPC::Connection& connection, WebCore::PlatformDisplayID displayID, bool wantsFullSpeedUpdates)
     825{
     826    for (auto& displayLink : m_displayLinks) {
     827        if (displayLink->displayID() == displayID) {
     828            if (wantsFullSpeedUpdates)
     829                displayLink->incrementFullSpeedRequestClientCount(connection);
     830            else
     831                displayLink->decrementFullSpeedRequestClientCount(connection);
     832            return;
     833        }
     834    }
     835}
     836
    823837#endif // HAVE(CVDISPLAYLINK)
    824838
  • trunk/Source/WebKit/UIProcess/WebPageProxy.cpp

    r275434 r275440  
    186186#include <WebCore/WindowFeatures.h>
    187187#include <WebCore/WritingDirection.h>
    188 #include <pal/HysteresisActivity.h>
    189188#include <stdio.h>
    190189#include <wtf/CallbackAggregator.h>
     
    324323
    325324DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageProxyCounter, ("WebPageProxy"));
    326 
    327 #if HAVE(CVDISPLAYLINK)
    328 class ScrollingObserver {
    329     WTF_MAKE_NONCOPYABLE(ScrollingObserver);
    330     WTF_MAKE_FAST_ALLOCATED;
    331     friend NeverDestroyed<ScrollingObserver>;
    332 public:
    333     static ScrollingObserver& singleton();
    334 
    335     void willSendWheelEvent()
    336     {
    337         m_hysteresis.impulse();
    338     }
    339 
    340 private:
    341     ScrollingObserver()
    342         : m_hysteresis([](PAL::HysteresisState state) { DisplayLink::setShouldSendIPCOnBackgroundQueue(state == PAL::HysteresisState::Started); })
    343     {
    344     }
    345 
    346     PAL::HysteresisActivity m_hysteresis;
    347 };
    348 
    349 ScrollingObserver& ScrollingObserver::singleton()
    350 {
    351     static NeverDestroyed<ScrollingObserver> detector;
    352     return detector;
    353 }
    354 #endif
    355325
    356326class StorageRequests {
     
    513483    , m_waitsForPaintAfterViewDidMoveToWindow(m_configuration->waitsForPaintAfterViewDidMoveToWindow())
    514484    , m_hasRunningProcess(process.state() != WebProcessProxy::State::Terminated)
     485#if HAVE(CVDISPLAYLINK)
     486    , m_wheelEventActivityHysteresis([this](PAL::HysteresisState state) { wheelEventHysteresisUpdated(state); })
     487#endif
    515488    , m_controlledByAutomation(m_configuration->isControlledByAutomation())
    516489#if PLATFORM(COCOA)
     
    27572730}
    27582731
     2732#if HAVE(CVDISPLAYLINK)
     2733void WebPageProxy::wheelEventHysteresisUpdated(PAL::HysteresisState state)
     2734{
     2735    if (!m_process->hasConnection() || !m_displayID)
     2736        return;
     2737
     2738    bool wantsFullSpeedUpdates = state == PAL::HysteresisState::Started;
     2739    process().processPool().setDisplayLinkForDisplayWantsFullSpeedUpdates(*m_process->connection(), *m_displayID, wantsFullSpeedUpdates);
     2740}
     2741#endif
     2742
    27592743void WebPageProxy::sendWheelEvent(const WebWheelEvent& event)
    27602744{
    27612745#if HAVE(CVDISPLAYLINK)
    2762     ScrollingObserver::singleton().willSendWheelEvent();
     2746    m_wheelEventActivityHysteresis.impulse();
    27632747#endif
    27642748
     
    37773761void WebPageProxy::windowScreenDidChange(PlatformDisplayID displayID, Optional<unsigned> nominalFramesPerSecond)
    37783762{
     3763    m_displayID = displayID;
     3764
    37793765    if (!hasRunningProcess())
    37803766        return;
  • trunk/Source/WebKit/UIProcess/WebPageProxy.h

    r275434 r275440  
    113113#include <WebCore/ViewportArguments.h>
    114114#include <memory>
     115#include <pal/HysteresisActivity.h>
    115116#include <wtf/CompletionHandler.h>
    116117#include <wtf/FileSystem.h>
     
    23012302    WebWheelEventCoalescer& wheelEventCoalescer();
    23022303
     2304#if HAVE(CVDISPLAYLINK)
     2305    void wheelEventHysteresisUpdated(PAL::HysteresisState);
     2306#endif
     2307
    23032308#if ENABLE(TOUCH_EVENTS)
    23042309    void updateTouchEventTracking(const WebTouchEvent&);
     
    26602665    std::unique_ptr<WebWheelEventCoalescer> m_wheelEventCoalescer;
    26612666
     2667    Optional<WebCore::PlatformDisplayID> m_displayID;
     2668#if HAVE(CVDISPLAYLINK)
     2669    PAL::HysteresisActivity m_wheelEventActivityHysteresis;
     2670#endif
     2671
    26622672    Deque<NativeWebMouseEvent> m_mouseEventQueue;
    26632673    Deque<NativeWebKeyboardEvent> m_keyEventQueue;
  • trunk/Source/WebKit/UIProcess/WebProcessPool.h

    r275389 r275440  
    244244    void setDisplayLinkPreferredFramesPerSecond(IPC::Connection&, DisplayLinkObserverID, WebCore::PlatformDisplayID, WebCore::FramesPerSecond);
    245245    void stopDisplayLinks(IPC::Connection&);
     246
     247    void setDisplayLinkForDisplayWantsFullSpeedUpdates(IPC::Connection&, WebCore::PlatformDisplayID, bool wantsFullSpeedUpdates);
    246248#endif
    247249
  • trunk/Source/WebKit/UIProcess/mac/DisplayLink.cpp

    r275345 r275440  
    6161    m_displayNominalFramesPerSecond = nominalFramesPerSecondFromDisplayLink(m_displayLink);
    6262
    63     LOG_WITH_STREAM(DisplayLink, stream << "[UI ] Creating DisplayLink for display " << displayID << " with nominal fps " << m_displayNominalFramesPerSecond);
     63    LOG_WITH_STREAM(DisplayLink, stream << "[UI ] Created DisplayLink " << this << " for display " << displayID << " with nominal fps " << m_displayNominalFramesPerSecond);
    6464}
    6565
    6666DisplayLink::~DisplayLink()
    6767{
    68     LOG_WITH_STREAM(DisplayLink, stream << "[UI ] Destroying DisplayLink for display " << m_displayID);
     68    LOG_WITH_STREAM(DisplayLink, stream << "[UI ] Destroying DisplayLink " << this << " for display " << m_displayID);
    6969
    7070    ASSERT(hasProcessPrivilege(ProcessPrivilege::CanCommunicateWithWindowServer));
     
    8787    ASSERT(RunLoop::isMain());
    8888
     89    LOG_WITH_STREAM(DisplayLink, stream << "[UI ] DisplayLink " << this << " for display display " << m_displayID << " add observer " << observerID << " fps " << preferredFramesPerSecond);
     90
    8991    {
    9092        auto locker = holdLock(m_observersLock);
    9193        m_observers.ensure(&connection, [] {
    92             return Vector<ObserverInfo> { };
    93         }).iterator->value.append({ observerID, preferredFramesPerSecond });
     94            return ConnectionClientInfo { };
     95        }).iterator->value.observers.append({ observerID, preferredFramesPerSecond });
    9496    }
    9597
     
    113115    if (it == m_observers.end())
    114116        return;
    115     bool removed = it->value.removeFirstMatching([observerID](const auto& value) {
     117
     118    auto& connectionInfo = it->value;
     119
     120    bool removed = connectionInfo.observers.removeFirstMatching([observerID](const auto& value) {
    116121        return value.observerID == observerID;
    117122    });
    118123    ASSERT_UNUSED(removed, removed);
    119     if (it->value.isEmpty())
    120         m_observers.remove(it);
     124
     125    LOG_WITH_STREAM(DisplayLink, stream << "[UI ] DisplayLink " << this << " for display " << m_displayID << " remove observer " << observerID);
     126
     127    removeInfoForConnectionIfPossible(connection);
    121128
    122129    // We do not stop the display link right away when |m_observers| becomes empty. Instead, we
     
    137144}
    138145
     146void DisplayLink::removeInfoForConnectionIfPossible(IPC::Connection& connection)
     147{
     148    auto it = m_observers.find(&connection);
     149    if (it == m_observers.end())
     150        return;
     151
     152    auto& connectionInfo = it->value;
     153    if (connectionInfo.observers.isEmpty() && !connectionInfo.fullSpeedUpdatesClientCount)
     154        m_observers.remove(it);
     155}
     156
     157void DisplayLink::incrementFullSpeedRequestClientCount(IPC::Connection& connection)
     158{
     159    auto locker = holdLock(m_observersLock);
     160
     161    auto& connectionInfo = m_observers.ensure(&connection, [] {
     162        return ConnectionClientInfo { };
     163    }).iterator->value;;
     164
     165    ++connectionInfo.fullSpeedUpdatesClientCount;
     166}
     167
     168void DisplayLink::decrementFullSpeedRequestClientCount(IPC::Connection& connection)
     169{
     170    auto locker = holdLock(m_observersLock);
     171
     172    auto it = m_observers.find(&connection);
     173    if (it == m_observers.end())
     174        return;
     175
     176    auto& connectionInfo = it->value;
     177    ASSERT(connectionInfo.fullSpeedUpdatesClientCount);
     178    --connectionInfo.fullSpeedUpdatesClientCount;
     179    removeInfoForConnectionIfPossible(connection);
     180}
     181
    139182void DisplayLink::setPreferredFramesPerSecond(IPC::Connection& connection, DisplayLinkObserverID observerID, WebCore::FramesPerSecond preferredFramesPerSecond)
    140183{
    141     LOG_WITH_STREAM(DisplayLink, stream << "[UI ] DisplayLink::setPreferredFramesPerSecond - display " << m_displayID << " observer " << observerID << " fps " << preferredFramesPerSecond);
    142 
    143     auto locker = holdLock(m_observersLock);
    144 
    145     auto it = m_observers.find(&connection);
    146     if (it == m_observers.end())
    147         return;
    148 
    149     auto index = it->value.findMatching([observerID](const auto& observer) {
     184    LOG_WITH_STREAM(DisplayLink, stream << "[UI ] DisplayLink " << this << " setPreferredFramesPerSecond - display " << m_displayID << " observer " << observerID << " fps " << preferredFramesPerSecond);
     185
     186    auto locker = holdLock(m_observersLock);
     187
     188    auto it = m_observers.find(&connection);
     189    if (it == m_observers.end())
     190        return;
     191
     192    auto& connectionInfo = it->value;
     193    auto index = connectionInfo.observers.findMatching([observerID](const auto& observer) {
    150194        return observer.observerID == observerID;
    151195    });
    152196
    153197    if (index != notFound)
    154         it->value[index].preferredFramesPerSecond = preferredFramesPerSecond;
     198        connectionInfo.observers[index].preferredFramesPerSecond = preferredFramesPerSecond;
    155199}
    156200
     
    166210
    167211    auto locker = holdLock(m_observersLock);
    168     if (m_observers.isEmpty()) {
    169         if (++m_fireCountWithoutObservers >= maxFireCountWithoutObservers) {
    170             LOG_WITH_STREAM(DisplayLink, stream << "[UI ] DisplayLink for display " << m_displayID << " fired " << m_fireCountWithoutObservers << " times with no observers; stopping CVDisplayLink");
    171             CVDisplayLinkStop(m_displayLink);
    172         }
    173         return;
    174     }
    175     m_fireCountWithoutObservers = 0;
    176212
    177213    auto maxFramesPerSecond = [](const Vector<ObserverInfo>& observers) {
     
    182218    };
    183219
    184     for (auto& [connection, observers] : m_observers) {
    185         auto observersMaxFramesPerSecond = maxFramesPerSecond(observers);
    186         auto updateIsRelevant = m_currentUpdate.relevantForUpdateFrequency(observersMaxFramesPerSecond.valueOr(WebCore::FullSpeedFramesPerSecond));
    187 
    188         LOG_WITH_STREAM(DisplayLink, stream << "[UI ] DisplayLink for display " << m_displayID << " (display fps " << m_displayNominalFramesPerSecond << ") update " << m_currentUpdate << " " << observers.size()
    189             << " observers, on background queue " << shouldSendIPCOnBackgroundQueue << " maxFramesPerSecond " << observersMaxFramesPerSecond << " relevant " << updateIsRelevant);
    190 
    191         if (!updateIsRelevant)
     220    bool anyConnectionHadObservers = false;
     221    for (auto& [connection, connectionInfo] : m_observers) {
     222        if (connectionInfo.observers.isEmpty())
    192223            continue;
    193224
    194         if (shouldSendIPCOnBackgroundQueue)
    195             connection->send(Messages::EventDispatcher::DisplayWasRefreshed(m_displayID, m_currentUpdate), 0);
    196         else
     225        anyConnectionHadObservers = true;
     226
     227        auto observersMaxFramesPerSecond = maxFramesPerSecond(connectionInfo.observers);
     228        auto mainThreadWantsUpdate = m_currentUpdate.relevantForUpdateFrequency(observersMaxFramesPerSecond.valueOr(WebCore::FullSpeedFramesPerSecond));
     229
     230        LOG_WITH_STREAM(DisplayLink, stream << "[UI ] DisplayLink " << this << " for display " << m_displayID << " (display fps " << m_displayNominalFramesPerSecond << ") update " << m_currentUpdate << " " << connectionInfo.observers.size()
     231            << " observers, on background queue " << shouldSendIPCOnBackgroundQueue << " maxFramesPerSecond " << observersMaxFramesPerSecond << " full speed clients " << connectionInfo.fullSpeedUpdatesClientCount << " relevant " << mainThreadWantsUpdate);
     232
     233        if (connectionInfo.fullSpeedUpdatesClientCount) {
     234            connection->send(Messages::EventDispatcher::DisplayWasRefreshed(m_displayID, m_currentUpdate, mainThreadWantsUpdate), 0);
     235        } else if (mainThreadWantsUpdate)
    197236            connection->send(Messages::WebProcess::DisplayWasRefreshed(m_displayID, m_currentUpdate), 0);
    198237    }
    199238
    200239    m_currentUpdate = m_currentUpdate.nextUpdate();
     240
     241    if (!anyConnectionHadObservers) {
     242        if (++m_fireCountWithoutObservers >= maxFireCountWithoutObservers) {
     243            LOG_WITH_STREAM(DisplayLink, stream << "[UI ] DisplayLink for display " << m_displayID << " fired " << m_fireCountWithoutObservers << " times with no observers; stopping CVDisplayLink");
     244            CVDisplayLinkStop(m_displayLink);
     245        }
     246        return;
     247    }
     248    m_fireCountWithoutObservers = 0;
    201249}
    202250
  • trunk/Source/WebKit/UIProcess/mac/DisplayLink.h

    r275345 r275440  
    5252    void removeObservers(IPC::Connection&);
    5353
     54    void incrementFullSpeedRequestClientCount(IPC::Connection&);
     55    void decrementFullSpeedRequestClientCount(IPC::Connection&);
     56
    5457    void setPreferredFramesPerSecond(IPC::Connection&, DisplayLinkObserverID, WebCore::FramesPerSecond);
    5558
     
    6568    static CVReturn displayLinkCallback(CVDisplayLinkRef, const CVTimeStamp*, const CVTimeStamp*, CVOptionFlags, CVOptionFlags*, void* data);
    6669    void notifyObserversDisplayWasRefreshed();
    67    
     70
     71    void removeInfoForConnectionIfPossible(IPC::Connection&);
     72
    6873    static WebCore::FramesPerSecond nominalFramesPerSecondFromDisplayLink(CVDisplayLinkRef);
    6974
     
    7277        WebCore::FramesPerSecond preferredFramesPerSecond;
    7378    };
     79   
     80    struct ConnectionClientInfo {
     81        unsigned fullSpeedUpdatesClientCount { 0 };
     82        Vector<ObserverInfo> observers;
     83    };
    7484
    7585    CVDisplayLinkRef m_displayLink { nullptr };
    7686    Lock m_observersLock;
    77     HashMap<RefPtr<IPC::Connection>, Vector<ObserverInfo>> m_observers;
     87    HashMap<RefPtr<IPC::Connection>, ConnectionClientInfo> m_observers;
    7888    WebCore::PlatformDisplayID m_displayID;
    7989    WebCore::FramesPerSecond m_displayNominalFramesPerSecond { 0 };
  • trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp

    r275163 r275440  
    290290
    291291#if HAVE(CVDISPLAYLINK)
    292 void EventDispatcher::displayWasRefreshed(PlatformDisplayID displayID, const DisplayUpdate& displayUpdate)
     292void EventDispatcher::displayWasRefreshed(PlatformDisplayID displayID, const DisplayUpdate& displayUpdate, bool sendToMainThread)
    293293{
    294294    ASSERT(!RunLoop::isMain());
    295295    notifyScrollingTreesDisplayWasRefreshed(displayID);
     296
     297    if (!sendToMainThread)
     298        return;
    296299
    297300    RunLoop::main().dispatch([displayID, displayUpdate]() {
  • trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.h

    r275163 r275440  
    109109
    110110#if PLATFORM(MAC)
    111     void displayWasRefreshed(WebCore::PlatformDisplayID, const WebCore::DisplayUpdate&);
     111    void displayWasRefreshed(WebCore::PlatformDisplayID, const WebCore::DisplayUpdate&, bool sendToMainThread);
    112112#endif
    113113
  • trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.messages.in

    r275163 r275440  
    3131#endif
    3232#if HAVE(CVDISPLAYLINK)
    33     DisplayWasRefreshed(uint32_t displayID, struct WebCore::DisplayUpdate update)
     33    DisplayWasRefreshed(uint32_t displayID, struct WebCore::DisplayUpdate update, bool sendToMainThread)
    3434#endif
    3535}
  • trunk/Source/WebKit/WebProcess/WebPage/mac/DisplayRefreshMonitorMac.cpp

    r275345 r275440  
    7272        return true;
    7373
    74     LOG_WITH_STREAM(DisplayLink, stream << "DisplayRefreshMonitorMac::requestRefreshCallback - starting");
     74    LOG_WITH_STREAM(DisplayLink, stream << "[Web ] DisplayRefreshMonitorMac::requestRefreshCallback for display " << displayID() << " - starting");
    7575    WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessProxy::StartDisplayLink(m_observerID, displayID(), maxClientPreferredFramesPerSecond().valueOr(FullSpeedFramesPerSecond)), 0);
    7676    if (!m_runLoopObserver) {
     
    101101void DisplayRefreshMonitorMac::adjustPreferredFramesPerSecond(FramesPerSecond preferredFramesPerSecond)
    102102{
    103     LOG_WITH_STREAM(DisplayLink, stream << "DisplayRefreshMonitorMac::adjustPreferredFramesPerSecond for display link on display " << displayID() << " to " << preferredFramesPerSecond);
     103    LOG_WITH_STREAM(DisplayLink, stream << "[Web] DisplayRefreshMonitorMac::adjustPreferredFramesPerSecond for display link on display " << displayID() << " to " << preferredFramesPerSecond);
    104104    WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessProxy::SetDisplayLinkPreferredFramesPerSecond(m_observerID, displayID(), preferredFramesPerSecond), 0);
    105105
Note: See TracChangeset for help on using the changeset viewer.