Title: [266771] trunk/Source/WebKit
Revision
266771
Author
[email protected]
Date
2020-09-08 21:12:33 -0700 (Tue, 08 Sep 2020)

Log 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:

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (266770 => 266771)


--- trunk/Source/WebKit/ChangeLog	2020-09-09 03:48:31 UTC (rev 266770)
+++ trunk/Source/WebKit/ChangeLog	2020-09-09 04:12:33 UTC (rev 266771)
@@ -1,3 +1,35 @@
+2020-09-08  Chris Dumez  <[email protected]>
+
+        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:
+
 2020-09-08  Megan Gardner  <[email protected]>
 
         Removed unneeded respondsToSelector checks on UIWKTextInteractionAssistant in WKContentViewInteraction.

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (266770 => 266771)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2020-09-09 03:48:31 UTC (rev 266770)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2020-09-09 04:12:33 UTC (rev 266771)
@@ -179,6 +179,7 @@
 #include <WebCore/ValidationBubble.h>
 #include <WebCore/WindowFeatures.h>
 #include <WebCore/WritingDirection.h>
+#include <pal/HysteresisActivity.h>
 #include <stdio.h>
 #include <wtf/CallbackAggregator.h>
 #include <wtf/NeverDestroyed.h>
@@ -294,6 +295,10 @@
 #include "WebDateTimePicker.h"
 #endif
 
+#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
+#include "DisplayLink.h"
+#endif
+
 // This controls what strategy we use for mouse wheel coalescing.
 #define MERGE_WHEEL_EVENTS 1
 
@@ -317,6 +322,35 @@
 
 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageProxyCounter, ("WebPageProxy"));
 
+#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
+class ScrollingObserver {
+    WTF_MAKE_NONCOPYABLE(ScrollingObserver);
+    WTF_MAKE_FAST_ALLOCATED;
+    friend NeverDestroyed<ScrollingObserver>;
+public:
+    static ScrollingObserver& singleton();
+
+    void willSendWheelEvent()
+    {
+        m_hysteresis.impulse();
+    }
+
+private:
+    ScrollingObserver()
+        : m_hysteresis([](PAL::HysteresisState state) { DisplayLink::setShouldSendIPCOnBackgroundQueue(state == PAL::HysteresisState::Started); })
+    {
+    }
+
+    PAL::HysteresisActivity m_hysteresis;
+};
+
+ScrollingObserver& ScrollingObserver::singleton()
+{
+    static NeverDestroyed<ScrollingObserver> detector;
+    return detector;
+}
+#endif // ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
+
 class StorageRequests {
     WTF_MAKE_NONCOPYABLE(StorageRequests); WTF_MAKE_FAST_ALLOCATED;
     friend NeverDestroyed<StorageRequests>;
@@ -2696,6 +2730,10 @@
 
 void WebPageProxy::sendWheelEvent(const WebWheelEvent& event)
 {
+#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
+    ScrollingObserver::singleton().willSendWheelEvent();
+#endif
+
     send(
         Messages::EventDispatcher::WheelEvent(
             m_webPageID,

Modified: trunk/Source/WebKit/UIProcess/mac/DisplayLink.cpp (266770 => 266771)


--- trunk/Source/WebKit/UIProcess/mac/DisplayLink.cpp	2020-09-09 03:48:31 UTC (rev 266770)
+++ trunk/Source/WebKit/UIProcess/mac/DisplayLink.cpp	2020-09-09 04:12:33 UTC (rev 266771)
@@ -32,6 +32,8 @@
 #include <wtf/ProcessPrivilege.h>
 
 namespace WebKit {
+
+bool DisplayLink::shouldSendIPCOnBackgroundQueue { false };
     
 DisplayLink::DisplayLink(WebCore::PlatformDisplayID displayID)
     : m_displayID(displayID)
@@ -131,8 +133,12 @@
 {
     auto* displayLink = static_cast<DisplayLink*>(data);
     LockHolder locker(displayLink->m_observersLock);
-    for (auto& connection : displayLink->m_observers.keys())
-        connection->send(Messages::EventDispatcher::DisplayWasRefreshed(displayLink->m_displayID), 0);
+    for (auto& connection : displayLink->m_observers.keys()) {
+        if (shouldSendIPCOnBackgroundQueue)
+            connection->send(Messages::EventDispatcher::DisplayWasRefreshed(displayLink->m_displayID), 0);
+        else
+            connection->send(Messages::WebProcess::DisplayWasRefreshed(displayLink->m_displayID), 0);
+    }
     return kCVReturnSuccess;
 }
 

Modified: trunk/Source/WebKit/UIProcess/mac/DisplayLink.h (266770 => 266771)


--- trunk/Source/WebKit/UIProcess/mac/DisplayLink.h	2020-09-09 03:48:31 UTC (rev 266770)
+++ trunk/Source/WebKit/UIProcess/mac/DisplayLink.h	2020-09-09 04:12:33 UTC (rev 266771)
@@ -54,6 +54,10 @@
     
     Optional<unsigned> nominalFramesPerSecond() const;
 
+    // When responsiveness is critical, we send the IPC to a background queue. Otherwise, we send it to the
+    // main thread to avoid unnecessary thread hopping and save power.
+    static void setShouldSendIPCOnBackgroundQueue(bool value) { shouldSendIPCOnBackgroundQueue = value; }
+
 private:
     static CVReturn displayLinkCallback(CVDisplayLinkRef, const CVTimeStamp*, const CVTimeStamp*, CVOptionFlags, CVOptionFlags*, void* data);
     
@@ -61,6 +65,7 @@
     Lock m_observersLock;
     HashMap<RefPtr<IPC::Connection>, Vector<DisplayLinkObserverID>> m_observers;
     WebCore::PlatformDisplayID m_displayID;
+    static bool shouldSendIPCOnBackgroundQueue;
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp (266770 => 266771)


--- trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp	2020-09-09 03:48:31 UTC (rev 266770)
+++ trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp	2020-09-09 04:12:33 UTC (rev 266771)
@@ -269,7 +269,8 @@
 #endif
 
 #if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
-void EventDispatcher::displayWasRefreshed(PlatformDisplayID displayID)
+
+void EventDispatcher::notifyScrollingTreesDisplayWasRefreshed(PlatformDisplayID displayID)
 {
 #if ENABLE(SCROLLING_THREAD)
     LockHolder locker(m_scrollingTreesMutex);
@@ -276,7 +277,13 @@
     for (auto keyValuePair : m_scrollingTrees)
         keyValuePair.value->displayDidRefresh(displayID);
 #endif
+}
 
+void EventDispatcher::displayWasRefreshed(PlatformDisplayID displayID)
+{
+    ASSERT(!RunLoop::isMain());
+    notifyScrollingTreesDisplayWasRefreshed(displayID);
+
     RunLoop::main().dispatch([displayID]() {
         DisplayRefreshMonitorManager::sharedManager().displayWasUpdated(displayID);
     });

Modified: trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.h (266770 => 266771)


--- trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.h	2020-09-09 03:48:31 UTC (rev 266770)
+++ trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.h	2020-09-09 04:12:33 UTC (rev 266771)
@@ -68,6 +68,10 @@
 
     void initializeConnection(IPC::Connection*);
 
+#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
+    void notifyScrollingTreesDisplayWasRefreshed(WebCore::PlatformDisplayID);
+#endif
+
 private:
     EventDispatcher();
 

Modified: trunk/Source/WebKit/WebProcess/WebProcess.cpp (266770 => 266771)


--- trunk/Source/WebKit/WebProcess/WebProcess.cpp	2020-09-09 03:48:31 UTC (rev 266770)
+++ trunk/Source/WebKit/WebProcess/WebProcess.cpp	2020-09-09 04:12:33 UTC (rev 266771)
@@ -193,6 +193,10 @@
 #include <WebCore/VP9UtilitiesCocoa.h>
 #endif
 
+#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
+#include <WebCore/DisplayRefreshMonitorManager.h>
+#endif
+
 #define RELEASE_LOG_SESSION_ID (m_sessionID ? m_sessionID->toUInt64() : 0)
 #define RELEASE_LOG_IF_ALLOWED(channel, fmt, ...) RELEASE_LOG_IF(isAlwaysOnLoggingAllowed(), channel, "%p - [sessionID=%" PRIu64 "] WebProcess::" fmt, this, RELEASE_LOG_SESSION_ID, ##__VA_ARGS__)
 #define RELEASE_LOG_ERROR_IF_ALLOWED(channel, fmt, ...) RELEASE_LOG_ERROR_IF(isAlwaysOnLoggingAllowed(), channel, "%p - [sessionID=%" PRIu64 "] WebProcess::" fmt, this, RELEASE_LOG_SESSION_ID, ##__VA_ARGS__)
@@ -1900,6 +1904,15 @@
     });
 }
 
+#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
+void WebProcess::displayWasRefreshed(uint32_t displayID)
+{
+    ASSERT(RunLoop::isMain());
+    m_eventDispatcher->notifyScrollingTreesDisplayWasRefreshed(displayID);
+    DisplayRefreshMonitorManager::sharedManager().displayWasUpdated(displayID);
+}
+#endif
+
 #if ENABLE(RESOURCE_LOAD_STATISTICS)
 void WebProcess::setThirdPartyCookieBlockingMode(ThirdPartyCookieBlockingMode thirdPartyCookieBlockingMode, CompletionHandler<void()>&& completionHandler)
 {

Modified: trunk/Source/WebKit/WebProcess/WebProcess.h (266770 => 266771)


--- trunk/Source/WebKit/WebProcess/WebProcess.h	2020-09-09 03:48:31 UTC (rev 266770)
+++ trunk/Source/WebKit/WebProcess/WebProcess.h	2020-09-09 04:12:33 UTC (rev 266771)
@@ -478,6 +478,10 @@
     void sendResourceLoadStatisticsDataImmediately(CompletionHandler<void()>&&);
 #endif
 
+#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
+    void displayWasRefreshed(uint32_t displayID);
+#endif
+
     void platformInitializeProcess(const AuxiliaryProcessInitializationParameters&);
 
     // IPC::Connection::Client

Modified: trunk/Source/WebKit/WebProcess/WebProcess.messages.in (266770 => 266771)


--- trunk/Source/WebKit/WebProcess/WebProcess.messages.in	2020-09-09 03:48:31 UTC (rev 266770)
+++ trunk/Source/WebKit/WebProcess/WebProcess.messages.in	2020-09-09 04:12:33 UTC (rev 266771)
@@ -183,4 +183,8 @@
 #if PLATFORM(COCOA)
     DidWriteToPasteboardAsynchronously(String pasteboardName);
 #endif
+
+#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
+    DisplayWasRefreshed(uint32_t displayID)
+#endif
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to