⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 276214 in webkit


Ignore:
Timestamp:
Apr 17, 2021, 5:10:13 PM (5 years ago)
Author:
Chris Dumez
Message:

LibWebRTCCodecs eagerly launches the GPUProcess and always relaunches it on exit
https://bugs.webkit.org/show_bug.cgi?id=224704

Reviewed by Darin Adler.

LibWebRTCCodecs eagerly launches the GPUProcess and always relaunches it on exit. The GPUProcess
should only be (re-)launched when needed. In the case of the LibWebRTCCodecs, it seems it only
needs a GPUProcess connection if it has m_decoders / m_encoders are non-empty.

  • WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp:

(WebKit::LibWebRTCCodecs::ensureGPUProcessConnectionOnMainThread):
Renamed startListeningForIPC() to ensureGPUProcessConnectionOnMainThread(). Only do the
connection initialization if m_connection is not null.

(WebKit::LibWebRTCCodecs::ensureGPUProcessConnectionAndDispatchToThread):
Version of dispatchToThread() which makes sure that the GPUProcessConnection is initialized
before dispatching. It is used when constructing a decoder / encoder. It sets the
m_needsGPUProcessConnection flag to true to indicate someone needed the connection
(and that we should re-initiate it in case it is severed). If the connection is already
initialized, then it does a simple dispatchToThread(). If the connection is not initialized
yet, then we have to hop to the main thread (if not already on it) to initialize the
GPUProcessConnection.

(WebKit::LibWebRTCCodecs::gpuProcessConnectionMayNoLongerBeNeeded):
Function that gets called on the background thread every time a encoder / decoder is
removed. Its purpose is to set m_needsGPUProcessConnection back to false once we no
longer have any encoder / decoder, so that gpuProcessConnectionDidClose() does not
attempt to relaunch the GPUProcess if it goes away.

LibWebRTCCodecs::setCallbacks():
Check if VP9Support is enabled via PlatformMediaSessionManager instead of from the
GPUProcessConnection. This avoids eagerly launching the GPUProcess. The
GPUProcessConnection constructor gets its VPx support information from
PlatformMediaSessionManager anyway. The WebPage constructor is where the VPx support
information comes from and it updates the VPx flags on the PlatformMediaSessionManager.
The WebPage constructor only updates the VPx flags on the GPUProcessConnection if this
connection already exists to avoid eagerly launching the GPUProcess.

(WebKit::LibWebRTCCodecs::createDecoder):

  • Call ensureGPUProcessConnectionAndDispatchToThread() instead of dispatchToThread() to make sure we have a GPUProcessConnection before creating the decoder.
  • Add a missing locker for m_connectionLock on the background thread since it is using m_connection (pre-existing bug).

(WebKit::LibWebRTCCodecs::releaseDecoder):
Call gpuProcessConnectionMayNoLongerBeNeeded() to reset the m_needsGPUProcessConnection
flag to false if necessary.

(WebKit::LibWebRTCCodecs::createEncoder):

  • Call ensureGPUProcessConnectionAndDispatchToThread() instead of dispatchToThread() to make sure we have a GPUProcessConnection before creating the encoder.

(WebKit::LibWebRTCCodecs::releaseEncoder):
Call gpuProcessConnectionMayNoLongerBeNeeded() to reset the m_needsGPUProcessConnection
flag to false if necessary.

(WebKit::LibWebRTCCodecs::gpuProcessConnectionDidClose):

  • Clear m_connection when the GPUProcess connection is severed (note that this does not necessarily indicate a crash since the GPUProcess exits when idle and under memory pressure).
  • Only re-initiate the GPUProcess connection if m_needsGPUProcessConnection is true, meaning that we have encoders/decoders. I use this flag instead of checking m_encoders & m_decoders since those containers are modified on the background thread and this function is called on the main thread.
  • WebProcess/GPU/webrtc/LibWebRTCCodecs.h:

(WebKit::LibWebRTCCodecs::create):

  • Stop calling startListeningForIPC() on construction as we don't want to launch the GPUProcess

until an encoder / decoder is created.

  • Fix a pre-existing issue where the class subclasses ThreadSafeRefCounted (via ThreadMessageReceiverRefCounted) and yet was using std::unique_ptr<> instead of RefPtr<>.
  • WebProcess/WebProcess.h:
Location:
trunk/Source
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/wtf/Locker.h

    r268271 r276214  
    8484        return result;
    8585    }
     86
     87    T* lockable() { return m_lockable; }
    8688   
    8789    explicit operator bool() const { return !!m_lockable; }
  • trunk/Source/WebKit/ChangeLog

    r276212 r276214  
     12021-04-17  Chris Dumez  <cdumez@apple.com>
     2
     3        LibWebRTCCodecs eagerly launches the GPUProcess and always relaunches it on exit
     4        https://bugs.webkit.org/show_bug.cgi?id=224704
     5
     6        Reviewed by Darin Adler.
     7
     8        LibWebRTCCodecs eagerly launches the GPUProcess and always relaunches it on exit. The GPUProcess
     9        should only be (re-)launched when needed. In the case of the LibWebRTCCodecs, it seems it only
     10        needs a GPUProcess connection if it has m_decoders / m_encoders are non-empty.
     11
     12        * WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp:
     13        (WebKit::LibWebRTCCodecs::ensureGPUProcessConnectionOnMainThread):
     14        Renamed startListeningForIPC() to ensureGPUProcessConnectionOnMainThread(). Only do the
     15        connection initialization if m_connection is not null.
     16
     17        (WebKit::LibWebRTCCodecs::ensureGPUProcessConnectionAndDispatchToThread):
     18        Version of dispatchToThread() which makes sure that the GPUProcessConnection is initialized
     19        before dispatching. It is used when constructing a decoder / encoder. It sets the
     20        m_needsGPUProcessConnection flag to true to indicate someone needed the connection
     21        (and that we should re-initiate it in case it is severed). If the connection is already
     22        initialized, then it does a simple dispatchToThread(). If the connection is not initialized
     23        yet, then we have to hop to the main thread (if not already on it) to initialize the
     24        GPUProcessConnection.
     25
     26        (WebKit::LibWebRTCCodecs::gpuProcessConnectionMayNoLongerBeNeeded):
     27        Function that gets called on the background thread every time a encoder / decoder is
     28        removed. Its purpose is to set m_needsGPUProcessConnection back to false once we no
     29        longer have any encoder / decoder, so that gpuProcessConnectionDidClose() does not
     30        attempt to relaunch the GPUProcess if it goes away.
     31
     32        LibWebRTCCodecs::setCallbacks():
     33        Check if VP9Support is enabled via PlatformMediaSessionManager instead of from the
     34        GPUProcessConnection. This avoids eagerly launching the GPUProcess. The
     35        GPUProcessConnection constructor gets its VPx support information from
     36        PlatformMediaSessionManager anyway. The WebPage constructor is where the VPx support
     37        information comes from and it updates the VPx flags on the PlatformMediaSessionManager.
     38        The WebPage constructor only updates the VPx flags on the GPUProcessConnection if this
     39        connection already exists to avoid eagerly launching the GPUProcess.
     40
     41        (WebKit::LibWebRTCCodecs::createDecoder):
     42        - Call ensureGPUProcessConnectionAndDispatchToThread() instead of dispatchToThread()
     43          to make sure we have a GPUProcessConnection before creating the decoder.
     44        - Add a missing locker for m_connectionLock on the background thread since it is using
     45          m_connection (pre-existing bug).
     46
     47        (WebKit::LibWebRTCCodecs::releaseDecoder):
     48        Call gpuProcessConnectionMayNoLongerBeNeeded() to reset the m_needsGPUProcessConnection
     49        flag to false if necessary.
     50
     51        (WebKit::LibWebRTCCodecs::createEncoder):
     52        - Call ensureGPUProcessConnectionAndDispatchToThread() instead of dispatchToThread()
     53          to make sure we have a GPUProcessConnection before creating the encoder.
     54
     55        (WebKit::LibWebRTCCodecs::releaseEncoder):
     56        Call gpuProcessConnectionMayNoLongerBeNeeded() to reset the m_needsGPUProcessConnection
     57        flag to false if necessary.
     58
     59        (WebKit::LibWebRTCCodecs::gpuProcessConnectionDidClose):
     60        - Clear m_connection when the GPUProcess connection is severed (note that this does not
     61          necessarily indicate a crash since the GPUProcess exits when idle and under memory
     62          pressure).
     63        - Only re-initiate the GPUProcess connection if m_needsGPUProcessConnection is true,
     64          meaning that we have encoders/decoders. I use this flag instead of checking m_encoders
     65          & m_decoders since those containers are modified on the background thread and this
     66          function is called on the main thread.
     67
     68        * WebProcess/GPU/webrtc/LibWebRTCCodecs.h:
     69        (WebKit::LibWebRTCCodecs::create):
     70        - Stop calling startListeningForIPC() on construction as we don't want to launch the GPUProcess
     71        until an encoder / decoder is created.
     72        - Fix a pre-existing issue where the class subclasses ThreadSafeRefCounted (via
     73          ThreadMessageReceiverRefCounted) and yet was using std::unique_ptr<> instead of
     74          RefPtr<>.
     75
     76        * WebProcess/WebProcess.h:
     77
    1782021-04-17  Chris Dumez  <cdumez@apple.com>
    279
  • trunk/Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.cpp

    r275525 r276214  
    3535#include "WebProcess.h"
    3636#include <WebCore/LibWebRTCMacros.h>
     37#include <WebCore/PlatformMediaSessionManager.h>
    3738#include <WebCore/RealtimeVideoUtilities.h>
    3839#include <WebCore/RemoteVideoSample.h>
     
    164165}
    165166
     167Ref<LibWebRTCCodecs> LibWebRTCCodecs::create()
     168{
     169    return adoptRef(*new LibWebRTCCodecs);
     170}
     171
    166172LibWebRTCCodecs::LibWebRTCCodecs()
    167173    : m_queue(WorkQueue::create("LibWebRTCCodecs", WorkQueue::Type::Serial, WorkQueue::QOS::UserInteractive))
     
    169175}
    170176
    171 void LibWebRTCCodecs::startListeningForIPC()
    172 {
    173     ASSERT(!m_connection);
     177void LibWebRTCCodecs::ensureGPUProcessConnectionOnMainThread(Locker<Lock>& locker)
     178{
     179    ASSERT(isMainRunLoop());
     180    ASSERT_UNUSED(locker, locker.lockable() == &m_connectionLock);
     181    if (m_connection)
     182        return;
     183
    174184    auto& gpuConnection = WebProcess::singleton().ensureGPUProcessConnection();
    175185    gpuConnection.addClient(*this);
     
    178188}
    179189
     190// May be called on any thread.
     191void LibWebRTCCodecs::ensureGPUProcessConnectionAndDispatchToThread(Function<void()>&& task)
     192{
     193    m_needsGPUProcessConnection = true;
     194    {
     195        auto locker = holdLock(m_connectionLock);
     196        if (m_connection)
     197            return dispatchToThread(WTFMove(task));
     198    }
     199    ensureOnMainRunLoop([this, task = WTFMove(task)]() mutable {
     200        auto locker = holdLock(m_connectionLock);
     201        ensureGPUProcessConnectionOnMainThread(locker);
     202        dispatchToThread(WTFMove(task));
     203    });
     204}
     205
     206void LibWebRTCCodecs::gpuProcessConnectionMayNoLongerBeNeeded()
     207{
     208    ASSERT(!isMainRunLoop());
     209    if (m_encoders.isEmpty() && m_decoders.isEmpty())
     210        m_needsGPUProcessConnection = false;
     211}
     212
    180213LibWebRTCCodecs::~LibWebRTCCodecs()
    181214{
     
    197230
    198231#if ENABLE(VP9)
    199     auto& gpuConnection = WebProcess::singleton().ensureGPUProcessConnection();
    200232    // FIMXE: We should disable VP9VTB if VP9 hardware decoding is enabled but there is no support for it.
    201     WebProcess::singleton().libWebRTCCodecs().setVP9VTBSupport(gpuConnection.isVP9DecoderEnabled() || gpuConnection.isVPSWDecoderEnabled());
     233    WebProcess::singleton().libWebRTCCodecs().setVP9VTBSupport(PlatformMediaSessionManager::shouldEnableVP9Decoder() || PlatformMediaSessionManager::shouldEnableVP9SWDecoder());
    202234#endif
    203235
     
    213245    decoder->type = type;
    214246
    215     dispatchToThread([this, decoder = WTFMove(decoder)]() mutable {
     247    ensureGPUProcessConnectionAndDispatchToThread([this, decoder = WTFMove(decoder)]() mutable {
     248        auto locker = holdLock(m_connectionLock);
    216249        decoder->connection = m_connection;
    217250        createRemoteDecoder(*decoder, *m_connection);
     
    229262    dispatchToThread([this, decoderIdentifier = decoder.identifier] {
    230263        ASSERT(m_decoders.contains(decoderIdentifier));
    231         if (auto decoder = m_decoders.take(decoderIdentifier))
     264        if (auto decoder = m_decoders.take(decoderIdentifier)) {
    232265            decoder->connection->send(Messages::LibWebRTCCodecsProxy::ReleaseDecoder { decoderIdentifier }, 0);
     266            gpuProcessConnectionMayNoLongerBeNeeded();
     267        }
    233268    });
    234269    return 0;
     
    332367        parameters.append(std::make_pair(String::fromUTF8(keyValue.first.data(), keyValue.first.length()), String::fromUTF8(keyValue.second.data(), keyValue.second.length())));
    333368
    334     dispatchToThread([this, encoder = WTFMove(encoder), type, parameters = WTFMove(parameters)]() mutable {
     369    ensureGPUProcessConnectionAndDispatchToThread([this, encoder = WTFMove(encoder), type, parameters = WTFMove(parameters)]() mutable {
    335370        LockHolder holder(m_connectionLock);
    336371        encoder->connection = m_connection;
     
    352387        auto encoder = m_encoders.take(encoderIdentifier);
    353388        encoder->connection->send(Messages::LibWebRTCCodecsProxy::ReleaseEncoder { encoderIdentifier }, 0);
     389        gpuProcessConnectionMayNoLongerBeNeeded();
    354390    });
    355391    return 0;
     
    461497void LibWebRTCCodecs::gpuProcessConnectionDidClose(GPUProcessConnection&)
    462498{
    463     auto& gpuConnection = WebProcess::singleton().ensureGPUProcessConnection();
    464     gpuConnection.addClient(*this);
    465     {
    466         auto lock = holdLock(m_connectionLock);
    467         m_connection->removeThreadMessageReceiver(Messages::LibWebRTCCodecs::messageReceiverName());
    468         m_connection = makeRef(gpuConnection.connection());
    469         m_connection->addThreadMessageReceiver(Messages::LibWebRTCCodecs::messageReceiverName(), this);
    470     }
    471 
     499    ASSERT(isMainRunLoop());
     500    auto locker = holdLock(m_connectionLock);
     501    std::exchange(m_connection, nullptr)->removeThreadMessageReceiver(Messages::LibWebRTCCodecs::messageReceiverName());
     502    if (!m_needsGPUProcessConnection)
     503        return;
     504
     505    ensureGPUProcessConnectionOnMainThread(locker);
    472506    dispatchToThread([this]() {
    473507        // Lock everything so that we can update encoder/decoder connection.
  • trunk/Source/WebKit/WebProcess/GPU/webrtc/LibWebRTCCodecs.h

    r273074 r276214  
    6363    WTF_MAKE_FAST_ALLOCATED;
    6464public:
    65     static std::unique_ptr<LibWebRTCCodecs> create()
    66     {
    67         auto instance = std::unique_ptr<LibWebRTCCodecs>(new LibWebRTCCodecs);
    68         instance->startListeningForIPC();
    69         return instance;
    70     }
     65    static Ref<LibWebRTCCodecs> create();
    7166    ~LibWebRTCCodecs();
    7267
     
    126121private:
    127122    LibWebRTCCodecs();
    128     void startListeningForIPC();
     123    void ensureGPUProcessConnectionAndDispatchToThread(Function<void()>&&);
     124    void ensureGPUProcessConnectionOnMainThread(Locker<Lock>&);
     125    void gpuProcessConnectionMayNoLongerBeNeeded();
    129126
    130127    void failedDecoding(RTCDecoderIdentifier);
     
    145142    HashMap<RTCEncoderIdentifier, std::unique_ptr<Encoder>> m_encoders;
    146143
     144    std::atomic<bool> m_needsGPUProcessConnection;
     145
    147146    Lock m_connectionLock;
    148147    RefPtr<IPC::Connection> m_connection;
  • trunk/Source/WebKit/WebProcess/WebProcess.h

    r275163 r276214  
    622622    RefPtr<GPUProcessConnection> m_gpuProcessConnection;
    623623#if PLATFORM(COCOA) && USE(LIBWEBRTC)
    624     std::unique_ptr<LibWebRTCCodecs> m_libWebRTCCodecs;
     624    RefPtr<LibWebRTCCodecs> m_libWebRTCCodecs;
    625625#endif
    626626#endif
Note: See TracChangeset for help on using the changeset viewer.