Changeset 276189 in webkit
- Timestamp:
- Apr 16, 2021, 6:30:19 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
-
Source/WebKit/ChangeLog (modified) (1 diff)
-
Source/WebKit/GPUProcess/media/RemoteAudioDestinationManager.cpp (modified) (1 diff)
-
Source/WebKit/WebProcess/GPU/media/RemoteAudioDestinationProxy.cpp (modified) (7 diffs)
-
Source/WebKit/WebProcess/GPU/media/RemoteAudioDestinationProxy.h (modified) (2 diffs)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm (modified) (1 diff)
-
Tools/TestWebKitAPI/Tests/WebKitCocoa/audio-context-playing.html (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r276188 r276189 1 2021-04-16 Chris Dumez <cdumez@apple.com> 2 3 RemoteAudioDestinationProxy should not launch / relaunch the GPUProcess unless it is actually rendering 4 https://bugs.webkit.org/show_bug.cgi?id=224691 5 6 Reviewed by Geoffrey Garen. 7 8 RemoteAudioDestinationProxy was initiating a connection to the GPUProcess in its constructor and 9 re-initiating the connection right away upon GPUProcess crash. This goes against our recent efforts 10 to run the GPUProcess only when it is actually needed. The RemoteAudioDestinationProxy really only 11 needs the GPUProcess when it is actually rendering / playing. 12 13 * GPUProcess/media/RemoteAudioDestinationManager.cpp: 14 (WebKit::RemoteAudioDestinationManager::allowsExitUnderMemoryPressure const): 15 Allow the GPUProcess to exit when under memory pressure even if it has AudioDestinations, as long 16 as they are not playing. 17 18 * WebProcess/GPU/media/RemoteAudioDestinationProxy.cpp: 19 (WebKit::RemoteAudioDestinationProxy::RemoteAudioDestinationProxy): 20 (WebKit::RemoteAudioDestinationProxy::ensureGPUProcessConnection): 21 (WebKit::RemoteAudioDestinationProxy::~RemoteAudioDestinationProxy): 22 (WebKit::RemoteAudioDestinationProxy::startRendering): 23 (WebKit::RemoteAudioDestinationProxy::stopRendering): 24 (WebKit::RemoteAudioDestinationProxy::storageChanged): 25 (WebKit::RemoteAudioDestinationProxy::gpuProcessConnectionDidClose): 26 * WebProcess/GPU/media/RemoteAudioDestinationProxy.h: 27 1 28 2021-04-16 Chris Dumez <cdumez@apple.com> 2 29 -
trunk/Source/WebKit/GPUProcess/media/RemoteAudioDestinationManager.cpp
r276188 r276189 190 190 bool RemoteAudioDestinationManager::allowsExitUnderMemoryPressure() const 191 191 { 192 return m_audioDestinations.isEmpty(); 192 for (auto& audioDestination : m_audioDestinations.values()) { 193 if (audioDestination->isPlaying()) 194 return false; 195 } 196 return true; 193 197 } 194 198 -
trunk/Source/WebKit/WebProcess/GPU/media/RemoteAudioDestinationProxy.cpp
r275553 r276189 70 70 , m_numberOfInputChannels(numberOfInputChannels) 71 71 { 72 connectToGPUProcess();73 72 } 74 73 … … 100 99 } 101 100 102 void RemoteAudioDestinationProxy::connectToGPUProcess() 103 { 104 auto& connection = WebProcess::singleton().ensureGPUProcessConnection(); 105 connection.addClient(*this); 106 auto didSucceed = connection.connection().sendSync( 107 Messages::RemoteAudioDestinationManager::CreateAudioDestination(m_inputDeviceId, m_numberOfInputChannels, numberOfOutputChannels(), sampleRate(), hardwareSampleRate(), m_renderSemaphore), Messages::RemoteAudioDestinationManager::CreateAudioDestination::Reply(m_destinationID), 0); 108 109 if (!didSucceed) { 110 // The GPUProcess likely crashed during this synchronous IPC. gpuProcessConnectionDidClose() will get called to reconnect to the GPUProcess. 111 RELEASE_LOG_ERROR(Media, "RemoteAudioDestinationProxy::connectToGPUProcess: Failed to send RemoteAudioDestinationManager::CreateAudioDestination() IPC (GPU process likely crashed)"); 112 return; 101 GPUProcessConnection& RemoteAudioDestinationProxy::ensureGPUProcessConnection() 102 { 103 if (!m_gpuProcessConnection) { 104 m_gpuProcessConnection = makeWeakPtr(WebProcess::singleton().ensureGPUProcessConnection()); 105 m_gpuProcessConnection->addClient(*this); 106 107 #if PLATFORM(COCOA) 108 m_currentFrame = 0; 109 AudioStreamBasicDescription streamFormat; 110 getAudioStreamBasicDescription(streamFormat); 111 m_ringBuffer->allocate(streamFormat, m_numberOfFrames); 112 m_audioBufferList = makeUnique<WebCore::WebAudioBufferList>(streamFormat); 113 m_audioBufferList->setSampleCount(WebCore::AudioUtilities::renderQuantumSize); 114 #endif 115 116 startRenderingThread(); 113 117 } 114 115 116 #if PLATFORM(COCOA) 117 m_currentFrame = 0; 118 AudioStreamBasicDescription streamFormat; 119 getAudioStreamBasicDescription(streamFormat); 120 m_ringBuffer->allocate(streamFormat, m_numberOfFrames); 121 m_audioBufferList = makeUnique<WebCore::WebAudioBufferList>(streamFormat); 122 m_audioBufferList->setSampleCount(WebCore::AudioUtilities::renderQuantumSize); 123 #endif 124 125 startRenderingThread(); 118 return *m_gpuProcessConnection; 119 } 120 121 RemoteAudioDestinationIdentifier RemoteAudioDestinationProxy::destinationID() 122 { 123 if (!m_destinationID) 124 ensureGPUProcessConnection().connection().sendSync(Messages::RemoteAudioDestinationManager::CreateAudioDestination(m_inputDeviceId, m_numberOfInputChannels, numberOfOutputChannels(), sampleRate(), hardwareSampleRate(), m_renderSemaphore), Messages::RemoteAudioDestinationManager::CreateAudioDestination::Reply(m_destinationID), 0); 125 return m_destinationID; 126 126 } 127 127 128 128 RemoteAudioDestinationProxy::~RemoteAudioDestinationProxy() 129 129 { 130 auto& connection = WebProcess::singleton().ensureGPUProcessConnection();131 132 connection.connection().sendWithAsyncReply(133 Messages::RemoteAudioDestinationManager::DeleteAudioDestination(m_destinationID), [] {134 // Can't remove this from proxyMap() here because the object would have been already deleted.135 } );130 if (m_gpuProcessConnection && m_destinationID) { 131 m_gpuProcessConnection->connection().sendWithAsyncReply( 132 Messages::RemoteAudioDestinationManager::DeleteAudioDestination(m_destinationID), [] { 133 // Can't remove this from proxyMap() here because the object would have been already deleted. 134 }); 135 } 136 136 137 137 stopRenderingThread(); … … 140 140 void RemoteAudioDestinationProxy::startRendering(CompletionHandler<void(bool)>&& completionHandler) 141 141 { 142 WebProcess::singleton().ensureGPUProcessConnection().connection().sendWithAsyncReply(Messages::RemoteAudioDestinationManager::StartAudioDestination(m_destinationID), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](bool isPlaying) mutable {142 ensureGPUProcessConnection().connection().sendWithAsyncReply(Messages::RemoteAudioDestinationManager::StartAudioDestination(destinationID()), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](bool isPlaying) mutable { 143 143 setIsPlaying(isPlaying); 144 144 completionHandler(isPlaying); … … 148 148 void RemoteAudioDestinationProxy::stopRendering(CompletionHandler<void(bool)>&& completionHandler) 149 149 { 150 WebProcess::singleton().ensureGPUProcessConnection().connection().sendWithAsyncReply(Messages::RemoteAudioDestinationManager::StopAudioDestination(m_destinationID), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](bool isPlaying) mutable {150 ensureGPUProcessConnection().connection().sendWithAsyncReply(Messages::RemoteAudioDestinationManager::StopAudioDestination(destinationID()), [this, protectedThis = makeRef(*this), completionHandler = WTFMove(completionHandler)](bool isPlaying) mutable { 151 151 setIsPlaying(isPlaying); 152 152 completionHandler(!isPlaying); … … 168 168 void RemoteAudioDestinationProxy::storageChanged(SharedMemory* storage, const WebCore::CAAudioStreamDescription& format, size_t frameCount) 169 169 { 170 if (!m_gpuProcessConnection) 171 return; 172 170 173 SharedMemory::Handle handle; 171 174 if (storage) … … 179 182 #endif 180 183 181 WebProcess::singleton().ensureGPUProcessConnection().connection().send(Messages::RemoteAudioDestinationManager::AudioSamplesStorageChanged { m_destinationID, SharedMemory::IPCHandle { WTFMove(handle), dataSize }, format, frameCount }, 0);184 m_gpuProcessConnection->connection().send(Messages::RemoteAudioDestinationManager::AudioSamplesStorageChanged { destinationID(), SharedMemory::IPCHandle { WTFMove(handle), dataSize }, format, frameCount }, 0); 182 185 } 183 186 #endif … … 188 191 189 192 stopRenderingThread(); 190 191 connectToGPUProcess();193 m_gpuProcessConnection = nullptr; 194 m_destinationID = { }; 192 195 193 196 if (isPlaying()) -
trunk/Source/WebKit/WebProcess/GPU/media/RemoteAudioDestinationProxy.h
r272382 r276189 80 80 void renderQuantum(); 81 81 82 void connectToGPUProcess(); 82 RemoteAudioDestinationIdentifier destinationID(); 83 GPUProcessConnection& ensureGPUProcessConnection(); 83 84 84 85 // GPUProcessConnection::Client. … … 96 97 #endif 97 98 98 RemoteAudioDestinationIdentifier m_destinationID; 99 RemoteAudioDestinationIdentifier m_destinationID; // Call destinationID() getter to make sure the destinationID is valid. 99 100 101 WeakPtr<GPUProcessConnection> m_gpuProcessConnection; 100 102 #if PLATFORM(COCOA) 101 103 uint64_t m_numberOfFrames { 0 }; -
trunk/Tools/ChangeLog
r276184 r276189 1 2021-04-16 Chris Dumez <cdumez@apple.com> 2 3 RemoteAudioDestinationProxy should not launch / relaunch the GPUProcess unless it is actually rendering 4 https://bugs.webkit.org/show_bug.cgi?id=224691 5 6 Reviewed by Geoffrey Garen. 7 8 Add API test coverage. 9 10 * TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm: 11 (TEST): 12 * TestWebKitAPI/Tests/WebKitCocoa/audio-context-playing.html: 13 1 14 2021-04-16 Jiewen Tan <jiewen_tan@apple.com> 2 15 -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm
r276148 r276189 580 580 }); 581 581 } 582 583 TEST(GPUProcess, ExitsUnderMemoryPressureWebAudioNonRenderingAudioContext) 584 { 585 auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]); 586 WKPreferencesSetBoolValueForKeyForTesting((__bridge WKPreferencesRef)[configuration preferences], true, WKStringCreateWithUTF8CString("UseGPUProcessForMediaEnabled")); 587 WKPreferencesSetBoolValueForKeyForTesting((__bridge WKPreferencesRef)[configuration preferences], true, WKStringCreateWithUTF8CString("CaptureVideoInGPUProcessEnabled")); 588 WKPreferencesSetBoolValueForKeyForTesting((__bridge WKPreferencesRef)[configuration preferences], true, WKStringCreateWithUTF8CString("UseGPUProcessForCanvasRenderingEnabled")); 589 WKPreferencesSetBoolValueForKeyForTesting((__bridge WKPreferencesRef)[configuration preferences], false, WKStringCreateWithUTF8CString("UseGPUProcessForDOMRenderingEnabled")); 590 591 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 400, 400) configuration:configuration.get()]); 592 [webView synchronouslyLoadTestPageNamed:@"audio-context-playing"]; 593 594 // evaluateJavaScript gives us the user gesture we need to reliably start audio playback on all platforms. 595 __block bool done = false; 596 [webView evaluateJavaScript:@"startPlaying()" completionHandler:^(id result, NSError *error) { 597 EXPECT_TRUE(!error); 598 done = true; 599 }]; 600 TestWebKitAPI::Util::run(&done); 601 602 // A GPUProcess should get launched. 603 while (![configuration.get().processPool _gpuProcessIdentifier]) 604 TestWebKitAPI::Util::sleep(0.1); 605 auto gpuProcessPID = [configuration.get().processPool _gpuProcessIdentifier]; 606 607 // Simulate memory pressure (notifyutil -p org.WebKit.lowMemory). 608 notify_post("org.WebKit.lowMemory"); 609 610 // Make sure the GPUProcess does not exit since it is still needed. 611 TestWebKitAPI::Util::sleep(0.5); 612 EXPECT_EQ(gpuProcessPID, [configuration.get().processPool _gpuProcessIdentifier]); 613 614 // Suspend audio rendering. 615 [webView evaluateJavaScript:@"context.suspend() && true" completionHandler:^(id result, NSError *error) { 616 EXPECT_TRUE(!error); 617 done = true; 618 }]; 619 620 // The GPUProcess should exit on memory pressure. 621 do { 622 // Simulate memory pressure (notifyutil -p org.WebKit.lowMemory). 623 notify_post("org.WebKit.lowMemory"); 624 TestWebKitAPI::Util::sleep(0.1); 625 } while ([configuration.get().processPool _gpuProcessIdentifier]); 626 627 // The GPUProcess should not relaunch. 628 TestWebKitAPI::Util::sleep(0.5); 629 EXPECT_EQ(0, [configuration.get().processPool _gpuProcessIdentifier]); 630 } -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/audio-context-playing.html
r269698 r276189 5 5 function startPlaying() 6 6 { 7 letcontext = new AudioContext();7 context = new AudioContext(); 8 8 let oscillator = new OscillatorNode(context); 9 9 oscillator.connect(context.destination);
Note:
See TracChangeset
for help on using the changeset viewer.