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) {