Title: [277774] trunk/Source/WebKit
Revision
277774
Author
[email protected]
Date
2021-05-19 22:05:19 -0700 (Wed, 19 May 2021)

Log 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.

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (277773 => 277774)


--- trunk/Source/WebKit/ChangeLog	2021-05-20 03:34:28 UTC (rev 277773)
+++ trunk/Source/WebKit/ChangeLog	2021-05-20 05:05:19 UTC (rev 277774)
@@ -1,3 +1,27 @@
+2021-05-19  Chris Dumez  <[email protected]>
+
+        [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.
+
 2021-05-19  Alex Christensen  <[email protected]>
 
         Add support for Navigation Timing Level 2

Modified: trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp (277773 => 277774)


--- trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp	2021-05-20 03:34:28 UTC (rev 277773)
+++ trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp	2021-05-20 05:05:19 UTC (rev 277774)
@@ -132,11 +132,13 @@
         return false;
 
     auto& mediaItem = item.get<DisplayList::PaintFrameForMedia>();
-    auto player = m_gpuConnectionToWebProcess->remoteMediaPlayerManagerProxy().mediaPlayer(mediaItem.identifier());
-    if (!player)
-        return true;
-
-    context.paintFrameForMedia(*player, mediaItem.destination());
+    callOnMainRunLoopAndWait([&, gpuConnectionToWebProcess = m_gpuConnectionToWebProcess, mediaPlayerIdentifier = mediaItem.identifier()] {
+        auto player = gpuConnectionToWebProcess->remoteMediaPlayerManagerProxy().mediaPlayer(mediaPlayerIdentifier);
+        if (!player)
+            return;
+        // It is currently not safe to call paintFrameForMedia() off the main thread.
+        context.paintFrameForMedia(*player, mediaItem.destination());
+    });
     return true;
 }
 

Modified: trunk/Source/WebKit/GPUProcess/media/RemoteMediaPlayerManagerProxy.cpp (277773 => 277774)


--- trunk/Source/WebKit/GPUProcess/media/RemoteMediaPlayerManagerProxy.cpp	2021-05-20 03:34:28 UTC (rev 277773)
+++ trunk/Source/WebKit/GPUProcess/media/RemoteMediaPlayerManagerProxy.cpp	2021-05-20 05:05:19 UTC (rev 277774)
@@ -61,8 +61,6 @@
 {
     ASSERT(RunLoop::isMain());
     ASSERT(m_gpuConnectionToWebProcess);
-
-    auto locker = holdLock(m_proxiesLock);
     ASSERT(!m_proxies.contains(identifier));
 
     auto proxy = makeUnique<RemoteMediaPlayerProxy>(*this, identifier, m_gpuConnectionToWebProcess->connection(), engineIdentifier, WTFMove(proxyConfiguration));
@@ -72,11 +70,10 @@
 void RemoteMediaPlayerManagerProxy::deleteMediaPlayer(MediaPlayerIdentifier identifier)
 {
     ASSERT(RunLoop::isMain());
-    {
-        auto locker = holdLock(m_proxiesLock);
-        if (auto proxy = m_proxies.take(identifier))
-            proxy->invalidate();
-    }
+
+    if (auto proxy = m_proxies.take(identifier))
+        proxy->invalidate();
+
     if (m_gpuConnectionToWebProcess && allowsExitUnderMemoryPressure())
         m_gpuConnectionToWebProcess->gpuProcess().tryExitIfUnusedAndUnderMemoryPressure();
 }
@@ -173,10 +170,9 @@
     return false;
 }
 
-// May get called on a background thread.
 RefPtr<MediaPlayer> RemoteMediaPlayerManagerProxy::mediaPlayer(const MediaPlayerIdentifier& identifier)
 {
-    auto locker = holdLock(m_proxiesLock);
+    ASSERT(RunLoop::isMain());
     auto results = m_proxies.find(identifier);
     if (results != m_proxies.end())
         return results->value->mediaPlayer();

Modified: trunk/Source/WebKit/GPUProcess/media/RemoteMediaPlayerManagerProxy.h (277773 => 277774)


--- trunk/Source/WebKit/GPUProcess/media/RemoteMediaPlayerManagerProxy.h	2021-05-20 03:34:28 UTC (rev 277773)
+++ trunk/Source/WebKit/GPUProcess/media/RemoteMediaPlayerManagerProxy.h	2021-05-20 05:05:19 UTC (rev 277774)
@@ -83,7 +83,6 @@
     void clearMediaCacheForOrigins(WebCore::MediaPlayerEnums::MediaEngineIdentifier, const String&&, HashSet<WebCore::SecurityOriginData>&&);
     void supportsKeySystem(WebCore::MediaPlayerEnums::MediaEngineIdentifier, const String&&, const String&&, CompletionHandler<void(bool)>&&);
 
-    Lock m_proxiesLock;
     HashMap<WebCore::MediaPlayerIdentifier, std::unique_ptr<RemoteMediaPlayerProxy>> m_proxies;
     WeakPtr<GPUConnectionToWebProcess> m_gpuConnectionToWebProcess;
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to