Diff
Modified: trunk/Source/WebCore/ChangeLog (275439 => 275440)
--- trunk/Source/WebCore/ChangeLog 2021-04-02 21:20:45 UTC (rev 275439)
+++ trunk/Source/WebCore/ChangeLog 2021-04-02 21:29:13 UTC (rev 275440)
@@ -1,3 +1,17 @@
+2021-04-02 Simon Fraser <[email protected]>
+
+ Allow wheel events to trigger high frequency DisplayLinks
+ https://bugs.webkit.org/show_bug.cgi?id=224095
+
+ Reviewed by Sam Weinig.
+
+ 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):
+
2021-04-02 David Kilzer <[email protected]>
UBSan: AlternativeTextController::dismiss()/dismissSoon(): runtime error: load of value nnn, which is not a valid value for type 'bool'
Modified: trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitor.cpp (275439 => 275440)
--- trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitor.cpp 2021-04-02 21:20:45 UTC (rev 275439)
+++ trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitor.cpp 2021-04-02 21:29:13 UTC (rev 275440)
@@ -172,7 +172,7 @@
if (!isPreviousFrameDone())
return;
- LOG_WITH_STREAM(DisplayLink, stream << "DisplayRefreshMonitor::displayLinkFired for display " << displayID() << " - scheduled " << isScheduled() << " unscheduledFireCount " << m_unscheduledFireCount << " of " << m_maxUnscheduledFireCount);
+ LOG_WITH_STREAM(DisplayLink, stream << "[Web] DisplayRefreshMonitor::displayLinkFired for display " << displayID() << " - scheduled " << isScheduled() << " unscheduledFireCount " << m_unscheduledFireCount << " of " << m_maxUnscheduledFireCount);
if (firedAndReachedMaxUnscheduledFireCount()) {
stopNotificationMechanism();
return;
Modified: trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitorManager.cpp (275439 => 275440)
--- trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitorManager.cpp 2021-04-02 21:20:45 UTC (rev 275439)
+++ trunk/Source/WebCore/platform/graphics/DisplayRefreshMonitorManager.cpp 2021-04-02 21:29:13 UTC (rev 275440)
@@ -50,7 +50,7 @@
if (!monitor)
return nullptr;
- LOG_WITH_STREAM(DisplayLink, stream << "DisplayRefreshMonitorManager::ensureMonitorForDisplayID() - created monitor " << monitor.get() << " for display " << displayID);
+ LOG_WITH_STREAM(DisplayLink, stream << "[Web] DisplayRefreshMonitorManager::ensureMonitorForDisplayID() - created monitor " << monitor.get() << " for display " << displayID);
DisplayRefreshMonitor* result = monitor.get();
m_monitors.append({ WTFMove(monitor) });
return result;
Modified: trunk/Source/WebKit/ChangeLog (275439 => 275440)
--- trunk/Source/WebKit/ChangeLog 2021-04-02 21:20:45 UTC (rev 275439)
+++ trunk/Source/WebKit/ChangeLog 2021-04-02 21:29:13 UTC (rev 275440)
@@ -1,3 +1,66 @@
+2021-04-01 Simon Fraser <[email protected]>
+
+ Allow wheel events to trigger high frequency DisplayLinks
+ https://bugs.webkit.org/show_bug.cgi?id=224095
+
+ Reviewed by Sam Weinig.
+
+ 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):
+
2021-04-02 Chris Dumez <[email protected]>
Make sure we are no longer show the previous page when running a JS prompt
Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm (275439 => 275440)
--- trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm 2021-04-02 21:20:45 UTC (rev 275439)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm 2021-04-02 21:29:13 UTC (rev 275440)
@@ -820,6 +820,20 @@
}
}
}
+
+void WebProcessPool::setDisplayLinkForDisplayWantsFullSpeedUpdates(IPC::Connection& connection, WebCore::PlatformDisplayID displayID, bool wantsFullSpeedUpdates)
+{
+ for (auto& displayLink : m_displayLinks) {
+ if (displayLink->displayID() == displayID) {
+ if (wantsFullSpeedUpdates)
+ displayLink->incrementFullSpeedRequestClientCount(connection);
+ else
+ displayLink->decrementFullSpeedRequestClientCount(connection);
+ return;
+ }
+ }
+}
+
#endif // HAVE(CVDISPLAYLINK)
// FIXME: Deprecated. Left here until a final decision is made.
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (275439 => 275440)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2021-04-02 21:20:45 UTC (rev 275439)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2021-04-02 21:29:13 UTC (rev 275440)
@@ -185,7 +185,6 @@
#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>
@@ -324,35 +323,6 @@
DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageProxyCounter, ("WebPageProxy"));
-#if HAVE(CVDISPLAYLINK)
-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
-
class StorageRequests {
WTF_MAKE_NONCOPYABLE(StorageRequests); WTF_MAKE_FAST_ALLOCATED;
friend NeverDestroyed<StorageRequests>;
@@ -512,6 +482,9 @@
, m_backForwardList(WebBackForwardList::create(*this))
, m_waitsForPaintAfterViewDidMoveToWindow(m_configuration->waitsForPaintAfterViewDidMoveToWindow())
, m_hasRunningProcess(process.state() != WebProcessProxy::State::Terminated)
+#if HAVE(CVDISPLAYLINK)
+ , m_wheelEventActivityHysteresis([this](PAL::HysteresisState state) { wheelEventHysteresisUpdated(state); })
+#endif
, m_controlledByAutomation(m_configuration->isControlledByAutomation())
#if PLATFORM(COCOA)
, m_isSmartInsertDeleteEnabled(TextChecker::isSmartInsertDeleteEnabled())
@@ -2756,10 +2729,21 @@
}
}
+#if HAVE(CVDISPLAYLINK)
+void WebPageProxy::wheelEventHysteresisUpdated(PAL::HysteresisState state)
+{
+ if (!m_process->hasConnection() || !m_displayID)
+ return;
+
+ bool wantsFullSpeedUpdates = state == PAL::HysteresisState::Started;
+ process().processPool().setDisplayLinkForDisplayWantsFullSpeedUpdates(*m_process->connection(), *m_displayID, wantsFullSpeedUpdates);
+}
+#endif
+
void WebPageProxy::sendWheelEvent(const WebWheelEvent& event)
{
#if HAVE(CVDISPLAYLINK)
- ScrollingObserver::singleton().willSendWheelEvent();
+ m_wheelEventActivityHysteresis.impulse();
#endif
send(
@@ -3776,6 +3760,8 @@
void WebPageProxy::windowScreenDidChange(PlatformDisplayID displayID, Optional<unsigned> nominalFramesPerSecond)
{
+ m_displayID = displayID;
+
if (!hasRunningProcess())
return;
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (275439 => 275440)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2021-04-02 21:20:45 UTC (rev 275439)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2021-04-02 21:29:13 UTC (rev 275440)
@@ -112,6 +112,7 @@
#include <WebCore/UserInterfaceLayoutDirection.h>
#include <WebCore/ViewportArguments.h>
#include <memory>
+#include <pal/HysteresisActivity.h>
#include <wtf/CompletionHandler.h>
#include <wtf/FileSystem.h>
#include <wtf/HashMap.h>
@@ -2300,6 +2301,10 @@
WebWheelEventCoalescer& wheelEventCoalescer();
+#if HAVE(CVDISPLAYLINK)
+ void wheelEventHysteresisUpdated(PAL::HysteresisState);
+#endif
+
#if ENABLE(TOUCH_EVENTS)
void updateTouchEventTracking(const WebTouchEvent&);
WebCore::TrackingType touchEventTrackingType(const WebTouchEvent&) const;
@@ -2659,6 +2664,11 @@
std::unique_ptr<WebWheelEventCoalescer> m_wheelEventCoalescer;
+ Optional<WebCore::PlatformDisplayID> m_displayID;
+#if HAVE(CVDISPLAYLINK)
+ PAL::HysteresisActivity m_wheelEventActivityHysteresis;
+#endif
+
Deque<NativeWebMouseEvent> m_mouseEventQueue;
Deque<NativeWebKeyboardEvent> m_keyEventQueue;
#if ENABLE(MAC_GESTURE_EVENTS)
Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.h (275439 => 275440)
--- trunk/Source/WebKit/UIProcess/WebProcessPool.h 2021-04-02 21:20:45 UTC (rev 275439)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.h 2021-04-02 21:29:13 UTC (rev 275440)
@@ -243,6 +243,8 @@
void stopDisplayLink(IPC::Connection&, DisplayLinkObserverID, WebCore::PlatformDisplayID);
void setDisplayLinkPreferredFramesPerSecond(IPC::Connection&, DisplayLinkObserverID, WebCore::PlatformDisplayID, WebCore::FramesPerSecond);
void stopDisplayLinks(IPC::Connection&);
+
+ void setDisplayLinkForDisplayWantsFullSpeedUpdates(IPC::Connection&, WebCore::PlatformDisplayID, bool wantsFullSpeedUpdates);
#endif
void addSupportedPlugin(String&& matchingDomain, String&& name, HashSet<String>&& mimeTypes, HashSet<String> extensions);
Modified: trunk/Source/WebKit/UIProcess/mac/DisplayLink.cpp (275439 => 275440)
--- trunk/Source/WebKit/UIProcess/mac/DisplayLink.cpp 2021-04-02 21:20:45 UTC (rev 275439)
+++ trunk/Source/WebKit/UIProcess/mac/DisplayLink.cpp 2021-04-02 21:29:13 UTC (rev 275440)
@@ -60,12 +60,12 @@
m_displayNominalFramesPerSecond = nominalFramesPerSecondFromDisplayLink(m_displayLink);
- LOG_WITH_STREAM(DisplayLink, stream << "[UI ] Creating DisplayLink for display " << displayID << " with nominal fps " << m_displayNominalFramesPerSecond);
+ LOG_WITH_STREAM(DisplayLink, stream << "[UI ] Created DisplayLink " << this << " for display " << displayID << " with nominal fps " << m_displayNominalFramesPerSecond);
}
DisplayLink::~DisplayLink()
{
- LOG_WITH_STREAM(DisplayLink, stream << "[UI ] Destroying DisplayLink for display " << m_displayID);
+ LOG_WITH_STREAM(DisplayLink, stream << "[UI ] Destroying DisplayLink " << this << " for display " << m_displayID);
ASSERT(hasProcessPrivilege(ProcessPrivilege::CanCommunicateWithWindowServer));
ASSERT(m_displayLink);
@@ -86,11 +86,13 @@
{
ASSERT(RunLoop::isMain());
+ LOG_WITH_STREAM(DisplayLink, stream << "[UI ] DisplayLink " << this << " for display display " << m_displayID << " add observer " << observerID << " fps " << preferredFramesPerSecond);
+
{
auto locker = holdLock(m_observersLock);
m_observers.ensure(&connection, [] {
- return Vector<ObserverInfo> { };
- }).iterator->value.append({ observerID, preferredFramesPerSecond });
+ return ConnectionClientInfo { };
+ }).iterator->value.observers.append({ observerID, preferredFramesPerSecond });
}
if (!CVDisplayLinkIsRunning(m_displayLink)) {
@@ -112,13 +114,18 @@
auto it = m_observers.find(&connection);
if (it == m_observers.end())
return;
- bool removed = it->value.removeFirstMatching([observerID](const auto& value) {
+
+ auto& connectionInfo = it->value;
+
+ bool removed = connectionInfo.observers.removeFirstMatching([observerID](const auto& value) {
return value.observerID == observerID;
});
ASSERT_UNUSED(removed, removed);
- if (it->value.isEmpty())
- m_observers.remove(it);
+ LOG_WITH_STREAM(DisplayLink, stream << "[UI ] DisplayLink " << this << " for display " << m_displayID << " remove observer " << observerID);
+
+ removeInfoForConnectionIfPossible(connection);
+
// We do not stop the display link right away when |m_observers| becomes empty. Instead, we
// let the display link fire up to |maxFireCountWithoutObservers| times without observers to avoid
// killing & restarting too many threads when observers gets removed & added in quick succession.
@@ -136,9 +143,45 @@
// killing & restarting too many threads when observers gets removed & added in quick succession.
}
+void DisplayLink::removeInfoForConnectionIfPossible(IPC::Connection& connection)
+{
+ auto it = m_observers.find(&connection);
+ if (it == m_observers.end())
+ return;
+
+ auto& connectionInfo = it->value;
+ if (connectionInfo.observers.isEmpty() && !connectionInfo.fullSpeedUpdatesClientCount)
+ m_observers.remove(it);
+}
+
+void DisplayLink::incrementFullSpeedRequestClientCount(IPC::Connection& connection)
+{
+ auto locker = holdLock(m_observersLock);
+
+ auto& connectionInfo = m_observers.ensure(&connection, [] {
+ return ConnectionClientInfo { };
+ }).iterator->value;;
+
+ ++connectionInfo.fullSpeedUpdatesClientCount;
+}
+
+void DisplayLink::decrementFullSpeedRequestClientCount(IPC::Connection& connection)
+{
+ auto locker = holdLock(m_observersLock);
+
+ auto it = m_observers.find(&connection);
+ if (it == m_observers.end())
+ return;
+
+ auto& connectionInfo = it->value;
+ ASSERT(connectionInfo.fullSpeedUpdatesClientCount);
+ --connectionInfo.fullSpeedUpdatesClientCount;
+ removeInfoForConnectionIfPossible(connection);
+}
+
void DisplayLink::setPreferredFramesPerSecond(IPC::Connection& connection, DisplayLinkObserverID observerID, WebCore::FramesPerSecond preferredFramesPerSecond)
{
- LOG_WITH_STREAM(DisplayLink, stream << "[UI ] DisplayLink::setPreferredFramesPerSecond - display " << m_displayID << " observer " << observerID << " fps " << preferredFramesPerSecond);
+ LOG_WITH_STREAM(DisplayLink, stream << "[UI ] DisplayLink " << this << " setPreferredFramesPerSecond - display " << m_displayID << " observer " << observerID << " fps " << preferredFramesPerSecond);
auto locker = holdLock(m_observersLock);
@@ -146,12 +189,13 @@
if (it == m_observers.end())
return;
- auto index = it->value.findMatching([observerID](const auto& observer) {
+ auto& connectionInfo = it->value;
+ auto index = connectionInfo.observers.findMatching([observerID](const auto& observer) {
return observer.observerID == observerID;
});
if (index != notFound)
- it->value[index].preferredFramesPerSecond = preferredFramesPerSecond;
+ connectionInfo.observers[index].preferredFramesPerSecond = preferredFramesPerSecond;
}
CVReturn DisplayLink::displayLinkCallback(CVDisplayLinkRef displayLinkRef, const CVTimeStamp*, const CVTimeStamp*, CVOptionFlags, CVOptionFlags*, void* data)
@@ -165,14 +209,6 @@
ASSERT(!RunLoop::isMain());
auto locker = holdLock(m_observersLock);
- if (m_observers.isEmpty()) {
- if (++m_fireCountWithoutObservers >= maxFireCountWithoutObservers) {
- LOG_WITH_STREAM(DisplayLink, stream << "[UI ] DisplayLink for display " << m_displayID << " fired " << m_fireCountWithoutObservers << " times with no observers; stopping CVDisplayLink");
- CVDisplayLinkStop(m_displayLink);
- }
- return;
- }
- m_fireCountWithoutObservers = 0;
auto maxFramesPerSecond = [](const Vector<ObserverInfo>& observers) {
Optional<WebCore::FramesPerSecond> observersMaxFramesPerSecond;
@@ -181,23 +217,35 @@
return observersMaxFramesPerSecond;
};
- for (auto& [connection, observers] : m_observers) {
- auto observersMaxFramesPerSecond = maxFramesPerSecond(observers);
- auto updateIsRelevant = m_currentUpdate.relevantForUpdateFrequency(observersMaxFramesPerSecond.valueOr(WebCore::FullSpeedFramesPerSecond));
+ bool anyConnectionHadObservers = false;
+ for (auto& [connection, connectionInfo] : m_observers) {
+ if (connectionInfo.observers.isEmpty())
+ continue;
- LOG_WITH_STREAM(DisplayLink, stream << "[UI ] DisplayLink for display " << m_displayID << " (display fps " << m_displayNominalFramesPerSecond << ") update " << m_currentUpdate << " " << observers.size()
- << " observers, on background queue " << shouldSendIPCOnBackgroundQueue << " maxFramesPerSecond " << observersMaxFramesPerSecond << " relevant " << updateIsRelevant);
+ anyConnectionHadObservers = true;
- if (!updateIsRelevant)
- continue;
+ auto observersMaxFramesPerSecond = maxFramesPerSecond(connectionInfo.observers);
+ auto mainThreadWantsUpdate = m_currentUpdate.relevantForUpdateFrequency(observersMaxFramesPerSecond.valueOr(WebCore::FullSpeedFramesPerSecond));
- if (shouldSendIPCOnBackgroundQueue)
- connection->send(Messages::EventDispatcher::DisplayWasRefreshed(m_displayID, m_currentUpdate), 0);
- else
+ LOG_WITH_STREAM(DisplayLink, stream << "[UI ] DisplayLink " << this << " for display " << m_displayID << " (display fps " << m_displayNominalFramesPerSecond << ") update " << m_currentUpdate << " " << connectionInfo.observers.size()
+ << " observers, on background queue " << shouldSendIPCOnBackgroundQueue << " maxFramesPerSecond " << observersMaxFramesPerSecond << " full speed clients " << connectionInfo.fullSpeedUpdatesClientCount << " relevant " << mainThreadWantsUpdate);
+
+ if (connectionInfo.fullSpeedUpdatesClientCount) {
+ connection->send(Messages::EventDispatcher::DisplayWasRefreshed(m_displayID, m_currentUpdate, mainThreadWantsUpdate), 0);
+ } else if (mainThreadWantsUpdate)
connection->send(Messages::WebProcess::DisplayWasRefreshed(m_displayID, m_currentUpdate), 0);
}
m_currentUpdate = m_currentUpdate.nextUpdate();
+
+ if (!anyConnectionHadObservers) {
+ if (++m_fireCountWithoutObservers >= maxFireCountWithoutObservers) {
+ LOG_WITH_STREAM(DisplayLink, stream << "[UI ] DisplayLink for display " << m_displayID << " fired " << m_fireCountWithoutObservers << " times with no observers; stopping CVDisplayLink");
+ CVDisplayLinkStop(m_displayLink);
+ }
+ return;
+ }
+ m_fireCountWithoutObservers = 0;
}
} // namespace WebKit
Modified: trunk/Source/WebKit/UIProcess/mac/DisplayLink.h (275439 => 275440)
--- trunk/Source/WebKit/UIProcess/mac/DisplayLink.h 2021-04-02 21:20:45 UTC (rev 275439)
+++ trunk/Source/WebKit/UIProcess/mac/DisplayLink.h 2021-04-02 21:29:13 UTC (rev 275440)
@@ -51,6 +51,9 @@
void removeObserver(IPC::Connection&, DisplayLinkObserverID);
void removeObservers(IPC::Connection&);
+ void incrementFullSpeedRequestClientCount(IPC::Connection&);
+ void decrementFullSpeedRequestClientCount(IPC::Connection&);
+
void setPreferredFramesPerSecond(IPC::Connection&, DisplayLinkObserverID, WebCore::FramesPerSecond);
WebCore::PlatformDisplayID displayID() const { return m_displayID; }
@@ -64,7 +67,9 @@
private:
static CVReturn displayLinkCallback(CVDisplayLinkRef, const CVTimeStamp*, const CVTimeStamp*, CVOptionFlags, CVOptionFlags*, void* data);
void notifyObserversDisplayWasRefreshed();
-
+
+ void removeInfoForConnectionIfPossible(IPC::Connection&);
+
static WebCore::FramesPerSecond nominalFramesPerSecondFromDisplayLink(CVDisplayLinkRef);
struct ObserverInfo {
@@ -71,10 +76,15 @@
DisplayLinkObserverID observerID;
WebCore::FramesPerSecond preferredFramesPerSecond;
};
+
+ struct ConnectionClientInfo {
+ unsigned fullSpeedUpdatesClientCount { 0 };
+ Vector<ObserverInfo> observers;
+ };
CVDisplayLinkRef m_displayLink { nullptr };
Lock m_observersLock;
- HashMap<RefPtr<IPC::Connection>, Vector<ObserverInfo>> m_observers;
+ HashMap<RefPtr<IPC::Connection>, ConnectionClientInfo> m_observers;
WebCore::PlatformDisplayID m_displayID;
WebCore::FramesPerSecond m_displayNominalFramesPerSecond { 0 };
WebCore::DisplayUpdate m_currentUpdate;
Modified: trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp (275439 => 275440)
--- trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp 2021-04-02 21:20:45 UTC (rev 275439)
+++ trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.cpp 2021-04-02 21:29:13 UTC (rev 275440)
@@ -289,11 +289,14 @@
}
#if HAVE(CVDISPLAYLINK)
-void EventDispatcher::displayWasRefreshed(PlatformDisplayID displayID, const DisplayUpdate& displayUpdate)
+void EventDispatcher::displayWasRefreshed(PlatformDisplayID displayID, const DisplayUpdate& displayUpdate, bool sendToMainThread)
{
ASSERT(!RunLoop::isMain());
notifyScrollingTreesDisplayWasRefreshed(displayID);
+ if (!sendToMainThread)
+ return;
+
RunLoop::main().dispatch([displayID, displayUpdate]() {
DisplayRefreshMonitorManager::sharedManager().displayWasUpdated(displayID, displayUpdate);
});
Modified: trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.h (275439 => 275440)
--- trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.h 2021-04-02 21:20:45 UTC (rev 275439)
+++ trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.h 2021-04-02 21:29:13 UTC (rev 275440)
@@ -108,7 +108,7 @@
#endif
#if PLATFORM(MAC)
- void displayWasRefreshed(WebCore::PlatformDisplayID, const WebCore::DisplayUpdate&);
+ void displayWasRefreshed(WebCore::PlatformDisplayID, const WebCore::DisplayUpdate&, bool sendToMainThread);
#endif
#if ENABLE(SCROLLING_THREAD)
Modified: trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.messages.in (275439 => 275440)
--- trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.messages.in 2021-04-02 21:20:45 UTC (rev 275439)
+++ trunk/Source/WebKit/WebProcess/WebPage/EventDispatcher.messages.in 2021-04-02 21:29:13 UTC (rev 275440)
@@ -30,6 +30,6 @@
GestureEvent(WebCore::PageIdentifier pageID, WebKit::WebGestureEvent event)
#endif
#if HAVE(CVDISPLAYLINK)
- DisplayWasRefreshed(uint32_t displayID, struct WebCore::DisplayUpdate update)
+ DisplayWasRefreshed(uint32_t displayID, struct WebCore::DisplayUpdate update, bool sendToMainThread)
#endif
}
Modified: trunk/Source/WebKit/WebProcess/WebPage/mac/DisplayRefreshMonitorMac.cpp (275439 => 275440)
--- trunk/Source/WebKit/WebProcess/WebPage/mac/DisplayRefreshMonitorMac.cpp 2021-04-02 21:20:45 UTC (rev 275439)
+++ trunk/Source/WebKit/WebProcess/WebPage/mac/DisplayRefreshMonitorMac.cpp 2021-04-02 21:29:13 UTC (rev 275440)
@@ -71,7 +71,7 @@
if (m_displayLinkIsActive)
return true;
- LOG_WITH_STREAM(DisplayLink, stream << "DisplayRefreshMonitorMac::requestRefreshCallback - starting");
+ LOG_WITH_STREAM(DisplayLink, stream << "[Web ] DisplayRefreshMonitorMac::requestRefreshCallback for display " << displayID() << " - starting");
WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessProxy::StartDisplayLink(m_observerID, displayID(), maxClientPreferredFramesPerSecond().valueOr(FullSpeedFramesPerSecond)), 0);
if (!m_runLoopObserver) {
// The RunLoopObserver repeats.
@@ -100,7 +100,7 @@
void DisplayRefreshMonitorMac::adjustPreferredFramesPerSecond(FramesPerSecond preferredFramesPerSecond)
{
- LOG_WITH_STREAM(DisplayLink, stream << "DisplayRefreshMonitorMac::adjustPreferredFramesPerSecond for display link on display " << displayID() << " to " << preferredFramesPerSecond);
+ LOG_WITH_STREAM(DisplayLink, stream << "[Web] DisplayRefreshMonitorMac::adjustPreferredFramesPerSecond for display link on display " << displayID() << " to " << preferredFramesPerSecond);
WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessProxy::SetDisplayLinkPreferredFramesPerSecond(m_observerID, displayID(), preferredFramesPerSecond), 0);
}