Title: [276222] trunk
Revision
276222
Author
[email protected]
Date
2021-04-17 22:23:02 -0700 (Sat, 17 Apr 2021)

Log Message

GPUConnectionToWebProcess::allowsExitUnderMemoryPressure() should check if libWebRTCCodecsProxy is used
https://bugs.webkit.org/show_bug.cgi?id=224709

Reviewed by Darin Adler.

Source/WebKit:

If the libWebRTCCodecsProxy has either encoders or decoders then the GPUProcess should not
exit under memory pressure, since it is not idle.

* GPUProcess/GPUConnectionToWebProcess.cpp:
(WebKit::GPUConnectionToWebProcess::allowsExitUnderMemoryPressure const):
* GPUProcess/webrtc/LibWebRTCCodecsProxy.h:
* GPUProcess/webrtc/LibWebRTCCodecsProxy.mm:
(WebKit::LibWebRTCCodecsProxy::createH264Decoder):
(WebKit::LibWebRTCCodecsProxy::createH265Decoder):
(WebKit::LibWebRTCCodecsProxy::createVP9Decoder):
(WebKit::LibWebRTCCodecsProxy::releaseDecoder):
(WebKit::LibWebRTCCodecsProxy::createEncoder):
(WebKit::LibWebRTCCodecsProxy::releaseEncoder):
(WebKit::LibWebRTCCodecsProxy::updateHasEncodersOrDecoders):
(WebKit::LibWebRTCCodecsProxy::allowsExitUnderMemoryPressure const):
Use a std::atomic<bool> to determine if the LibWebRTCCodecsProxy has encoders/decoders since
allowsExitUnderMemoryPressure() gets called on the main thread but m_encoders / m_decoders
get updated on a background thread.

Tools:

Add API test coverage.

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

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (276221 => 276222)


--- trunk/Source/WebKit/ChangeLog	2021-04-18 04:47:47 UTC (rev 276221)
+++ trunk/Source/WebKit/ChangeLog	2021-04-18 05:23:02 UTC (rev 276222)
@@ -1,3 +1,29 @@
+2021-04-17  Chris Dumez  <[email protected]>
+
+        GPUConnectionToWebProcess::allowsExitUnderMemoryPressure() should check if libWebRTCCodecsProxy is used
+        https://bugs.webkit.org/show_bug.cgi?id=224709
+
+        Reviewed by Darin Adler.
+
+        If the libWebRTCCodecsProxy has either encoders or decoders then the GPUProcess should not
+        exit under memory pressure, since it is not idle.
+
+        * GPUProcess/GPUConnectionToWebProcess.cpp:
+        (WebKit::GPUConnectionToWebProcess::allowsExitUnderMemoryPressure const):
+        * GPUProcess/webrtc/LibWebRTCCodecsProxy.h:
+        * GPUProcess/webrtc/LibWebRTCCodecsProxy.mm:
+        (WebKit::LibWebRTCCodecsProxy::createH264Decoder):
+        (WebKit::LibWebRTCCodecsProxy::createH265Decoder):
+        (WebKit::LibWebRTCCodecsProxy::createVP9Decoder):
+        (WebKit::LibWebRTCCodecsProxy::releaseDecoder):
+        (WebKit::LibWebRTCCodecsProxy::createEncoder):
+        (WebKit::LibWebRTCCodecsProxy::releaseEncoder):
+        (WebKit::LibWebRTCCodecsProxy::updateHasEncodersOrDecoders):
+        (WebKit::LibWebRTCCodecsProxy::allowsExitUnderMemoryPressure const):
+        Use a std::atomic<bool> to determine if the LibWebRTCCodecsProxy has encoders/decoders since
+        allowsExitUnderMemoryPressure() gets called on the main thread but m_encoders / m_decoders
+        get updated on a background thread.
+
 2021-04-17  Kimmo Kinnunen  <[email protected]>
 
         Unhandled IPC messages should use correct format with the decoder.destinationID() ASSERT message

Modified: trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp (276221 => 276222)


--- trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp	2021-04-18 04:47:47 UTC (rev 276221)
+++ trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp	2021-04-18 05:23:02 UTC (rev 276222)
@@ -307,6 +307,10 @@
     if (m_legacyCdmFactoryProxy && !m_legacyCdmFactoryProxy->allowsExitUnderMemoryPressure())
         return false;
 #endif
+#if PLATFORM(COCOA) && USE(LIBWEBRTC)
+    if (!m_libWebRTCCodecsProxy->allowsExitUnderMemoryPressure())
+        return false;
+#endif
     return true;
 }
 

Modified: trunk/Source/WebKit/GPUProcess/webrtc/LibWebRTCCodecsProxy.h (276221 => 276222)


--- trunk/Source/WebKit/GPUProcess/webrtc/LibWebRTCCodecsProxy.h	2021-04-18 04:47:47 UTC (rev 276221)
+++ trunk/Source/WebKit/GPUProcess/webrtc/LibWebRTCCodecsProxy.h	2021-04-18 05:23:02 UTC (rev 276222)
@@ -59,6 +59,8 @@
 
     void close();
 
+    bool allowsExitUnderMemoryPressure() const;
+
 private:
     explicit LibWebRTCCodecsProxy(GPUConnectionToWebProcess&);
 
@@ -80,11 +82,14 @@
     void encodeFrame(RTCEncoderIdentifier, WebCore::RemoteVideoSample&&, uint32_t timeStamp, bool shouldEncodeAsKeyFrame);
     void setEncodeRates(RTCEncoderIdentifier, uint32_t bitRate, uint32_t frameRate);
 
+    void updateHasEncodersOrDecoders();
+
     CFDictionaryRef ioSurfacePixelBufferCreationOptions(IOSurfaceRef);
 
     GPUConnectionToWebProcess& m_gpuConnectionToWebProcess;
     HashMap<RTCDecoderIdentifier, webrtc::LocalDecoder> m_decoders;
     HashMap<RTCEncoderIdentifier, webrtc::LocalEncoder> m_encoders;
+    std::atomic<bool> m_hasEncodersOrDecoders;
 
     Ref<WorkQueue> m_queue;
     std::unique_ptr<WebCore::ImageTransferSessionVT> m_imageTransferSession;

Modified: trunk/Source/WebKit/GPUProcess/webrtc/LibWebRTCCodecsProxy.mm (276221 => 276222)


--- trunk/Source/WebKit/GPUProcess/webrtc/LibWebRTCCodecsProxy.mm	2021-04-18 04:47:47 UTC (rev 276221)
+++ trunk/Source/WebKit/GPUProcess/webrtc/LibWebRTCCodecsProxy.mm	2021-04-18 05:23:02 UTC (rev 276222)
@@ -78,6 +78,7 @@
         if (auto sample = WebCore::RemoteVideoSample::create(pixelBuffer, MediaTime(timeStampNs, 1)))
             connection->send(Messages::LibWebRTCCodecs::CompletedDecoding { identifier, timeStamp, *sample }, 0);
     }).get()));
+    updateHasEncodersOrDecoders();
 }
 
 void LibWebRTCCodecsProxy::createH265Decoder(RTCDecoderIdentifier identifier)
@@ -87,6 +88,7 @@
         if (auto sample = WebCore::RemoteVideoSample::create(pixelBuffer, MediaTime(timeStampNs, 1)))
             connection->send(Messages::LibWebRTCCodecs::CompletedDecoding { identifier, timeStamp, *sample }, 0);
     }).get()));
+    updateHasEncodersOrDecoders();
 }
 
 void LibWebRTCCodecsProxy::createVP9Decoder(RTCDecoderIdentifier identifier)
@@ -96,13 +98,16 @@
         if (auto sample = WebCore::RemoteVideoSample::create(pixelBuffer, MediaTime(timeStampNs, 1)))
             connection->send(Messages::LibWebRTCCodecs::CompletedDecoding { identifier, timeStamp, *sample }, 0);
     }).get()));
+    updateHasEncodersOrDecoders();
 }
 
 void LibWebRTCCodecsProxy::releaseDecoder(RTCDecoderIdentifier identifier)
 {
     ASSERT(m_decoders.contains(identifier));
-    if (auto decoder = m_decoders.take(identifier))
+    if (auto decoder = m_decoders.take(identifier)) {
         webrtc::releaseLocalDecoder(decoder);
+        updateHasEncodersOrDecoders();
+    }
 }
 
 void LibWebRTCCodecsProxy::decodeFrame(RTCDecoderIdentifier identifier, uint32_t timeStamp, const IPC::DataReference& data)
@@ -139,13 +144,16 @@
     }).get());
     webrtc::setLocalEncoderLowLatency(encoder, useLowLatency);
     m_encoders.add(identifier, encoder);
+    updateHasEncodersOrDecoders();
 }
 
 void LibWebRTCCodecsProxy::releaseEncoder(RTCEncoderIdentifier identifier)
 {
     ASSERT(m_encoders.contains(identifier));
-    if (auto encoder = m_encoders.take(identifier))
+    if (auto encoder = m_encoders.take(identifier)) {
         webrtc::releaseLocalEncoder(encoder);
+        updateHasEncodersOrDecoders();
+    }
 }
 
 void LibWebRTCCodecsProxy::initializeEncoder(RTCEncoderIdentifier identifier, uint16_t width, uint16_t height, unsigned startBitrate, unsigned maxBitrate, unsigned minBitrate, uint32_t maxFramerate)
@@ -199,6 +207,16 @@
     webrtc::setLocalEncoderRates(encoder, bitRate, frameRate);
 }
 
+void LibWebRTCCodecsProxy::updateHasEncodersOrDecoders()
+{
+    m_hasEncodersOrDecoders = !m_encoders.isEmpty() || !m_decoders.isEmpty();
 }
 
+bool LibWebRTCCodecsProxy::allowsExitUnderMemoryPressure() const
+{
+    return !m_hasEncodersOrDecoders;
+}
+
+}
+
 #endif

Modified: trunk/Tools/ChangeLog (276221 => 276222)


--- trunk/Tools/ChangeLog	2021-04-18 04:47:47 UTC (rev 276221)
+++ trunk/Tools/ChangeLog	2021-04-18 05:23:02 UTC (rev 276222)
@@ -1,3 +1,17 @@
+2021-04-17  Chris Dumez  <[email protected]>
+
+        GPUConnectionToWebProcess::allowsExitUnderMemoryPressure() should check if libWebRTCCodecsProxy is used
+        https://bugs.webkit.org/show_bug.cgi?id=224709
+
+        Reviewed by Darin Adler.
+
+        Add API test coverage.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm:
+        (runMemoryPressureExitTest):
+        (waitUntilCaptureState):
+        (TEST):
+
 2021-04-17  Wenson Hsieh  <[email protected]>
 
         Remove PromisedAttachmentInfo::blobURL and adjacent code

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm (276221 => 276222)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm	2021-04-18 04:47:47 UTC (rev 276221)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm	2021-04-18 05:23:02 UTC (rev 276222)
@@ -28,11 +28,13 @@
 #import "PlatformUtilities.h"
 #import "TestNavigationDelegate.h"
 #import "TestWKWebView.h"
+#import "UserMediaCaptureUIDelegate.h"
 #import <WebKit/WKPreferencesPrivate.h>
 #import <WebKit/WKPreferencesRefPrivate.h>
 #import <WebKit/WKProcessPoolPrivate.h>
 #import <WebKit/WKString.h>
 #import <WebKit/WKWebViewConfiguration.h>
+#import <WebKit/WKWebViewConfigurationPrivate.h>
 #import <WebKit/WKWebViewPrivate.h>
 #import <notify.h>
 #import <wtf/Function.h>
@@ -493,14 +495,19 @@
     TestWebKitAPI::Util::run(&done);
 }
 
-static void runMemoryPressureExitTest(Function<void(WKWebView *)>&& loadTestPageSynchronously)
+static void runMemoryPressureExitTest(Function<void(WKWebView *)>&& loadTestPageSynchronously, Function<void(WKWebViewConfiguration *)>&& updateConfiguration = [](WKWebViewConfiguration *) { })
 {
     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("CaptureAudioInGPUProcessEnabled"));
+    WKPreferencesSetBoolValueForKeyForTesting((__bridge WKPreferencesRef)[configuration preferences], true, WKStringCreateWithUTF8CString("WebRTCPlatformCodecsInGPUProcessEnabled"));
+    WKPreferencesSetBoolValueForKeyForTesting((__bridge WKPreferencesRef)[configuration preferences], false, WKStringCreateWithUTF8CString("CaptureAudioInUIProcessEnabled"));
     WKPreferencesSetBoolValueForKeyForTesting((__bridge WKPreferencesRef)[configuration preferences], true, WKStringCreateWithUTF8CString("UseGPUProcessForCanvasRenderingEnabled"));
     WKPreferencesSetBoolValueForKeyForTesting((__bridge WKPreferencesRef)[configuration preferences], false, WKStringCreateWithUTF8CString("UseGPUProcessForDOMRenderingEnabled"));
 
+    updateConfiguration(configuration.get());
+
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 400, 400) configuration:configuration.get()]);
     loadTestPageSynchronously(webView.get());
 
@@ -565,6 +572,42 @@
     });
 }
 
+#if ENABLE(MEDIA_STREAM)
+static bool waitUntilCaptureState(WKWebView *webView, _WKMediaCaptureStateDeprecated expectedState)
+{
+    NSTimeInterval end = [[NSDate date] timeIntervalSinceReferenceDate] + 10;
+    do {
+        if ([webView _mediaCaptureState] == expectedState)
+            return true;
+
+        TestWebKitAPI::Util::spinRunLoop(1);
+
+        if ([[NSDate date] timeIntervalSinceReferenceDate] > end)
+            break;
+    } while (true);
+
+    return false;
+}
+
+TEST(GPUProcess, ExitsUnderMemoryPressureWebRTCCase)
+{
+    runMemoryPressureExitTest([](WKWebView *webView) {
+        auto delegate = adoptNS([[UserMediaCaptureUIDelegate alloc] init]);
+        webView.UIDelegate = delegate.get();
+
+        [webView loadTestPageNamed:@"getUserMedia"];
+        EXPECT_TRUE(waitUntilCaptureState(webView, _WKMediaCaptureStateDeprecatedActiveCamera));
+        [webView stringByEvaluatingJavaScript:@"captureAudioAndVideo(true)"];
+        [webView stringByEvaluatingJavaScript:@"createConnection()"];
+    }, [](WKWebViewConfiguration* configuration) {
+        auto preferences = configuration.preferences;
+        preferences._mediaCaptureRequiresSecureConnection = NO;
+        configuration._mediaCaptureEnabled = YES;
+        preferences._mockCaptureDevicesEnabled = YES;
+    });
+}
+#endif // ENABLE(MEDIA_STREAM)
+
 TEST(GPUProcess, ExitsUnderMemoryPressureWebAudioCase)
 {
     runMemoryPressureExitTest([](WKWebView *webView) {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to