Changeset 266771 in webkit


Ignore:
Timestamp:
Sep 8, 2020 9:12:33 PM (4 years ago)
Author:
Chris Dumez
Message:

Regression(r260614) Power usage has increased due to extra thread hopping
https://bugs.webkit.org/show_bug.cgi?id=216296
<rdar://problem/67719299>

Reviewed by Simon Fraser.

Power usage has increased after r260614 due to extra thread hopping. To recover,
we now process the DisplayWasRefreshed IPC to a background queue if there is
scrolling going on and responsiveness is thus critical. In the common case, where
the user is not scrolling, we keep processing the IPC on the main thread, like
before r260614. This avoids extra thread hopping and saves power.

  • UIProcess/WebPageProxy.cpp:

(WebKit::ScrollingObserver::willSendWheelEvent):
(WebKit::ScrollingObserver::ScrollingObserver):
(WebKit::ScrollingObserver::singleton):
(WebKit::WebPageProxy::sendWheelEvent):

  • UIProcess/mac/DisplayLink.cpp:

(WebKit::DisplayLink::displayLinkCallback):

  • UIProcess/mac/DisplayLink.h:

(WebKit::DisplayLink::setShouldSendIPCOnBackgroundQueue):

  • WebProcess/WebPage/EventDispatcher.cpp:

(WebKit::EventDispatcher::notifyScrollingTreesDisplayWasRefreshed):
(WebKit::EventDispatcher::displayWasRefreshed):

  • WebProcess/WebPage/EventDispatcher.h:
  • WebProcess/WebProcess.cpp:

(WebKit::WebProcess::displayWasRefreshed):

  • WebProcess/WebProcess.h:
  • WebProcess/WebProcess.messages.in:
Location:
trunk/Source/WebKit
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r266766 r266771  
     12020-09-08  Chris Dumez  <cdumez@apple.com>
     2
     3        Regression(r260614) Power usage has increased due to extra thread hopping
     4        https://bugs.webkit.org/show_bug.cgi?id=216296
     5        <rdar://problem/67719299>
     6
     7        Reviewed by Simon Fraser.
     8
     9        Power usage has increased after r260614 due to extra thread hopping. To recover,
     10        we now process the DisplayWasRefreshed IPC to a background queue if there is
     11        scrolling going on and responsiveness is thus critical. In the common case, where
     12        the user is not scrolling, we keep processing the IPC on the main thread, like
     13        before r260614. This avoids extra thread hopping and saves power.
     14
     15        * UIProcess/WebPageProxy.cpp:
     16        (WebKit::ScrollingObserver::willSendWheelEvent):
     17        (WebKit::ScrollingObserver::ScrollingObserver):
     18        (WebKit::ScrollingObserver::singleton):
     19        (WebKit::WebPageProxy::sendWheelEvent):
     20        * UIProcess/mac/DisplayLink.cpp:
     21        (WebKit::DisplayLink::displayLinkCallback):
     22        * UIProcess/mac/DisplayLink.h:
     23        (WebKit::DisplayLink::setShouldSendIPCOnBackgroundQueue):
     24        * WebProcess/WebPage/EventDispatcher.cpp:
     25        (WebKit::EventDispatcher::notifyScrollingTreesDisplayWasRefreshed):
     26        (WebKit::EventDispatcher::displayWasRefreshed):
     27        * WebProcess/WebPage/EventDispatcher.h:
     28        * WebProcess/WebProcess.cpp:
     29        (WebKit::WebProcess::displayWasRefreshed):
     30        * WebProcess/WebProcess.h:
     31        * WebProcess/WebProcess.messages.in:
     32
    1332020-09-08  Megan Gardner  <megan_gardner@apple.com>
    234
  • trunk/Source/WebKit/UIProcess/WebPageProxy.cpp

    r266654 r266771  
    180180#include <WebCore/WindowFeatures.h>
    181181#include <WebCore/WritingDirection.h>
     182#include <pal/HysteresisActivity.h>
    182183#include <stdio.h>
    183184#include <wtf/CallbackAggregator.h>
     
    295296#endif
    296297
     298#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
     299#include "DisplayLink.h"
     300#endif
     301
    297302// This controls what strategy we use for mouse wheel coalescing.
    298303#define MERGE_WHEEL_EVENTS 1
     
    317322
    318323DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageProxyCounter, ("WebPageProxy"));
     324
     325#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
     326class ScrollingObserver {
     327    WTF_MAKE_NONCOPYABLE(ScrollingObserver);
     328    WTF_MAKE_FAST_ALLOCATED;
     329    friend NeverDestroyed<ScrollingObserver>;
     330public:
     331    static ScrollingObserver& singleton();
     332
     333    void willSendWheelEvent()
     334    {
     335        m_hysteresis.impulse();
     336    }
     337
     338private:
     339    ScrollingObserver()
     340        : m_hysteresis([](PAL::HysteresisState state) { DisplayLink::setShouldSendIPCOnBackgroundQueue(state == PAL::HysteresisState::Started); })
     341    {
     342    }
     343
     344    PAL::HysteresisActivity m_hysteresis;
     345};
     346
     347ScrollingObserver& ScrollingObserver::singleton()
     348{
     349    static NeverDestroyed<ScrollingObserver> detector;
     350    return detector;
     351}
     352#endif // ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
    319353
    320354class StorageRequests {
     
    26972731void WebPageProxy::sendWheelEvent(const WebWheelEvent& event)
    26982732{
     2733#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
     2734    ScrollingObserver::singleton().willSendWheelEvent();
     2735#endif
     2736
    26992737    send(
    27002738        Messages::EventDispatcher::WheelEvent(
  • trunk/Source/WebKit/UIProcess/mac/DisplayLink.cpp

    r266710 r266771  
    3333
    3434namespace WebKit {
     35
     36bool DisplayLink::shouldSendIPCOnBackgroundQueue { false };
    3537   
    3638DisplayLink::DisplayLink(WebCore::PlatformDisplayID displayID)
     
    132134    auto* displayLink = static_cast<DisplayLink*>(data);
    133135    LockHolder locker(displayLink->m_observersLock);
    134     for (auto& connection : displayLink->m_observers.keys())
    135         connection->send(Messages::EventDispatcher::DisplayWasRefreshed(displayLink->m_displayID), 0);
     136    for (auto& connection : displayLink->m_observers.keys()) {
     137        if (shouldSendIPCOnBackgroundQueue)
     138            connection->send(Messages::EventDispatcher::DisplayWasRefreshed(displayLink->m_displayID), 0);
     139        else
     140            connection->send(Messages::WebProcess::DisplayWasRefreshed(displayLink->m_displayID), 0);
     141    }
    136142    return kCVReturnSuccess;
    137143}
  • trunk/Source/WebKit/UIProcess/mac/DisplayLink.h

    r266710 r266771  
    5555    Optional<unsigned> nominalFramesPerSecond() const;
    5656
     57    // When responsiveness is critical, we send the IPC to a background queue. Otherwise, we send it to the
     58    // main thread to avoid unnecessary thread hopping and save power.
     59    static void setShouldSendIPCOnBackgroundQueue(bool value) { shouldSendIPCOnBackgroundQueue = value; }
     60
    5761private:
    5862    static CVReturn displayLinkCallback(CVDisplayLinkRef, const CVTimeStamp*, const CVTimeStamp*, CVOptionFlags, CVOptionFlags*, void* data);
     
    6266    HashMap<RefPtr<IPC::Connection>, Vector<DisplayLinkObserverID>> m_observers;
    6367    WebCore::PlatformDisplayID m_displayID;
     68    static bool shouldSendIPCOnBackgroundQueue;
    6469};
    6570
  • trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp

    r265743 r266771  
    270270
    271271#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
    272 void EventDispatcher::displayWasRefreshed(PlatformDisplayID displayID)
     272
     273void EventDispatcher::notifyScrollingTreesDisplayWasRefreshed(PlatformDisplayID displayID)
    273274{
    274275#if ENABLE(SCROLLING_THREAD)
     
    277278        keyValuePair.value->displayDidRefresh(displayID);
    278279#endif
     280}
     281
     282void EventDispatcher::displayWasRefreshed(PlatformDisplayID displayID)
     283{
     284    ASSERT(!RunLoop::isMain());
     285    notifyScrollingTreesDisplayWasRefreshed(displayID);
    279286
    280287    RunLoop::main().dispatch([displayID]() {
  • trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.h

    r265515 r266771  
    6969    void initializeConnection(IPC::Connection*);
    7070
     71#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
     72    void notifyScrollingTreesDisplayWasRefreshed(WebCore::PlatformDisplayID);
     73#endif
     74
    7175private:
    7276    EventDispatcher();
  • trunk/Source/WebKit/WebProcess/WebProcess.cpp

    r266395 r266771  
    194194#endif
    195195
     196#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
     197#include <WebCore/DisplayRefreshMonitorManager.h>
     198#endif
     199
    196200#define RELEASE_LOG_SESSION_ID (m_sessionID ? m_sessionID->toUInt64() : 0)
    197201#define RELEASE_LOG_IF_ALLOWED(channel, fmt, ...) RELEASE_LOG_IF(isAlwaysOnLoggingAllowed(), channel, "%p - [sessionID=%" PRIu64 "] WebProcess::" fmt, this, RELEASE_LOG_SESSION_ID, ##__VA_ARGS__)
     
    19011905}
    19021906
     1907#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
     1908void WebProcess::displayWasRefreshed(uint32_t displayID)
     1909{
     1910    ASSERT(RunLoop::isMain());
     1911    m_eventDispatcher->notifyScrollingTreesDisplayWasRefreshed(displayID);
     1912    DisplayRefreshMonitorManager::sharedManager().displayWasUpdated(displayID);
     1913}
     1914#endif
     1915
    19031916#if ENABLE(RESOURCE_LOAD_STATISTICS)
    19041917void WebProcess::setThirdPartyCookieBlockingMode(ThirdPartyCookieBlockingMode thirdPartyCookieBlockingMode, CompletionHandler<void()>&& completionHandler)
  • trunk/Source/WebKit/WebProcess/WebProcess.h

    r266214 r266771  
    479479#endif
    480480
     481#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
     482    void displayWasRefreshed(uint32_t displayID);
     483#endif
     484
    481485    void platformInitializeProcess(const AuxiliaryProcessInitializationParameters&);
    482486
  • trunk/Source/WebKit/WebProcess/WebProcess.messages.in

    r266214 r266771  
    184184    DidWriteToPasteboardAsynchronously(String pasteboardName);
    185185#endif
     186
     187#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
     188    DisplayWasRefreshed(uint32_t displayID)
     189#endif
    186190}
Note: See TracChangeset for help on using the changeset viewer.