Diff
Modified: trunk/Source/WebKit/ChangeLog (241231 => 241232)
--- trunk/Source/WebKit/ChangeLog 2019-02-09 04:06:34 UTC (rev 241231)
+++ trunk/Source/WebKit/ChangeLog 2019-02-09 04:36:57 UTC (rev 241232)
@@ -1,3 +1,41 @@
+2019-02-08 Chris Dumez <[email protected]>
+
+ [WK2][macOS] Avoid creating new CVDisplayLink objects for each WebProcess
+ https://bugs.webkit.org/show_bug.cgi?id=194463
+
+ Reviewed by Tim Horton.
+
+ Avoid creating new CVDisplayLink objects for each WebProcess. We really only need one per
+ display, creating such object is expensive and it is even worse in a PSON world where we
+ swap process on navigation.
+
+ This patch moves the DisplayLink storing from WebProcessProxy to WebProcessPool. Also,
+ a DisplayLink can now be associated to several IPC connections instead of having a 1:1
+ mapping. When a DisplayLink no longer has any observers, we now merely stop it instead
+ of destroying it.
+
+ * UIProcess/Cocoa/WebProcessPoolCocoa.mm:
+ (WebKit::WebProcessPool::startDisplayLink):
+ (WebKit::WebProcessPool::stopDisplayLink):
+ (WebKit::WebProcessPool::stopDisplayLinks):
+ * UIProcess/WebProcessPool.h:
+ * UIProcess/WebProcessProxy.cpp:
+ (WebKit::WebProcessProxy::~WebProcessProxy):
+ (WebKit::WebProcessProxy::processWillShutDown):
+ (WebKit::WebProcessProxy::shutDown):
+ * UIProcess/WebProcessProxy.h:
+ * UIProcess/mac/DisplayLink.cpp:
+ (WebKit::DisplayLink::DisplayLink):
+ (WebKit::DisplayLink::addObserver):
+ (WebKit::DisplayLink::removeObserver):
+ (WebKit::DisplayLink::removeObservers):
+ (WebKit::DisplayLink::hasObservers const):
+ (WebKit::DisplayLink::displayLinkCallback):
+ * UIProcess/mac/DisplayLink.h:
+ * UIProcess/mac/WebProcessProxyMac.mm:
+ (WebKit::WebProcessProxy::startDisplayLink):
+ (WebKit::WebProcessProxy::stopDisplayLink):
+
2019-02-08 Alexander Mikhaylenko <[email protected]>
[GTK] Implement back/forward touchpad gesture
Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm (241231 => 241232)
--- trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm 2019-02-09 04:06:34 UTC (rev 241231)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm 2019-02-09 04:36:57 UTC (rev 241232)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2019 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -468,6 +468,37 @@
_CFNetworkResetHSTSHostsSinceDate(privateBrowsingSession(), (__bridge CFDateRef)startDate);
}
+#if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
+void WebProcessPool::startDisplayLink(IPC::Connection& connection, unsigned observerID, uint32_t displayID)
+{
+ for (auto& displayLink : m_displayLinks) {
+ if (displayLink->displayID() == displayID) {
+ displayLink->addObserver(connection, observerID);
+ return;
+ }
+ }
+ auto displayLink = std::make_unique<DisplayLink>(displayID);
+ displayLink->addObserver(connection, observerID);
+ m_displayLinks.append(WTFMove(displayLink));
+}
+
+void WebProcessPool::stopDisplayLink(IPC::Connection& connection, unsigned observerID, uint32_t displayID)
+{
+ for (auto& displayLink : m_displayLinks) {
+ if (displayLink->displayID() == displayID) {
+ displayLink->removeObserver(connection, observerID);
+ return;
+ }
+ }
+}
+
+void WebProcessPool::stopDisplayLinks(IPC::Connection& connection)
+{
+ for (auto& displayLink : m_displayLinks)
+ displayLink->removeObservers(connection);
+}
+#endif
+
// FIXME: Deprecated. Left here until a final decision is made.
void WebProcessPool::setCookieStoragePartitioningEnabled(bool enabled)
{
Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.h (241231 => 241232)
--- trunk/Source/WebKit/UIProcess/WebProcessPool.h 2019-02-09 04:06:34 UTC (rev 241231)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.h 2019-02-09 04:36:57 UTC (rev 241232)
@@ -71,6 +71,10 @@
OBJC_CLASS NSString;
#endif
+#if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
+#include "DisplayLink.h"
+#endif
+
namespace API {
class AutomationClient;
class CustomProtocolManagerClient;
@@ -208,6 +212,12 @@
const HashMap<String, HashMap<String, HashMap<String, uint8_t>>>& pluginLoadClientPolicies() const { return m_pluginLoadClientPolicies; }
#endif
+#if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
+ void startDisplayLink(IPC::Connection&, unsigned observerID, uint32_t displayID);
+ void stopDisplayLink(IPC::Connection&, unsigned observerID, uint32_t displayID);
+ void stopDisplayLinks(IPC::Connection&);
+#endif
+
void addSupportedPlugin(String&& matchingDomain, String&& name, HashSet<String>&& mimeTypes, HashSet<String> extensions);
void clearSupportedPlugins();
@@ -730,6 +740,10 @@
HashMap<String, std::unique_ptr<WebCore::PrewarmInformation>> m_prewarmInformationPerRegistrableDomain;
+#if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
+ Vector<std::unique_ptr<DisplayLink>> m_displayLinks;
+#endif
+
#if PLATFORM(GTK) || PLATFORM(WPE)
bool m_sandboxEnabled { false };
HashMap<CString, SandboxPermission> m_extraSandboxPaths;
Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp (241231 => 241232)
--- trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp 2019-02-09 04:06:34 UTC (rev 241231)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp 2019-02-09 04:36:57 UTC (rev 241232)
@@ -162,6 +162,11 @@
WebPasteboardProxy::singleton().removeWebProcessProxy(*this);
+#if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
+ if (state() == State::Running)
+ processPool().stopDisplayLinks(*connection());
+#endif
+
if (m_webConnection)
m_webConnection->invalidate();
@@ -240,6 +245,10 @@
{
ASSERT_UNUSED(connection, this->connection() == &connection);
+#if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
+ processPool().stopDisplayLinks(connection);
+#endif
+
for (auto& page : m_pageMap.values())
page->webProcessWillShutDown();
}
Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.h (241231 => 241232)
--- trunk/Source/WebKit/UIProcess/WebProcessProxy.h 2019-02-09 04:06:34 UTC (rev 241231)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.h 2019-02-09 04:36:57 UTC (rev 241232)
@@ -50,10 +50,6 @@
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
-#if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
-#include "DisplayLink.h"
-#endif
-
namespace API {
class Navigation;
class PageConfiguration;
@@ -421,10 +417,6 @@
#if PLATFORM(WATCHOS)
ProcessThrottler::BackgroundActivityToken m_backgroundActivityTokenForFullscreenFormControls;
#endif
-
-#if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
- Vector<std::unique_ptr<DisplayLink>> m_displayLinks;
-#endif
};
} // namespace WebKit
Modified: trunk/Source/WebKit/UIProcess/mac/DisplayLink.cpp (241231 => 241232)
--- trunk/Source/WebKit/UIProcess/mac/DisplayLink.cpp 2019-02-09 04:06:34 UTC (rev 241231)
+++ trunk/Source/WebKit/UIProcess/mac/DisplayLink.cpp 2019-02-09 04:36:57 UTC (rev 241232)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2018-2019 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,16 +28,13 @@
#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
-#include "DrawingAreaMessages.h"
#include "WebProcessMessages.h"
-#include "WebProcessProxy.h"
#include <wtf/ProcessPrivilege.h>
namespace WebKit {
-DisplayLink::DisplayLink(WebCore::PlatformDisplayID displayID, WebProcessProxy& webProcessProxy)
- : m_connection(webProcessProxy.connection())
- , m_displayID(displayID)
+DisplayLink::DisplayLink(WebCore::PlatformDisplayID displayID)
+ : m_displayID(displayID)
{
ASSERT(hasProcessPrivilege(ProcessPrivilege::CanCommunicateWithWindowServer));
CVReturn error = CVDisplayLinkCreateWithCGDisplay(displayID, &m_displayLink);
@@ -51,10 +48,6 @@
WTFLogAlways("Could not set the display link output callback: %d", error);
return;
}
-
- error = CVDisplayLinkStart(m_displayLink);
- if (error)
- WTFLogAlways("Could not start the display link: %d", error);
}
DisplayLink::~DisplayLink()
@@ -68,28 +61,73 @@
CVDisplayLinkRelease(m_displayLink);
}
-void DisplayLink::addObserver(unsigned observerID)
+void DisplayLink::addObserver(IPC::Connection& connection, unsigned observerID)
{
- m_observers.add(observerID);
+ ASSERT(RunLoop::isMain());
+ bool isRunning = !m_observers.isEmpty();
+
+ {
+ LockHolder locker(m_observersLock);
+ m_observers.ensure(&connection, [] {
+ return Vector<unsigned> { };
+ }).iterator->value.append(observerID);
+ }
+
+ if (!isRunning) {
+ CVReturn error = CVDisplayLinkStart(m_displayLink);
+ if (error)
+ WTFLogAlways("Could not start the display link: %d", error);
+ }
}
-void DisplayLink::removeObserver(unsigned observerID)
+void DisplayLink::removeObserver(IPC::Connection& connection, unsigned observerID)
{
- m_observers.remove(observerID);
+ ASSERT(RunLoop::isMain());
+
+ {
+ LockHolder locker(m_observersLock);
+
+ auto it = m_observers.find(&connection);
+ if (it == m_observers.end())
+ return;
+ bool removed = it->value.removeFirst(observerID);
+ ASSERT_UNUSED(removed, removed);
+ if (it->value.isEmpty())
+ m_observers.remove(it);
+ }
+
+ if (m_observers.isEmpty())
+ CVDisplayLinkStop(m_displayLink);
}
+void DisplayLink::removeObservers(IPC::Connection& connection)
+{
+ ASSERT(RunLoop::isMain());
+
+ {
+ LockHolder locker(m_observersLock);
+ m_observers.remove(&connection);
+ }
+
+ if (m_observers.isEmpty())
+ CVDisplayLinkStop(m_displayLink);
+}
+
bool DisplayLink::hasObservers() const
{
+ ASSERT(RunLoop::isMain());
return !m_observers.isEmpty();
}
CVReturn DisplayLink::displayLinkCallback(CVDisplayLinkRef displayLinkRef, const CVTimeStamp*, const CVTimeStamp*, CVOptionFlags, CVOptionFlags*, void* data)
{
- DisplayLink* displayLink = static_cast<DisplayLink*>(data);
- displayLink->m_connection->send(Messages::WebProcess::DisplayWasRefreshed(displayLink->m_displayID), 0);
+ auto* displayLink = static_cast<DisplayLink*>(data);
+ LockHolder locker(displayLink->m_observersLock);
+ for (auto& connection : displayLink->m_observers.keys())
+ connection->send(Messages::WebProcess::DisplayWasRefreshed(displayLink->m_displayID), 0);
return kCVReturnSuccess;
}
-}
+} // namespace WebKit
#endif
Modified: trunk/Source/WebKit/UIProcess/mac/DisplayLink.h (241231 => 241232)
--- trunk/Source/WebKit/UIProcess/mac/DisplayLink.h 2019-02-09 04:06:34 UTC (rev 241231)
+++ trunk/Source/WebKit/UIProcess/mac/DisplayLink.h 2019-02-09 04:36:57 UTC (rev 241232)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2018-2019 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,9 +28,9 @@
#if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
#include <CoreVideo/CVDisplayLink.h>
-
#include <WebCore/PlatformScreen.h>
-#include <wtf/HashSet.h>
+#include <wtf/HashMap.h>
+#include <wtf/Lock.h>
namespace IPC {
class Connection;
@@ -37,17 +37,16 @@
}
namespace WebKit {
-
-class WebProcessProxy;
class DisplayLink {
WTF_MAKE_FAST_ALLOCATED;
public:
- DisplayLink(WebCore::PlatformDisplayID, WebProcessProxy&);
+ explicit DisplayLink(WebCore::PlatformDisplayID);
~DisplayLink();
- void addObserver(unsigned observerID);
- void removeObserver(unsigned observerID);
+ void addObserver(IPC::Connection&, unsigned observerID);
+ void removeObserver(IPC::Connection&, unsigned observerID);
+ void removeObservers(IPC::Connection&);
bool hasObservers() const;
WebCore::PlatformDisplayID displayID() const { return m_displayID; }
@@ -56,12 +55,12 @@
static CVReturn displayLinkCallback(CVDisplayLinkRef, const CVTimeStamp*, const CVTimeStamp*, CVOptionFlags, CVOptionFlags*, void* data);
CVDisplayLinkRef m_displayLink { nullptr };
- HashSet<unsigned> m_observers;
- RefPtr<IPC::Connection> m_connection;
- WebCore::PlatformDisplayID m_displayID { 0 };
+ Lock m_observersLock;
+ HashMap<RefPtr<IPC::Connection>, Vector<unsigned>> m_observers;
+ WebCore::PlatformDisplayID m_displayID;
};
-}
+} // namespace WebKit
#endif
Modified: trunk/Source/WebKit/UIProcess/mac/WebProcessProxyMac.mm (241231 => 241232)
--- trunk/Source/WebKit/UIProcess/mac/WebProcessProxyMac.mm 2019-02-09 04:06:34 UTC (rev 241231)
+++ trunk/Source/WebKit/UIProcess/mac/WebProcessProxyMac.mm 2019-02-09 04:36:57 UTC (rev 241232)
@@ -74,29 +74,14 @@
void WebProcessProxy::startDisplayLink(unsigned observerID, uint32_t displayID)
{
ASSERT(hasProcessPrivilege(ProcessPrivilege::CanCommunicateWithWindowServer));
- for (auto& displayLink : m_displayLinks) {
- if (displayLink->displayID() == displayID) {
- displayLink->addObserver(observerID);
- return;
- }
- }
- auto displayLink = std::make_unique<DisplayLink>(displayID, *this);
- displayLink->addObserver(observerID);
- m_displayLinks.append(WTFMove(displayLink));
+ ASSERT(connection());
+ processPool().startDisplayLink(*connection(), observerID, displayID);
}
void WebProcessProxy::stopDisplayLink(unsigned observerID, uint32_t displayID)
{
- size_t pos = 0;
- for (auto& displayLink : m_displayLinks) {
- if (displayLink->displayID() == displayID) {
- displayLink->removeObserver(observerID);
- if (!displayLink->hasObservers())
- m_displayLinks.remove(pos);
- return;
- }
- pos++;
- }
+ ASSERT(connection());
+ processPool().stopDisplayLink(*connection(), observerID, displayID);
}
#endif