Changeset 277774 in webkit


Ignore:
Timestamp:
May 19, 2021, 10:05:19 PM (4 years ago)
Author:
Chris Dumez
Message:

[GPUProcess] It is not safe to call GraphicsContext::paintFrameForMedia() off the main thread
https://bugs.webkit.org/show_bug.cgi?id=225996

Reviewed by Simon Fraser.

It is not safe to call GraphicsContext::paintFrameForMedia() off the main thread because it
relies on the MediaPlayer / MediaPlayerPrivate objects, which are main-thread object. Making
this function thread-safe would be a significant amount of work. As a result, I am simply
calling callOnMainThreadAndWait() in RemoteRenderingBackend::applyMediaItem(). Note that this
code path is only used when painting a video to a canvas.

  • GPUProcess/graphics/RemoteRenderingBackend.cpp:

(WebKit::RemoteRenderingBackend::applyMediaItem):
Make sure we call paintFrameForMedia() on the main thread.

  • GPUProcess/media/RemoteMediaPlayerManagerProxy.cpp:

(WebKit::RemoteMediaPlayerManagerProxy::createMediaPlayer):
(WebKit::RemoteMediaPlayerManagerProxy::deleteMediaPlayer):
(WebKit::RemoteMediaPlayerManagerProxy::mediaPlayer):

  • GPUProcess/media/RemoteMediaPlayerManagerProxy.h:

Drop lock that is no longer needed now that mediaPlayer() is always called on the main thread.

Location:
trunk/Source/WebKit
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r277767 r277774  
     12021-05-19  Chris Dumez  <cdumez@apple.com>
     2
     3        [GPUProcess] It is not safe to call GraphicsContext::paintFrameForMedia() off the main thread
     4        https://bugs.webkit.org/show_bug.cgi?id=225996
     5
     6        Reviewed by Simon Fraser.
     7
     8        It is not safe to call GraphicsContext::paintFrameForMedia() off the main thread because it
     9        relies on the MediaPlayer / MediaPlayerPrivate objects, which are main-thread object. Making
     10        this function thread-safe would be a significant amount of work. As a result, I am simply
     11        calling callOnMainThreadAndWait() in RemoteRenderingBackend::applyMediaItem(). Note that this
     12        code path is only used when painting a video to a canvas.
     13
     14        * GPUProcess/graphics/RemoteRenderingBackend.cpp:
     15        (WebKit::RemoteRenderingBackend::applyMediaItem):
     16        Make sure we call paintFrameForMedia() on the main thread.
     17
     18        * GPUProcess/media/RemoteMediaPlayerManagerProxy.cpp:
     19        (WebKit::RemoteMediaPlayerManagerProxy::createMediaPlayer):
     20        (WebKit::RemoteMediaPlayerManagerProxy::deleteMediaPlayer):
     21        (WebKit::RemoteMediaPlayerManagerProxy::mediaPlayer):
     22        * GPUProcess/media/RemoteMediaPlayerManagerProxy.h:
     23        Drop lock that is no longer needed now that mediaPlayer() is always called on the main thread.
     24
    1252021-05-19  Alex Christensen  <achristensen@webkit.org>
    226
  • trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp

    r277763 r277774  
    133133
    134134    auto& mediaItem = item.get<DisplayList::PaintFrameForMedia>();
    135     auto player = m_gpuConnectionToWebProcess->remoteMediaPlayerManagerProxy().mediaPlayer(mediaItem.identifier());
    136     if (!player)
    137         return true;
    138 
    139     context.paintFrameForMedia(*player, mediaItem.destination());
     135    callOnMainRunLoopAndWait([&, gpuConnectionToWebProcess = m_gpuConnectionToWebProcess, mediaPlayerIdentifier = mediaItem.identifier()] {
     136        auto player = gpuConnectionToWebProcess->remoteMediaPlayerManagerProxy().mediaPlayer(mediaPlayerIdentifier);
     137        if (!player)
     138            return;
     139        // It is currently not safe to call paintFrameForMedia() off the main thread.
     140        context.paintFrameForMedia(*player, mediaItem.destination());
     141    });
    140142    return true;
    141143}
  • trunk/Source/WebKit/GPUProcess/media/RemoteMediaPlayerManagerProxy.cpp

    r276993 r277774  
    6262    ASSERT(RunLoop::isMain());
    6363    ASSERT(m_gpuConnectionToWebProcess);
    64 
    65     auto locker = holdLock(m_proxiesLock);
    6664    ASSERT(!m_proxies.contains(identifier));
    6765
     
    7371{
    7472    ASSERT(RunLoop::isMain());
    75     {
    76         auto locker = holdLock(m_proxiesLock);
    77         if (auto proxy = m_proxies.take(identifier))
    78             proxy->invalidate();
    79     }
     73
     74    if (auto proxy = m_proxies.take(identifier))
     75        proxy->invalidate();
     76
    8077    if (m_gpuConnectionToWebProcess && allowsExitUnderMemoryPressure())
    8178        m_gpuConnectionToWebProcess->gpuProcess().tryExitIfUnusedAndUnderMemoryPressure();
     
    174171}
    175172
    176 // May get called on a background thread.
    177173RefPtr<MediaPlayer> RemoteMediaPlayerManagerProxy::mediaPlayer(const MediaPlayerIdentifier& identifier)
    178174{
    179     auto locker = holdLock(m_proxiesLock);
     175    ASSERT(RunLoop::isMain());
    180176    auto results = m_proxies.find(identifier);
    181177    if (results != m_proxies.end())
  • trunk/Source/WebKit/GPUProcess/media/RemoteMediaPlayerManagerProxy.h

    r276148 r277774  
    8484    void supportsKeySystem(WebCore::MediaPlayerEnums::MediaEngineIdentifier, const String&&, const String&&, CompletionHandler<void(bool)>&&);
    8585
    86     Lock m_proxiesLock;
    8786    HashMap<WebCore::MediaPlayerIdentifier, std::unique_ptr<RemoteMediaPlayerProxy>> m_proxies;
    8887    WeakPtr<GPUConnectionToWebProcess> m_gpuConnectionToWebProcess;
Note: See TracChangeset for help on using the changeset viewer.