Title: [275887] trunk
Revision
275887
Author
cdu...@apple.com
Date
2021-04-13 09:36:37 -0700 (Tue, 13 Apr 2021)

Log Message

The GPUProcess should only launch when it is needed
https://bugs.webkit.org/show_bug.cgi?id=224461

Reviewed by Eric Carlson.

Source/WebKit:

The GPUProcess should only launch when it is needed. This avoids wasting memory
on simple pages, especially until we enable "DOM rendering in GPU Process".

* WebProcess/GPU/GPUProcessConnection.cpp:
(WebKit::GPUProcessConnection::GPUProcessConnection):
As soon as we create a GPUProcessConnection, if "Media in GPUProcess" is enabled
we do some media-related initialization that we used to do in
WebProcess::setUseGPUProcessForMedia(). setUseGPUProcessForMedia() gets called
when constructing a WebPage and this initialization requires a GPUProcess. We
thus want to delay the initialization until we actually need a GPUProcess.

(WebKit::GPUProcessConnection::enableVP9Decoders):
Rename function to make it clear it is only used for VP9.

* WebProcess/GPU/GPUProcessConnection.h:
* WebProcess/GPU/media/RemoteAudioSession.cpp:
(WebKit::RemoteAudioSession::create):
(WebKit::RemoteAudioSession::RemoteAudioSession):
(WebKit::RemoteAudioSession::~RemoteAudioSession):
(WebKit::RemoteAudioSession::gpuProcessConnectionDidClose):
(WebKit::RemoteAudioSession::ensureConnection):
(WebKit::RemoteAudioSession::configuration const):
(WebKit::RemoteAudioSession::configuration):
(WebKit::RemoteAudioSession::setCategory):
(WebKit::RemoteAudioSession::setPreferredBufferSize):
(WebKit::RemoteAudioSession::tryToSetActiveInternal):
(WebKit::RemoteAudioSession::category const):
(WebKit::RemoteAudioSession::configurationChanged):
* WebProcess/GPU/media/RemoteAudioSession.h:
Update RemoteAudioSession to lazily initiate the GPUProcess connection instead
of doing it on construction. The RemoteAudioSession gets created as soon as we
create a WebPage, at which point we may not need a GPUProcess yet.

* WebProcess/GPU/media/ios/RemoteMediaSessionHelper.cpp:
(WebKit::RemoteMediaSessionHelper::RemoteMediaSessionHelper):
(WebKit::RemoteMediaSessionHelper::ensureConnection):
(WebKit::RemoteMediaSessionHelper::gpuProcessConnectionDidClose):
(WebKit::RemoteMediaSessionHelper::startMonitoringWirelessRoutesInternal):
(WebKit::RemoteMediaSessionHelper::stopMonitoringWirelessRoutesInternal):
(WebKit::RemoteMediaSessionHelper::providePresentingApplicationPID):
* WebProcess/GPU/media/ios/RemoteMediaSessionHelper.h:
Update RemoteMediaSessionHelper to lazily initiate the GPUProcess connection instead
of doing it on construction. The RemoteAudioSession gets created as soon as we
create a WebPage, at which point we may not need a GPUProcess yet.

* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::updatePreferences):
- Update GPUProcessConnection::updateParameters() call to enableVP9Decoders() due to rename.
  This makes it clear it is only useful for VP9. We also only call it if there is already
  a GPUProcess connection. If there is no connection right now, the GPUProcessConnection
  constructor will take care of getting the latest values from the PlatformMediaSessionManager
  and send them to the GPUProcess.
- Call ensureRemoteRenderingBackendProxy() only if we already have a GPUProcessConnection, to
  avoid eagerly launching the GPUProcess. If no GPUProcessConnection exists,
  WebProcess::ensureGPUProcessConnection() will take care of calling ensureRemoteRenderingBackendProxy()
  on its pages.

* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::ensureGPUProcessConnection):
This logic used to happen in WebPage::updatePreferences(). However, I had to make it conditional on
have a GPUProcessConnection to avoid eagerly launching the GPUProcess. As a result, I now need some
logic when we initiate the GPUProcessConnection to call ensureRemoteRenderingBackendProxy() on the
WebPages. Note that this is a temporary workaround until we enable DOM Rendering in the GPUProcess.

(WebKit::WebProcess::setUseGPUProcessForMedia):
setUseGPUProcessForMedia() gets called when constructing a WebPage, at which point a GPUProcess is
not useful yet. As a result, we should make sure setUseGPUProcessForMedia() does not call
ensureGPUProcessConnection() to avoid eagerly launching the GPUProcess and potentially wasting memory.
To fix this, I moved some of the logic to the GPUProcessConnection constructor so that we do the
media-related GPUProcess initialization ONLY once we actually have a GPUProcess.

Tools:

Add layout test coverage.

* TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm:
(TEST):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (275886 => 275887)


--- trunk/Source/WebKit/ChangeLog	2021-04-13 15:55:34 UTC (rev 275886)
+++ trunk/Source/WebKit/ChangeLog	2021-04-13 16:36:37 UTC (rev 275887)
@@ -1,3 +1,81 @@
+2021-04-13  Chris Dumez  <cdu...@apple.com>
+
+        The GPUProcess should only launch when it is needed
+        https://bugs.webkit.org/show_bug.cgi?id=224461
+
+        Reviewed by Eric Carlson.
+
+        The GPUProcess should only launch when it is needed. This avoids wasting memory
+        on simple pages, especially until we enable "DOM rendering in GPU Process".
+
+        * WebProcess/GPU/GPUProcessConnection.cpp:
+        (WebKit::GPUProcessConnection::GPUProcessConnection):
+        As soon as we create a GPUProcessConnection, if "Media in GPUProcess" is enabled
+        we do some media-related initialization that we used to do in
+        WebProcess::setUseGPUProcessForMedia(). setUseGPUProcessForMedia() gets called
+        when constructing a WebPage and this initialization requires a GPUProcess. We
+        thus want to delay the initialization until we actually need a GPUProcess.
+
+        (WebKit::GPUProcessConnection::enableVP9Decoders):
+        Rename function to make it clear it is only used for VP9.
+
+        * WebProcess/GPU/GPUProcessConnection.h:
+        * WebProcess/GPU/media/RemoteAudioSession.cpp:
+        (WebKit::RemoteAudioSession::create):
+        (WebKit::RemoteAudioSession::RemoteAudioSession):
+        (WebKit::RemoteAudioSession::~RemoteAudioSession):
+        (WebKit::RemoteAudioSession::gpuProcessConnectionDidClose):
+        (WebKit::RemoteAudioSession::ensureConnection):
+        (WebKit::RemoteAudioSession::configuration const):
+        (WebKit::RemoteAudioSession::configuration):
+        (WebKit::RemoteAudioSession::setCategory):
+        (WebKit::RemoteAudioSession::setPreferredBufferSize):
+        (WebKit::RemoteAudioSession::tryToSetActiveInternal):
+        (WebKit::RemoteAudioSession::category const):
+        (WebKit::RemoteAudioSession::configurationChanged):
+        * WebProcess/GPU/media/RemoteAudioSession.h:
+        Update RemoteAudioSession to lazily initiate the GPUProcess connection instead
+        of doing it on construction. The RemoteAudioSession gets created as soon as we
+        create a WebPage, at which point we may not need a GPUProcess yet.
+
+        * WebProcess/GPU/media/ios/RemoteMediaSessionHelper.cpp:
+        (WebKit::RemoteMediaSessionHelper::RemoteMediaSessionHelper):
+        (WebKit::RemoteMediaSessionHelper::ensureConnection):
+        (WebKit::RemoteMediaSessionHelper::gpuProcessConnectionDidClose):
+        (WebKit::RemoteMediaSessionHelper::startMonitoringWirelessRoutesInternal):
+        (WebKit::RemoteMediaSessionHelper::stopMonitoringWirelessRoutesInternal):
+        (WebKit::RemoteMediaSessionHelper::providePresentingApplicationPID):
+        * WebProcess/GPU/media/ios/RemoteMediaSessionHelper.h:
+        Update RemoteMediaSessionHelper to lazily initiate the GPUProcess connection instead
+        of doing it on construction. The RemoteAudioSession gets created as soon as we
+        create a WebPage, at which point we may not need a GPUProcess yet.
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::updatePreferences):
+        - Update GPUProcessConnection::updateParameters() call to enableVP9Decoders() due to rename.
+          This makes it clear it is only useful for VP9. We also only call it if there is already
+          a GPUProcess connection. If there is no connection right now, the GPUProcessConnection
+          constructor will take care of getting the latest values from the PlatformMediaSessionManager
+          and send them to the GPUProcess.
+        - Call ensureRemoteRenderingBackendProxy() only if we already have a GPUProcessConnection, to
+          avoid eagerly launching the GPUProcess. If no GPUProcessConnection exists,
+          WebProcess::ensureGPUProcessConnection() will take care of calling ensureRemoteRenderingBackendProxy()
+          on its pages.
+
+        * WebProcess/WebProcess.cpp:
+        (WebKit::WebProcess::ensureGPUProcessConnection):
+        This logic used to happen in WebPage::updatePreferences(). However, I had to make it conditional on
+        have a GPUProcessConnection to avoid eagerly launching the GPUProcess. As a result, I now need some
+        logic when we initiate the GPUProcessConnection to call ensureRemoteRenderingBackendProxy() on the
+        WebPages. Note that this is a temporary workaround until we enable DOM Rendering in the GPUProcess.
+
+        (WebKit::WebProcess::setUseGPUProcessForMedia):
+        setUseGPUProcessForMedia() gets called when constructing a WebPage, at which point a GPUProcess is
+        not useful yet. As a result, we should make sure setUseGPUProcessForMedia() does not call
+        ensureGPUProcessConnection() to avoid eagerly launching the GPUProcess and potentially wasting memory.
+        To fix this, I moved some of the logic to the GPUProcessConnection constructor so that we do the
+        media-related GPUProcess initialization ONLY once we actually have a GPUProcess.
+
 2021-04-13  Sihui Liu  <sihui_...@apple.com>
 
         StorageArea in LocalStorageNamespace can be abandoned

Modified: trunk/Source/WebKit/WebProcess/GPU/GPUProcessConnection.cpp (275886 => 275887)


--- trunk/Source/WebKit/WebProcess/GPU/GPUProcessConnection.cpp	2021-04-13 15:55:34 UTC (rev 275886)
+++ trunk/Source/WebKit/WebProcess/GPU/GPUProcessConnection.cpp	2021-04-13 16:36:37 UTC (rev 275887)
@@ -100,6 +100,21 @@
     m_connection->open();
 
     addLanguageChangeObserver(this, languagesChanged);
+
+    if (WebProcess::singleton().shouldUseRemoteRenderingFor(RenderingPurpose::MediaPainting)) {
+#if ENABLE(ENCRYPTED_MEDIA)
+        auto& cdmFactories = CDMFactory::registeredFactories();
+        cdmFactories.clear();
+        cdmFactory().registerFactory(cdmFactories);
+#endif
+#if ENABLE(LEGACY_ENCRYPTED_MEDIA)
+        legacyCDMFactory().registerFactory();
+#endif
+        mediaEngineConfigurationFactory().registerFactory();
+#if ENABLE(VP9)
+        enableVP9Decoders(PlatformMediaSessionManager::shouldEnableVP8Decoder(), PlatformMediaSessionManager::shouldEnableVP9Decoder(), PlatformMediaSessionManager::shouldEnableVP9SWDecoder());
+#endif
+    }
 }
 
 GPUProcessConnection::~GPUProcessConnection()
@@ -247,18 +262,18 @@
     PlatformMediaSessionManager::sharedManager().processDidReceiveRemoteControlCommand(type, argument);
 }
 
-void GPUProcessConnection::updateParameters(const WebPageCreationParameters& parameters)
+#if ENABLE(VP9)
+void GPUProcessConnection::enableVP9Decoders(bool enableVP8Decoder, bool enableVP9Decoder, bool enableVP9SWDecoder)
 {
-#if ENABLE(VP9)
-    if (m_enableVP8Decoder == parameters.shouldEnableVP8Decoder && m_enableVP9Decoder == parameters.shouldEnableVP9Decoder && m_enableVP9SWDecoder == parameters.shouldEnableVP9SWDecoder)
+    if (m_enableVP8Decoder == enableVP8Decoder && m_enableVP9Decoder == enableVP9Decoder && m_enableVP9SWDecoder == enableVP9SWDecoder)
         return;
 
-    m_enableVP9Decoder = parameters.shouldEnableVP8Decoder;
-    m_enableVP9Decoder = parameters.shouldEnableVP9Decoder;
-    m_enableVP9SWDecoder = parameters.shouldEnableVP9SWDecoder;
-    connection().send(Messages::GPUConnectionToWebProcess::EnableVP9Decoders(parameters.shouldEnableVP8Decoder, parameters.shouldEnableVP9Decoder, parameters.shouldEnableVP9SWDecoder), { });
+    m_enableVP9Decoder = enableVP8Decoder;
+    m_enableVP9Decoder = enableVP9Decoder;
+    m_enableVP9SWDecoder = enableVP9SWDecoder;
+    connection().send(Messages::GPUConnectionToWebProcess::EnableVP9Decoders(enableVP8Decoder, enableVP9Decoder, enableVP9SWDecoder), { });
+}
 #endif
-}
 
 void GPUProcessConnection::updateMediaConfiguration()
 {

Modified: trunk/Source/WebKit/WebProcess/GPU/GPUProcessConnection.h (275886 => 275887)


--- trunk/Source/WebKit/WebProcess/GPU/GPUProcessConnection.h	2021-04-13 15:55:34 UTC (rev 275886)
+++ trunk/Source/WebKit/WebProcess/GPU/GPUProcessConnection.h	2021-04-13 16:36:37 UTC (rev 275887)
@@ -82,10 +82,11 @@
 
     RemoteMediaEngineConfigurationFactory& mediaEngineConfigurationFactory();
 
-    void updateParameters(const WebPageCreationParameters&);
     void updateMediaConfiguration();
 
 #if ENABLE(VP9)
+    void enableVP9Decoders(bool enableVP8Decoder, bool enableVP9Decoder, bool enableVP9SWDecoder);
+
     bool isVP8DecoderEnabled() const { return m_enableVP8Decoder; }
     bool isVP9DecoderEnabled() const { return m_enableVP9Decoder; }
     bool isVPSWDecoderEnabled() const { return m_enableVP9SWDecoder; }

Modified: trunk/Source/WebKit/WebProcess/GPU/media/RemoteAudioSession.cpp (275886 => 275887)


--- trunk/Source/WebKit/WebProcess/GPU/media/RemoteAudioSession.cpp	2021-04-13 15:55:34 UTC (rev 275886)
+++ trunk/Source/WebKit/WebProcess/GPU/media/RemoteAudioSession.cpp	2021-04-13 16:36:37 UTC (rev 275887)
@@ -29,7 +29,6 @@
 #if ENABLE(GPU_PROCESS) && USE(AUDIO_SESSION)
 
 #include "GPUConnectionToWebProcessMessages.h"
-#include "GPUProcessConnection.h"
 #include "GPUProcessProxy.h"
 #include "RemoteAudioSessionMessages.h"
 #include "RemoteAudioSessionProxyMessages.h"
@@ -42,39 +41,67 @@
 
 UniqueRef<RemoteAudioSession> RemoteAudioSession::create(WebProcess& process)
 {
-    RemoteAudioSessionConfiguration configuration;
-    process.ensureGPUProcessConnection().connection().sendSync(Messages::GPUConnectionToWebProcess::EnsureAudioSession(), Messages::GPUConnectionToWebProcess::EnsureAudioSession::Reply(configuration), { });
-    return makeUniqueRef<RemoteAudioSession>(process, WTFMove(configuration));
+    return makeUniqueRef<RemoteAudioSession>(process);
 }
 
-RemoteAudioSession::RemoteAudioSession(WebProcess& process, RemoteAudioSessionConfiguration&& configuration)
+RemoteAudioSession::RemoteAudioSession(WebProcess& process)
     : m_process(process)
-    , m_configuration(WTFMove(configuration))
 {
-    m_process.ensureGPUProcessConnection().messageReceiverMap().addMessageReceiver(Messages::RemoteAudioSession::messageReceiverName(), *this);
 }
 
 RemoteAudioSession::~RemoteAudioSession()
 {
-    if (auto* connection = m_process.existingGPUProcessConnection())
-        connection->messageReceiverMap().removeMessageReceiver(Messages::RemoteAudioSession::messageReceiverName());
+    if (m_gpuProcessConnection)
+        m_gpuProcessConnection->messageReceiverMap().removeMessageReceiver(Messages::RemoteAudioSession::messageReceiverName());
 }
 
-IPC::Connection& RemoteAudioSession::connection()
+void RemoteAudioSession::gpuProcessConnectionDidClose(GPUProcessConnection& connection)
 {
-    return m_process.ensureGPUProcessConnection().connection();
+    ASSERT(m_gpuProcessConnection.get() == &connection);
+    m_gpuProcessConnection = nullptr;
+    connection.messageReceiverMap().removeMessageReceiver(Messages::RemoteAudioSession::messageReceiverName());
+    connection.removeClient(*this);
 }
 
+IPC::Connection& RemoteAudioSession::ensureConnection()
+{
+    if (!m_gpuProcessConnection) {
+        m_gpuProcessConnection = makeWeakPtr(m_process.ensureGPUProcessConnection());
+        m_gpuProcessConnection->addClient(*this);
+        m_gpuProcessConnection->messageReceiverMap().addMessageReceiver(Messages::RemoteAudioSession::messageReceiverName(), *this);
+
+        RemoteAudioSessionConfiguration configuration;
+        ensureConnection().sendSync(Messages::GPUConnectionToWebProcess::EnsureAudioSession(), Messages::GPUConnectionToWebProcess::EnsureAudioSession::Reply(configuration), { });
+        m_configuration = WTFMove(configuration);
+    }
+    return m_gpuProcessConnection->connection();
+}
+
+const RemoteAudioSessionConfiguration& RemoteAudioSession::configuration() const
+{
+    if (!m_configuration)
+        const_cast<RemoteAudioSession*>(this)->ensureConnection();
+    return *m_configuration;
+}
+
+RemoteAudioSessionConfiguration& RemoteAudioSession::configuration()
+{
+    if (!m_configuration)
+        ensureConnection();
+    return *m_configuration;
+}
+
 void RemoteAudioSession::setCategory(CategoryType type, RouteSharingPolicy policy)
 {
 #if PLATFORM(IOS_FAMILY)
-    if (type == m_configuration.category && policy == m_configuration.routeSharingPolicy)
+    auto& configuration = this->configuration();
+    if (type == configuration.category && policy == configuration.routeSharingPolicy)
         return;
 
-    m_configuration.category = type;
-    m_configuration.routeSharingPolicy = policy;
+    configuration.category = type;
+    configuration.routeSharingPolicy = policy;
 
-    connection().send(Messages::RemoteAudioSessionProxy::SetCategory(type, policy), { });
+    ensureConnection().send(Messages::RemoteAudioSessionProxy::SetCategory(type, policy), { });
 #elif PLATFORM(MAC)
     // FIXME: Move AudioSessionRoutingArbitratorProxy to the GPU process (webkit.org/b/217535)
     AudioSession::setCategory(type, policy);
@@ -86,15 +113,15 @@
 
 void RemoteAudioSession::setPreferredBufferSize(size_t size)
 {
-    connection().send(Messages::RemoteAudioSessionProxy::SetPreferredBufferSize(size), { });
+    ensureConnection().send(Messages::RemoteAudioSessionProxy::SetPreferredBufferSize(size), { });
 }
 
 bool RemoteAudioSession::tryToSetActiveInternal(bool active)
 {
     bool succeeded;
-    connection().sendSync(Messages::RemoteAudioSessionProxy::TryToSetActive(active), Messages::RemoteAudioSessionProxy::TryToSetActive::Reply(succeeded), { });
+    ensureConnection().sendSync(Messages::RemoteAudioSessionProxy::TryToSetActive(active), Messages::RemoteAudioSessionProxy::TryToSetActive::Reply(succeeded), { });
     if (succeeded)
-        m_configuration.isActive = active;
+        configuration().isActive = active;
     return succeeded;
 }
 
@@ -101,7 +128,7 @@
 AudioSession::CategoryType RemoteAudioSession::category() const
 {
 #if PLATFORM(IOS_FAMILY)
-    return m_configuration.category;
+    return configuration().category;
 #elif PLATFORM(MAC)
     return AudioSession::category();
 #else
@@ -111,9 +138,9 @@
 
 void RemoteAudioSession::configurationChanged(RemoteAudioSessionConfiguration&& configuration)
 {
-    bool mutedStateChanged = configuration.isMuted != m_configuration.isMuted;
+    bool mutedStateChanged = !m_configuration || configuration.isMuted != m_configuration->isMuted;
 
-    m_configuration = configuration;
+    m_configuration = WTFMove(configuration);
 
     if (mutedStateChanged)
         handleMutedStateChange();

Modified: trunk/Source/WebKit/WebProcess/GPU/media/RemoteAudioSession.h (275886 => 275887)


--- trunk/Source/WebKit/WebProcess/GPU/media/RemoteAudioSession.h	2021-04-13 15:55:34 UTC (rev 275886)
+++ trunk/Source/WebKit/WebProcess/GPU/media/RemoteAudioSession.h	2021-04-13 16:36:37 UTC (rev 275887)
@@ -27,6 +27,7 @@
 
 #if ENABLE(GPU_PROCESS) && USE(AUDIO_SESSION)
 
+#include "GPUProcessConnection.h"
 #include "MessageReceiver.h"
 #include "RemoteAudioSessionConfiguration.h"
 #include <WebCore/AudioSession.h>
@@ -42,6 +43,7 @@
 
 class RemoteAudioSession final
     : public WebCore::AudioSession
+    , public GPUProcessConnection::Client
     , IPC::MessageReceiver {
     WTF_MAKE_FAST_ALLOCATED;
 public:
@@ -49,9 +51,9 @@
     ~RemoteAudioSession();
 
 private:
-    friend UniqueRef<RemoteAudioSession> WTF::makeUniqueRefWithoutFastMallocCheck<RemoteAudioSession>(WebProcess&, RemoteAudioSessionConfiguration&&);
-    RemoteAudioSession(WebProcess&, RemoteAudioSessionConfiguration&&);
-    IPC::Connection& connection();
+    friend UniqueRef<RemoteAudioSession> WTF::makeUniqueRefWithoutFastMallocCheck<RemoteAudioSession>(WebProcess&);
+    explicit RemoteAudioSession(WebProcess&);
+    IPC::Connection& ensureConnection();
 
     // IPC::MessageReceiver
     void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
@@ -59,24 +61,32 @@
     // Messages
     void configurationChanged(RemoteAudioSessionConfiguration&&);
 
+    // GPUProcessConnection::Client
+    void gpuProcessConnectionDidClose(GPUProcessConnection&) final;
+
     // AudioSession
     void setCategory(CategoryType, WebCore::RouteSharingPolicy) final;
     void setPreferredBufferSize(size_t) final;
     bool tryToSetActiveInternal(bool) final;
 
+    const RemoteAudioSessionConfiguration& configuration() const;
+    RemoteAudioSessionConfiguration& configuration();
+    void initializeConfigurationIfNecessary();
+
     CategoryType category() const final;
-    WebCore::RouteSharingPolicy routeSharingPolicy() const final { return m_configuration.routeSharingPolicy; }
-    String routingContextUID() const final { return m_configuration.routingContextUID; }
-    float sampleRate() const final { return m_configuration.sampleRate; }
-    size_t bufferSize() const final { return m_configuration.bufferSize; }
-    size_t numberOfOutputChannels() const final { return m_configuration.numberOfOutputChannels; }
-    size_t maximumNumberOfOutputChannels() const final { return m_configuration.maximumNumberOfOutputChannels; }
-    size_t preferredBufferSize() const final { return m_configuration.preferredBufferSize; }
-    bool isMuted() const final { return m_configuration.isMuted; }
-    bool isActive() const final { return m_configuration.isActive; }
+    WebCore::RouteSharingPolicy routeSharingPolicy() const final { return configuration().routeSharingPolicy; }
+    String routingContextUID() const final { return configuration().routingContextUID; }
+    float sampleRate() const final { return configuration().sampleRate; }
+    size_t bufferSize() const final { return configuration().bufferSize; }
+    size_t numberOfOutputChannels() const final { return configuration().numberOfOutputChannels; }
+    size_t maximumNumberOfOutputChannels() const final { return configuration().maximumNumberOfOutputChannels; }
+    size_t preferredBufferSize() const final { return configuration().preferredBufferSize; }
+    bool isMuted() const final { return configuration().isMuted; }
+    bool isActive() const final { return configuration().isActive; }
 
     WebProcess& m_process;
-    RemoteAudioSessionConfiguration m_configuration;
+    Optional<RemoteAudioSessionConfiguration> m_configuration;
+    WeakPtr<GPUProcessConnection> m_gpuProcessConnection;
 };
 
 }

Modified: trunk/Source/WebKit/WebProcess/GPU/media/ios/RemoteMediaSessionHelper.cpp (275886 => 275887)


--- trunk/Source/WebKit/WebProcess/GPU/media/ios/RemoteMediaSessionHelper.cpp	2021-04-13 15:55:34 UTC (rev 275886)
+++ trunk/Source/WebKit/WebProcess/GPU/media/ios/RemoteMediaSessionHelper.cpp	2021-04-13 16:36:37 UTC (rev 275887)
@@ -44,42 +44,39 @@
 RemoteMediaSessionHelper::RemoteMediaSessionHelper(WebProcess& process)
     : m_process(process)
 {
-    connectToGPUProcess();
 }
 
-void RemoteMediaSessionHelper::connectToGPUProcess()
+IPC::Connection& RemoteMediaSessionHelper::ensureConnection()
 {
-    auto& gpuProcessConnection = m_process.ensureGPUProcessConnection();
-    gpuProcessConnection.addClient(*this);
-    gpuProcessConnection.messageReceiverMap().addMessageReceiver(Messages::RemoteMediaSessionHelper::messageReceiverName(), *this);
-    gpuProcessConnection.connection().send(Messages::GPUConnectionToWebProcess::EnsureMediaSessionHelper(), { });
+    if (!m_gpuProcessConnection) {
+        m_gpuProcessConnection = makeWeakPtr(m_process.ensureGPUProcessConnection());
+        m_gpuProcessConnection->addClient(*this);
+        m_gpuProcessConnection->messageReceiverMap().addMessageReceiver(Messages::RemoteMediaSessionHelper::messageReceiverName(), *this);
+        m_gpuProcessConnection->connection().send(Messages::GPUConnectionToWebProcess::EnsureMediaSessionHelper(), { });
+    }
+    return m_gpuProcessConnection->connection();
 }
 
-IPC::Connection& RemoteMediaSessionHelper::connection()
-{
-    return m_process.ensureGPUProcessConnection().connection();
-}
-
 void RemoteMediaSessionHelper::gpuProcessConnectionDidClose(GPUProcessConnection& gpuProcessConnection)
 {
     gpuProcessConnection.removeClient(*this);
     gpuProcessConnection.messageReceiverMap().removeMessageReceiver(*this);
-    connectToGPUProcess();
+    m_gpuProcessConnection = nullptr;
 }
 
 void RemoteMediaSessionHelper::startMonitoringWirelessRoutesInternal()
 {
-    connection().send(Messages::RemoteMediaSessionHelperProxy::StartMonitoringWirelessRoutes(), { });
+    ensureConnection().send(Messages::RemoteMediaSessionHelperProxy::StartMonitoringWirelessRoutes(), { });
 }
 
 void RemoteMediaSessionHelper::stopMonitoringWirelessRoutesInternal()
 {
-    connection().send(Messages::RemoteMediaSessionHelperProxy::StopMonitoringWirelessRoutes(), { });
+    ensureConnection().send(Messages::RemoteMediaSessionHelperProxy::StopMonitoringWirelessRoutes(), { });
 }
 
 void RemoteMediaSessionHelper::providePresentingApplicationPID(int pid)
 {
-    connection().send(Messages::RemoteMediaSessionHelperProxy::ProvidePresentingApplicationPID(pid), { });
+    ensureConnection().send(Messages::RemoteMediaSessionHelperProxy::ProvidePresentingApplicationPID(pid), { });
 }
 
 void RemoteMediaSessionHelper::activeVideoRouteDidChange(SupportsAirPlayVideo supportsAirPlayVideo, MediaPlaybackTargetContext&& targetContext)

Modified: trunk/Source/WebKit/WebProcess/GPU/media/ios/RemoteMediaSessionHelper.h (275886 => 275887)


--- trunk/Source/WebKit/WebProcess/GPU/media/ios/RemoteMediaSessionHelper.h	2021-04-13 15:55:34 UTC (rev 275886)
+++ trunk/Source/WebKit/WebProcess/GPU/media/ios/RemoteMediaSessionHelper.h	2021-04-13 16:36:37 UTC (rev 275887)
@@ -44,7 +44,7 @@
     RemoteMediaSessionHelper(WebProcess&);
     virtual ~RemoteMediaSessionHelper() = default;
 
-    IPC::Connection& connection();
+    IPC::Connection& ensureConnection();
 
     using HasAvailableTargets = WebCore::MediaSessionHelperClient::HasAvailableTargets;
     using PlayingToAutomotiveHeadUnit = WebCore::MediaSessionHelperClient::PlayingToAutomotiveHeadUnit;
@@ -53,8 +53,6 @@
     using SuspendedUnderLock = WebCore::MediaSessionHelperClient::SuspendedUnderLock;
 
 private:
-    void connectToGPUProcess();
-
     // IPC::MessageReceiver
     void didReceiveMessage(IPC::Connection&, IPC::Decoder&) final;
 
@@ -70,6 +68,7 @@
     void activeVideoRouteDidChange(SupportsAirPlayVideo, WebCore::MediaPlaybackTargetContext&&);
 
     WebProcess& m_process;
+    WeakPtr<GPUProcessConnection> m_gpuProcessConnection;
 };
 
 }

Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (275886 => 275887)


--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2021-04-13 15:55:34 UTC (rev 275886)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp	2021-04-13 16:36:37 UTC (rev 275887)
@@ -851,19 +851,16 @@
     send(Messages::WebPageProxy::DidCreateContextInWebProcessForVisibilityPropagation(m_contextForVisibilityPropagation->contextID()));
 #endif
 
-#if ENABLE(GPU_PROCESS)
-    if (m_shouldPlayMediaInGPUProcess)
-        WebProcess::singleton().ensureGPUProcessConnection().updateParameters(parameters);
-#endif
-
 #if ENABLE(IPC_TESTING_API)
     m_visitedLinkTableID = parameters.visitedLinkTableID;
 #endif
 
 #if ENABLE(VP9)
+    PlatformMediaSessionManager::setShouldEnableVP8Decoder(parameters.shouldEnableVP8Decoder);
     PlatformMediaSessionManager::setShouldEnableVP9Decoder(parameters.shouldEnableVP9Decoder);
-    PlatformMediaSessionManager::setShouldEnableVP8Decoder(parameters.shouldEnableVP8Decoder);
     PlatformMediaSessionManager::setShouldEnableVP9SWDecoder(parameters.shouldEnableVP9SWDecoder);
+    if (m_shouldPlayMediaInGPUProcess && WebProcess::singleton().existingGPUProcessConnection())
+        WebProcess::singleton().existingGPUProcessConnection()->enableVP9Decoders(parameters.shouldEnableVP8Decoder, parameters.shouldEnableVP9Decoder, parameters.shouldEnableVP9SWDecoder);
 #endif
 
     m_page->setCanUseCredentialStorage(parameters.canUseCredentialStorage);
@@ -3938,7 +3935,7 @@
     // For now, it is possible to use the GPUProcess for media playback only. Because media does not
     // use the RemoteRenderingBackend, we need to force the creation of a RemoteRenderingBackend in
     // the GPUProcess so that the page gets a visibility propagation view.
-    if (m_shouldPlayMediaInGPUProcess && !usingGPUProcessForDOMRendering)
+    if (m_shouldPlayMediaInGPUProcess && !usingGPUProcessForDOMRendering && WebProcess::singleton().existingGPUProcessConnection())
         ensureRemoteRenderingBackendProxy();
 #endif
 

Modified: trunk/Source/WebKit/WebProcess/WebProcess.cpp (275886 => 275887)


--- trunk/Source/WebKit/WebProcess/WebProcess.cpp	2021-04-13 15:55:34 UTC (rev 275886)
+++ trunk/Source/WebKit/WebProcess/WebProcess.cpp	2021-04-13 16:36:37 UTC (rev 275887)
@@ -1209,6 +1209,17 @@
         ASSERT(connectionInfo.auditToken);
         m_gpuProcessConnection->setAuditToken(WTFMove(connectionInfo.auditToken));
 #endif
+
+        // FIXME: This will no longer be needed once we use the GPUProcess for DOM rendering.
+        // For now, it is possible to use the GPUProcess for media playback only. Because media does not
+        // use the RemoteRenderingBackend, we need to force the creation of a RemoteRenderingBackend in
+        // the GPUProcess so that the page gets a visibility propagation view.
+        RunLoop::main().dispatch([this] {
+            if (m_useGPUProcessForMedia && !m_useGPUProcessForDOMRendering) {
+                for (auto& page : m_pageMap.values())
+                    page->ensureRemoteRenderingBackendProxy();
+            }
+        });
     }
     
     return *m_gpuProcessConnection;
@@ -1954,13 +1965,11 @@
     m_useGPUProcessForMedia = useGPUProcessForMedia;
 
 #if ENABLE(ENCRYPTED_MEDIA)
-    auto& cdmFactories = CDMFactory::registeredFactories();
-    cdmFactories.clear();
-
-    if (useGPUProcessForMedia)
-        ensureGPUProcessConnection().cdmFactory().registerFactory(cdmFactories);
-    else
+    if (!useGPUProcessForMedia) {
+        auto& cdmFactories = CDMFactory::registeredFactories();
+        cdmFactories.clear();
         CDMFactory::platformRegisterFactories(cdmFactories);
+    }
 #endif
 
 #if USE(AUDIO_SESSION)
@@ -1978,15 +1987,11 @@
 #endif
 
 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
-    if (useGPUProcessForMedia)
-        ensureGPUProcessConnection().legacyCDMFactory().registerFactory();
-    else
+    if (!useGPUProcessForMedia)
         LegacyCDM::resetFactories();
 #endif
 
-    if (useGPUProcessForMedia)
-        ensureGPUProcessConnection().mediaEngineConfigurationFactory().registerFactory();
-    else
+    if (!useGPUProcessForMedia)
         MediaEngineConfigurationFactory::resetFactories();
 
     if (useGPUProcessForMedia)

Modified: trunk/Tools/ChangeLog (275886 => 275887)


--- trunk/Tools/ChangeLog	2021-04-13 15:55:34 UTC (rev 275886)
+++ trunk/Tools/ChangeLog	2021-04-13 16:36:37 UTC (rev 275887)
@@ -1,3 +1,15 @@
+2021-04-13  Chris Dumez  <cdu...@apple.com>
+
+        The GPUProcess should only launch when it is needed
+        https://bugs.webkit.org/show_bug.cgi?id=224461
+
+        Reviewed by Eric Carlson.
+
+        Add layout test coverage.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm:
+        (TEST):
+
 2021-04-13  Carlos Garcia Campos  <cgar...@igalia.com>
 
         [GTK4] WTR crash in PlatformWebView::dismissAllPopupMenus()

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm (275886 => 275887)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm	2021-04-13 15:55:34 UTC (rev 275886)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm	2021-04-13 16:36:37 UTC (rev 275887)
@@ -213,6 +213,22 @@
     EXPECT_TRUE([webView _isPlayingAudio]);
 }
 
+TEST(GPUProcess, OnlyLaunchesGPUProcessWhenNecessary)
+{
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    WKPreferencesSetBoolValueForKeyForTesting((__bridge WKPreferencesRef)[configuration preferences], true, WKStringCreateWithUTF8CString("UseGPUProcessForMediaEnabled"));
+    WKPreferencesSetBoolValueForKeyForTesting((__bridge WKPreferencesRef)[configuration preferences], true, WKStringCreateWithUTF8CString("CaptureVideoInGPUProcessEnabled"));
+    WKPreferencesSetBoolValueForKeyForTesting((__bridge WKPreferencesRef)[configuration preferences], true, WKStringCreateWithUTF8CString("UseGPUProcessForCanvasRenderingEnabled"));
+    WKPreferencesSetBoolValueForKeyForTesting((__bridge WKPreferencesRef)[configuration preferences], false, WKStringCreateWithUTF8CString("UseGPUProcessForDOMRenderingEnabled"));
+
+    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 400, 400) configuration:configuration.get()]);
+    [webView synchronouslyLoadTestPageNamed:@"simple"];
+
+    TestWebKitAPI::Util::spinRunLoop(10);
+
+    EXPECT_EQ([configuration.get().processPool _gpuProcessIdentifier], 0);
+}
+
 TEST(GPUProcess, CrashWhilePlayingVideo)
 {
     auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to