Changeset 276148 in webkit
- Timestamp:
- Apr 16, 2021, 11:41:22 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 42 edited
-
Source/WebKit/ChangeLog (modified) (1 diff)
-
Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp (modified) (8 diffs)
-
Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h (modified) (5 diffs)
-
Source/WebKit/GPUProcess/GPUProcess.cpp (modified) (2 diffs)
-
Source/WebKit/GPUProcess/GPUProcess.h (modified) (2 diffs)
-
Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp (modified) (1 diff)
-
Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.h (modified) (1 diff)
-
Source/WebKit/GPUProcess/media/RemoteAudioDestinationManager.cpp (modified) (3 diffs)
-
Source/WebKit/GPUProcess/media/RemoteAudioDestinationManager.h (modified) (1 diff)
-
Source/WebKit/GPUProcess/media/RemoteCDMFactoryProxy.cpp (modified) (3 diffs)
-
Source/WebKit/GPUProcess/media/RemoteCDMFactoryProxy.h (modified) (1 diff)
-
Source/WebKit/GPUProcess/media/RemoteImageDecoderAVFProxy.cpp (modified) (3 diffs)
-
Source/WebKit/GPUProcess/media/RemoteImageDecoderAVFProxy.h (modified) (1 diff)
-
Source/WebKit/GPUProcess/media/RemoteLegacyCDMFactoryProxy.cpp (modified) (3 diffs)
-
Source/WebKit/GPUProcess/media/RemoteLegacyCDMFactoryProxy.h (modified) (1 diff)
-
Source/WebKit/GPUProcess/media/RemoteMediaPlayerManagerProxy.cpp (modified) (3 diffs)
-
Source/WebKit/GPUProcess/media/RemoteMediaPlayerManagerProxy.h (modified) (1 diff)
-
Source/WebKit/GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererManager.cpp (modified) (1 diff)
-
Source/WebKit/GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererManager.h (modified) (1 diff)
-
Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorderManager.cpp (modified) (1 diff)
-
Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorderManager.h (modified) (1 diff)
-
Source/WebKit/GPUProcess/webrtc/RemoteSampleBufferDisplayLayerManager.cpp (modified) (1 diff)
-
Source/WebKit/GPUProcess/webrtc/RemoteSampleBufferDisplayLayerManager.h (modified) (1 diff)
-
Source/WebKit/Shared/ProcessTerminationReason.h (modified) (1 diff)
-
Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp (modified) (1 diff)
-
Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.h (modified) (1 diff)
-
Source/WebKit/UIProcess/GPU/GPUProcessProxy.cpp (modified) (2 diffs)
-
Source/WebKit/UIProcess/GPU/GPUProcessProxy.h (modified) (3 diffs)
-
Source/WebKit/UIProcess/GPU/GPUProcessProxy.messages.in (modified) (1 diff)
-
Source/WebKit/UIProcess/PageClient.h (modified) (1 diff)
-
Source/WebKit/UIProcess/WebPageProxy.cpp (modified) (2 diffs)
-
Source/WebKit/UIProcess/WebPageProxy.h (modified) (1 diff)
-
Source/WebKit/UIProcess/WebProcessPool.cpp (modified) (1 diff)
-
Source/WebKit/UIProcess/WebProcessPool.h (modified) (1 diff)
-
Source/WebKit/UIProcess/WebProcessProxy.cpp (modified) (1 diff)
-
Source/WebKit/UIProcess/WebProcessProxy.h (modified) (1 diff)
-
Source/WebKit/UIProcess/ios/PageClientImplIOS.h (modified) (1 diff)
-
Source/WebKit/UIProcess/ios/PageClientImplIOS.mm (modified) (1 diff)
-
Source/WebKit/UIProcess/ios/WKContentView.h (modified) (1 diff)
-
Source/WebKit/UIProcess/ios/WKContentView.mm (modified) (1 diff)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/ChangeLog
r276145 r276148 1 2021-04-16 Chris Dumez <cdumez@apple.com> 2 3 Exit the GPUProcess when under memory pressure if it is not being used 4 https://bugs.webkit.org/show_bug.cgi?id=224556 5 6 Reviewed by Darin Adler. 7 8 Exit the GPUProcess when under memory pressure if it is not being used. This will 9 help us save memory, especially until we are able to enable "DOM Rendering in 10 GPUProcess". 11 12 Note that when the GPUProcess is ready to exit, it sends an IPC to the UIProcess 13 in order to get terminated, instead of terminating itself. The reason I do this is 14 so that the UIProcess can distinguish a GPUProcess crash from a normal idle exit. 15 16 A/B testing shows: 17 - 5-8% PLUM3 progression on iPhone 18 - 2.5-4% PLUM3 progression on iPad 19 - No PLT5 regression on either iPhone or iPad. 20 21 * GPUProcess/GPUConnectionToWebProcess.cpp: 22 (WebKit::GPUConnectionToWebProcess::GPUConnectionToWebProcess): 23 (WebKit::GPUConnectionToWebProcess::allowsExitUnderMemoryPressure const): 24 (WebKit::GPUConnectionToWebProcess::releaseRenderingBackend): 25 (WebKit::GPUConnectionToWebProcess::releaseGraphicsContextGL): 26 * GPUProcess/GPUConnectionToWebProcess.h: 27 (WebKit::GPUConnectionToWebProcess::remoteMediaPlayerManagerProxy): 28 * GPUProcess/GPUProcess.cpp: 29 (WebKit::GPUProcess::removeGPUConnectionToWebProcess): 30 (WebKit::GPUProcess::canExitUnderMemoryPressure const): 31 (WebKit::GPUProcess::tryExitIfUnusedAndUnderMemoryPressure): 32 (WebKit::GPUProcess::tryExitIfUnused): 33 (WebKit::GPUProcess::lowMemoryHandler): 34 * GPUProcess/GPUProcess.h: 35 * GPUProcess/graphics/RemoteRenderingBackend.cpp: 36 (WebKit::RemoteRenderingBackend::allowsExitUnderMemoryPressure const): 37 * GPUProcess/graphics/RemoteRenderingBackend.h: 38 * GPUProcess/media/RemoteAudioDestinationManager.cpp: 39 (WebKit::RemoteAudioDestinationManager::deleteAudioDestination): 40 (WebKit::RemoteAudioDestinationManager::allowsExitUnderMemoryPressure const): 41 * GPUProcess/media/RemoteAudioDestinationManager.h: 42 * GPUProcess/media/RemoteCDMFactoryProxy.cpp: 43 (WebKit::RemoteCDMFactoryProxy::removeInstance): 44 (WebKit::RemoteCDMFactoryProxy::allowsExitUnderMemoryPressure const): 45 * GPUProcess/media/RemoteCDMFactoryProxy.h: 46 * GPUProcess/media/RemoteImageDecoderAVFProxy.cpp: 47 (WebKit::RemoteImageDecoderAVFProxy::deleteDecoder): 48 (WebKit::RemoteImageDecoderAVFProxy::allowsExitUnderMemoryPressure const): 49 * GPUProcess/media/RemoteImageDecoderAVFProxy.h: 50 * GPUProcess/media/RemoteLegacyCDMFactoryProxy.cpp: 51 (WebKit::RemoteLegacyCDMFactoryProxy::removeSession): 52 (WebKit::RemoteLegacyCDMFactoryProxy::allowsExitUnderMemoryPressure const): 53 * GPUProcess/media/RemoteLegacyCDMFactoryProxy.h: 54 * GPUProcess/media/RemoteMediaPlayerManagerProxy.cpp: 55 (WebKit::RemoteMediaPlayerManagerProxy::deleteMediaPlayer): 56 (WebKit::RemoteMediaPlayerManagerProxy::allowsExitUnderMemoryPressure const): 57 * GPUProcess/media/RemoteMediaPlayerManagerProxy.h: 58 * GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererManager.cpp: 59 (WebKit::RemoteAudioMediaStreamTrackRendererManager::allowsExitUnderMemoryPressure const): 60 * GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererManager.h: 61 * GPUProcess/webrtc/RemoteMediaRecorderManager.cpp: 62 (WebKit::RemoteMediaRecorderManager::releaseRecorder): 63 (WebKit::RemoteMediaRecorderManager::allowsExitUnderMemoryPressure const): 64 * GPUProcess/webrtc/RemoteMediaRecorderManager.h: 65 * GPUProcess/webrtc/RemoteSampleBufferDisplayLayerManager.cpp: 66 (WebKit::RemoteSampleBufferDisplayLayerManager::allowsExitUnderMemoryPressure const): 67 * GPUProcess/webrtc/RemoteSampleBufferDisplayLayerManager.h: 68 * Shared/ProcessTerminationReason.h: 69 * UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp: 70 (WebKit::UserMediaCaptureManagerProxy::hasSourceProxies const): 71 * UIProcess/Cocoa/UserMediaCaptureManagerProxy.h: 72 * UIProcess/GPU/GPUProcessProxy.cpp: 73 (WebKit::GPUProcessProxy::gpuProcessExited): 74 (WebKit::GPUProcessProxy::processIsReadyToExit): 75 (WebKit::GPUProcessProxy::didClose): 76 (WebKit::GPUProcessProxy::didFinishLaunching): 77 * UIProcess/GPU/GPUProcessProxy.h: 78 * UIProcess/GPU/GPUProcessProxy.messages.in: 79 * UIProcess/PageClient.h: 80 (WebKit::PageClient::gpuProcessDidExit): 81 * UIProcess/WebPageProxy.cpp: 82 (WebKit::WebPageProxy::gpuProcessExited): 83 * UIProcess/WebPageProxy.h: 84 * UIProcess/WebProcessPool.cpp: 85 (WebKit::WebProcessPool::gpuProcessExited): 86 * UIProcess/WebProcessPool.h: 87 * UIProcess/WebProcessProxy.cpp: 88 (WebKit::WebProcessProxy::gpuProcessExited): 89 * UIProcess/WebProcessProxy.h: 90 * UIProcess/ios/PageClientImplIOS.h: 91 * UIProcess/ios/PageClientImplIOS.mm: 92 (WebKit::PageClientImpl::gpuProcessDidExit): 93 * UIProcess/ios/WKContentView.h: 94 * UIProcess/ios/WKContentView.mm: 95 (-[WKContentView _gpuProcessDidExit]): 96 1 97 2021-04-16 Chris Dumez <cdumez@apple.com> 2 98 -
trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.cpp
r276145 r276148 190 190 , m_webProcessIdentityToken(WTFMove(parameters.webProcessIdentityToken)) 191 191 #endif 192 , m_remoteMediaPlayerManagerProxy(makeUnique <RemoteMediaPlayerManagerProxy>(*this))192 , m_remoteMediaPlayerManagerProxy(makeUniqueRef<RemoteMediaPlayerManagerProxy>(*this)) 193 193 , m_sessionID(sessionID) 194 194 #if PLATFORM(COCOA) && USE(LIBWEBRTC) … … 268 268 #endif 269 269 270 bool GPUConnectionToWebProcess::allowsExitUnderMemoryPressure() const 271 { 272 for (auto& remoteRenderingBackend : m_remoteRenderingBackendMap.values()) { 273 if (!remoteRenderingBackend->allowsExitUnderMemoryPressure()) 274 return false; 275 } 276 #if ENABLE(WEBGL) 277 if (!m_remoteGraphicsContextGLMap.isEmpty()) 278 return false; 279 #endif 280 if (!m_remoteMediaPlayerManagerProxy->allowsExitUnderMemoryPressure()) 281 return false; 282 #if ENABLE(WEB_AUDIO) 283 if (m_remoteAudioDestinationManager && !m_remoteAudioDestinationManager->allowsExitUnderMemoryPressure()) 284 return false; 285 #endif 286 #if PLATFORM(COCOA) && ENABLE(MEDIA_STREAM) 287 if (m_userMediaCaptureManagerProxy && m_userMediaCaptureManagerProxy->hasSourceProxies()) 288 return false; 289 if (!m_audioTrackRendererManager->allowsExitUnderMemoryPressure()) 290 return false; 291 if (!m_sampleBufferDisplayLayerManager->allowsExitUnderMemoryPressure()) 292 return false; 293 #endif 294 #if PLATFORM(COCOA) && ENABLE(MEDIA_STREAM) && HAVE(AVASSETWRITERDELEGATE) 295 if (m_remoteMediaRecorderManager && !m_remoteMediaRecorderManager->allowsExitUnderMemoryPressure()) 296 return false; 297 #endif 298 #if HAVE(AVASSETREADER) 299 if (m_imageDecoderAVFProxy && !m_imageDecoderAVFProxy->allowsExitUnderMemoryPressure()) 300 return false; 301 #endif 302 #if ENABLE(ENCRYPTED_MEDIA) 303 if (m_cdmFactoryProxy && !m_cdmFactoryProxy->allowsExitUnderMemoryPressure()) 304 return false; 305 #endif 306 #if ENABLE(LEGACY_ENCRYPTED_MEDIA) 307 if (m_legacyCdmFactoryProxy && !m_legacyCdmFactoryProxy->allowsExitUnderMemoryPressure()) 308 return false; 309 #endif 310 return true; 311 } 312 270 313 Logger& GPUConnectionToWebProcess::logger() 271 314 { … … 320 363 return *m_userMediaCaptureManagerProxy; 321 364 } 322 323 #if HAVE(AVASSETWRITERDELEGATE) 365 #endif 366 367 #if PLATFORM(COCOA) && ENABLE(MEDIA_STREAM) && HAVE(AVASSETWRITERDELEGATE) 324 368 RemoteMediaRecorderManager& GPUConnectionToWebProcess::mediaRecorderManager() 325 369 { … … 330 374 } 331 375 #endif 332 #endif // PLATFORM(COCOA) && ENABLE(MEDIA_STREAM)333 376 334 377 #if ENABLE(ENCRYPTED_MEDIA) … … 375 418 bool found = m_remoteRenderingBackendMap.remove(renderingBackendIdentifier); 376 419 ASSERT_UNUSED(found, found); 420 gpuProcess().tryExitIfUnusedAndUnderMemoryPressure(); 377 421 } 378 422 … … 394 438 { 395 439 m_remoteGraphicsContextGLMap.remove(graphicsContextGLIdentifier); 440 if (m_remoteGraphicsContextGLMap.isEmpty()) 441 gpuProcess().tryExitIfUnusedAndUnderMemoryPressure(); 396 442 } 397 443 … … 538 584 return true; 539 585 } 540 #if HAVE(AVASSETWRITERDELEGATE) 586 #endif 587 #if PLATFORM(COCOA) && ENABLE(MEDIA_STREAM) && HAVE(AVASSETWRITERDELEGATE) 541 588 if (decoder.messageReceiverName() == Messages::RemoteMediaRecorderManager::messageReceiverName()) { 542 589 mediaRecorderManager().didReceiveMessageFromWebProcess(connection, decoder); … … 547 594 return true; 548 595 } 549 #endif // HAVE(AVASSETWRITERDELEGATE) 550 #endif // PLATFORM(COCOA) && ENABLE(MEDIA_STREAM) 596 #endif 551 597 #if ENABLE(ENCRYPTED_MEDIA) 552 598 if (decoder.messageReceiverName() == Messages::RemoteCDMFactoryProxy::messageReceiverName()) { -
trunk/Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h
r276145 r276148 133 133 134 134 RemoteMediaEngineConfigurationFactoryProxy& mediaEngineConfigurationFactoryProxy(); 135 RemoteMediaPlayerManagerProxy& remoteMediaPlayerManagerProxy() { return *m_remoteMediaPlayerManagerProxy; }135 RemoteMediaPlayerManagerProxy& remoteMediaPlayerManagerProxy() { return m_remoteMediaPlayerManagerProxy.get(); } 136 136 137 137 #if USE(AUDIO_SESSION) … … 145 145 void updateSupportedRemoteCommands(); 146 146 147 bool allowsExitUnderMemoryPressure() const; 148 147 149 void terminateWebProcess(); 148 150 #if ENABLE(WEBGL) … … 157 159 #if PLATFORM(COCOA) && ENABLE(MEDIA_STREAM) 158 160 UserMediaCaptureManagerProxy& userMediaCaptureManagerProxy(); 159 #if HAVE(AVASSETWRITERDELEGATE) 161 #endif 162 #if PLATFORM(COCOA) && ENABLE(MEDIA_STREAM) && HAVE(AVASSETWRITERDELEGATE) 160 163 RemoteMediaRecorderManager& mediaRecorderManager(); 161 #endif162 164 #endif 163 165 … … 229 231 #endif 230 232 std::unique_ptr<RemoteMediaResourceManager> m_remoteMediaResourceManager; 231 std::unique_ptr<RemoteMediaPlayerManagerProxy> m_remoteMediaPlayerManagerProxy;233 UniqueRef<RemoteMediaPlayerManagerProxy> m_remoteMediaPlayerManagerProxy; 232 234 PAL::SessionID m_sessionID; 233 235 #if PLATFORM(COCOA) && USE(LIBWEBRTC) … … 238 240 Ref<RemoteAudioMediaStreamTrackRendererManager> m_audioTrackRendererManager; 239 241 Ref<RemoteSampleBufferDisplayLayerManager> m_sampleBufferDisplayLayerManager; 240 #if HAVE(AVASSETWRITERDELEGATE) 242 #endif 243 #if PLATFORM(COCOA) && ENABLE(MEDIA_STREAM) && HAVE(AVASSETWRITERDELEGATE) 241 244 std::unique_ptr<RemoteMediaRecorderManager> m_remoteMediaRecorderManager; 242 #endif243 245 #endif 244 246 #if ENABLE(MEDIA_STREAM) -
trunk/Source/WebKit/GPUProcess/GPUProcess.cpp
r275768 r276148 112 112 ASSERT(m_webProcessConnections.contains(connection.webProcessIdentifier())); 113 113 m_webProcessConnections.remove(connection.webProcessIdentifier()); 114 tryExitIfUnusedAndUnderMemoryPressure(); 114 115 } 115 116 … … 123 124 } 124 125 126 bool GPUProcess::canExitUnderMemoryPressure() const 127 { 128 ASSERT(isMainRunLoop()); 129 for (auto& webProcessConnection : m_webProcessConnections.values()) { 130 if (!webProcessConnection->allowsExitUnderMemoryPressure()) 131 return false; 132 } 133 return true; 134 } 135 136 void GPUProcess::tryExitIfUnusedAndUnderMemoryPressure() 137 { 138 ASSERT(isMainRunLoop()); 139 if (!MemoryPressureHandler::singleton().isUnderMemoryPressure()) 140 return; 141 142 tryExitIfUnused(); 143 } 144 145 void GPUProcess::tryExitIfUnused() 146 { 147 ASSERT(isMainRunLoop()); 148 if (!canExitUnderMemoryPressure()) 149 return; 150 151 RELEASE_LOG(Process, "GPUProcess::tryExitIfUnused: GPUProcess is exiting because we are under memory pressure and the process is no longer useful."); 152 parentProcessConnection()->send(Messages::GPUProcessProxy::ProcessIsReadyToExit(), 0); 153 } 154 125 155 void GPUProcess::lowMemoryHandler(Critical critical, Synchronous synchronous) 126 156 { 157 RELEASE_LOG(Process, "GPUProcess::lowMemoryHandler: critical=%d, synchronous=%d", critical == Critical::Yes, synchronous == Synchronous::Yes); 158 tryExitIfUnused(); 159 127 160 WebCore::releaseGraphicsMemory(critical, synchronous); 128 161 } -
trunk/Source/WebKit/GPUProcess/GPUProcess.h
r275768 r276148 93 93 #endif 94 94 95 void tryExitIfUnusedAndUnderMemoryPressure(); 96 95 97 private: 96 98 void lowMemoryHandler(Critical, Synchronous); … … 101 103 void initializeSandbox(const AuxiliaryProcessInitializationParameters&, SandboxInitializationParameters&) override; 102 104 bool shouldTerminate() override; 105 106 void tryExitIfUnused(); 107 bool canExitUnderMemoryPressure() const; 103 108 104 109 // IPC::Connection::Client -
trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.cpp
r275921 r276148 598 598 } 599 599 600 bool RemoteRenderingBackend::allowsExitUnderMemoryPressure() const 601 { 602 return m_remoteResourceCache.imageBuffers().isEmpty() && m_remoteResourceCache.nativeImages().isEmpty(); 603 } 604 600 605 } // namespace WebKit 601 606 -
trunk/Source/WebKit/GPUProcess/graphics/RemoteRenderingBackend.h
r275921 r276148 84 84 void populateGetImageDataSharedMemory(WebCore::ImageData*); 85 85 86 bool allowsExitUnderMemoryPressure() const; 87 86 88 // Runs Function in RemoteRenderingBackend task queue. 87 89 void dispatch(Function<void()>&&); -
trunk/Source/WebKit/GPUProcess/media/RemoteAudioDestinationManager.cpp
r274174 r276148 30 30 31 31 #include "GPUConnectionToWebProcess.h" 32 #include "GPUProcess.h" 32 33 #include <WebCore/AudioUtilities.h> 33 34 #include <wtf/ThreadSafeRefCounted.h> … … 174 175 destination->scheduleGracefulShutdownIfNeeded(); 175 176 completionHandler(); 177 178 if (allowsExitUnderMemoryPressure()) 179 m_gpuConnectionToWebProcess.gpuProcess().tryExitIfUnusedAndUnderMemoryPressure(); 176 180 } 177 181 … … 204 208 #endif 205 209 210 bool RemoteAudioDestinationManager::allowsExitUnderMemoryPressure() const 211 { 212 return m_audioDestinations.isEmpty(); 213 } 214 206 215 } // namespace WebKit 207 216 -
trunk/Source/WebKit/GPUProcess/media/RemoteAudioDestinationManager.h
r274189 r276148 57 57 void didReceiveMessageFromWebProcess(IPC::Connection& connection, IPC::Decoder& decoder) { didReceiveMessage(connection, decoder); } 58 58 59 bool allowsExitUnderMemoryPressure() const; 60 59 61 private: 60 62 void didReceiveMessage(IPC::Connection&, IPC::Decoder&); -
trunk/Source/WebKit/GPUProcess/media/RemoteCDMFactoryProxy.cpp
r274189 r276148 29 29 #if ENABLE(GPU_PROCESS) && ENABLE(ENCRYPTED_MEDIA) 30 30 31 #include "GPUProcess.h" 31 32 #include "RemoteCDMConfiguration.h" 32 33 #include "RemoteCDMInstanceProxy.h" … … 143 144 ASSERT(m_instances.contains(identifier)); 144 145 m_instances.remove(identifier); 146 if (m_gpuConnectionToWebProcess && allowsExitUnderMemoryPressure()) 147 m_gpuConnectionToWebProcess->gpuProcess().tryExitIfUnusedAndUnderMemoryPressure(); 145 148 } 146 149 … … 162 165 } 163 166 167 bool RemoteCDMFactoryProxy::allowsExitUnderMemoryPressure() const 168 { 169 return m_instances.isEmpty(); 170 } 171 164 172 } 165 173 -
trunk/Source/WebKit/GPUProcess/media/RemoteCDMFactoryProxy.h
r274189 r276148 71 71 GPUConnectionToWebProcess* gpuConnectionToWebProcess() { return m_gpuConnectionToWebProcess.get(); } 72 72 73 bool allowsExitUnderMemoryPressure() const; 74 73 75 private: 74 76 friend class GPUProcessConnection; -
trunk/Source/WebKit/GPUProcess/media/RemoteImageDecoderAVFProxy.cpp
r275235 r276148 30 30 31 31 #include "GPUConnectionToWebProcess.h" 32 #include "GPUProcess.h" 32 33 #include "RemoteImageDecoderAVFManagerMessages.h" 33 34 #include "RemoteImageDecoderAVFProxyMessages.h" … … 71 72 72 73 m_imageDecoders.take(identifier); 74 if (m_connectionToWebProcess && allowsExitUnderMemoryPressure()) 75 m_connectionToWebProcess->gpuProcess().tryExitIfUnusedAndUnderMemoryPressure(); 73 76 } 74 77 … … 142 145 } 143 146 147 bool RemoteImageDecoderAVFProxy::allowsExitUnderMemoryPressure() const 148 { 149 return m_imageDecoders.isEmpty(); 150 } 151 144 152 } 145 153 -
trunk/Source/WebKit/GPUProcess/media/RemoteImageDecoderAVFProxy.h
r275235 r276148 51 51 bool didReceiveSyncMessage(IPC::Connection&, IPC::Decoder&, UniqueRef<IPC::Encoder>&) final; 52 52 53 bool allowsExitUnderMemoryPressure() const; 54 53 55 private: 54 56 void createDecoder(const IPC::DataReference&, const String& mimeType, CompletionHandler<void(Optional<WebCore::ImageDecoderIdentifier>&&)>&&); -
trunk/Source/WebKit/GPUProcess/media/RemoteLegacyCDMFactoryProxy.cpp
r274189 r276148 30 30 31 31 #include "GPUConnectionToWebProcess.h" 32 #include "GPUProcess.h" 32 33 #include "RemoteLegacyCDMProxy.h" 33 34 #include "RemoteLegacyCDMProxyMessages.h" … … 152 153 ASSERT(m_sessions.contains(identifier)); 153 154 m_sessions.remove(identifier); 155 156 if (m_gpuConnectionToWebProcess && allowsExitUnderMemoryPressure()) 157 m_gpuConnectionToWebProcess->gpuProcess().tryExitIfUnusedAndUnderMemoryPressure(); 154 158 } 155 159 … … 162 166 } 163 167 168 bool RemoteLegacyCDMFactoryProxy::allowsExitUnderMemoryPressure() const 169 { 170 return m_sessions.isEmpty(); 171 } 172 164 173 } 165 174 -
trunk/Source/WebKit/GPUProcess/media/RemoteLegacyCDMFactoryProxy.h
r274189 r276148 65 65 GPUConnectionToWebProcess* gpuConnectionToWebProcess() { return m_gpuConnectionToWebProcess.get(); } 66 66 67 bool allowsExitUnderMemoryPressure() const; 68 67 69 private: 68 70 friend class GPUProcessConnection; -
trunk/Source/WebKit/GPUProcess/media/RemoteMediaPlayerManagerProxy.cpp
r274264 r276148 30 30 31 31 #include "GPUConnectionToWebProcess.h" 32 #include "GPUProcess.h" 32 33 #include "Logging.h" 33 34 #include "RemoteMediaPlayerConfiguration.h" … … 73 74 { 74 75 ASSERT(RunLoop::isMain()); 75 auto locker = holdLock(m_proxiesLock); 76 if (auto proxy = m_proxies.take(identifier)) 77 proxy->invalidate(); 76 { 77 auto locker = holdLock(m_proxiesLock); 78 if (auto proxy = m_proxies.take(identifier)) 79 proxy->invalidate(); 80 } 81 if (m_gpuConnectionToWebProcess && allowsExitUnderMemoryPressure()) 82 m_gpuConnectionToWebProcess->gpuProcess().tryExitIfUnusedAndUnderMemoryPressure(); 78 83 } 79 84 … … 180 185 } 181 186 187 bool RemoteMediaPlayerManagerProxy::allowsExitUnderMemoryPressure() const 188 { 189 return m_proxies.isEmpty(); 190 } 191 182 192 #if !RELEASE_LOG_DISABLED 183 193 Logger& RemoteMediaPlayerManagerProxy::logger() -
trunk/Source/WebKit/GPUProcess/media/RemoteMediaPlayerManagerProxy.h
r274264 r276148 66 66 67 67 RefPtr<WebCore::MediaPlayer> mediaPlayer(const WebCore::MediaPlayerIdentifier&); 68 bool allowsExitUnderMemoryPressure() const; 68 69 69 70 private: -
trunk/Source/WebKit/GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererManager.cpp
r273074 r276148 89 89 } 90 90 91 bool RemoteAudioMediaStreamTrackRendererManager::allowsExitUnderMemoryPressure() const 92 { 93 return m_renderers.isEmpty(); 94 } 95 91 96 } 92 97 -
trunk/Source/WebKit/GPUProcess/webrtc/RemoteAudioMediaStreamTrackRendererManager.h
r273074 r276148 61 61 void close(); 62 62 63 bool allowsExitUnderMemoryPressure() const; 64 63 65 private: 64 66 explicit RemoteAudioMediaStreamTrackRendererManager(GPUConnectionToWebProcess&); -
trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorderManager.cpp
r268363 r276148 66 66 { 67 67 m_recorders.remove(identifier); 68 if (allowsExitUnderMemoryPressure()) 69 m_gpuConnectionToWebProcess.gpuProcess().tryExitIfUnusedAndUnderMemoryPressure(); 70 } 71 72 bool RemoteMediaRecorderManager::allowsExitUnderMemoryPressure() const 73 { 74 return m_recorders.isEmpty(); 68 75 } 69 76 -
trunk/Source/WebKit/GPUProcess/webrtc/RemoteMediaRecorderManager.h
r268363 r276148 59 59 void didReceiveMessageFromWebProcess(IPC::Connection& connection, IPC::Decoder& decoder) { didReceiveMessage(connection, decoder); } 60 60 61 bool allowsExitUnderMemoryPressure() const; 62 61 63 private: 62 64 // IPC::MessageReceiver -
trunk/Source/WebKit/GPUProcess/webrtc/RemoteSampleBufferDisplayLayerManager.cpp
r274194 r276148 104 104 } 105 105 106 bool RemoteSampleBufferDisplayLayerManager::allowsExitUnderMemoryPressure() const 107 { 108 return m_layers.isEmpty(); 109 } 110 106 111 } 107 112 -
trunk/Source/WebKit/GPUProcess/webrtc/RemoteSampleBufferDisplayLayerManager.h
r273074 r276148 60 60 void close(); 61 61 62 bool allowsExitUnderMemoryPressure() const; 63 62 64 private: 63 65 explicit RemoteSampleBufferDisplayLayerManager(GPUConnectionToWebProcess&); -
trunk/Source/WebKit/Shared/ProcessTerminationReason.h
r270415 r276148 38 38 }; 39 39 40 enum class GPUProcessTerminationReason { 41 Crash, 42 IdleExit 43 }; 44 40 45 } -
trunk/Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.cpp
r273892 r276148 369 369 } 370 370 371 bool UserMediaCaptureManagerProxy::hasSourceProxies() const 372 { 373 return !m_proxies.isEmpty(); 374 } 375 371 376 } 372 377 -
trunk/Source/WebKit/UIProcess/Cocoa/UserMediaCaptureManagerProxy.h
r272778 r276148 68 68 void didReceiveMessageFromGPUProcess(IPC::Connection& connection, IPC::Decoder& decoder) { didReceiveMessage(connection, decoder); } 69 69 70 bool hasSourceProxies() const; 71 70 72 private: 71 73 // IPC::MessageReceiver -
trunk/Source/WebKit/UIProcess/GPU/GPUProcessProxy.cpp
r275768 r276148 286 286 } 287 287 288 void GPUProcessProxy::gpuProcessCrashed() 289 { 288 void GPUProcessProxy::gpuProcessExited(GPUProcessTerminationReason reason) 289 { 290 auto protectedThis = makeRef(*this); 291 292 switch (reason) { 293 case GPUProcessTerminationReason::Crash: 294 RELEASE_LOG_ERROR(Process, "%p - GPUProcessProxy::gpuProcessExited: reason=crash", this); 295 break; 296 case GPUProcessTerminationReason::IdleExit: 297 RELEASE_LOG(Process, "%p - GPUProcessProxy::gpuProcessExited: reason=idle-exit", this); 298 break; 299 } 300 290 301 if (singleton() == this) 291 302 singleton() = nullptr; 292 303 293 304 for (auto& processPool : WebProcessPool::allProcessPools()) 294 processPool->gpuProcessCrashed(processIdentifier()); 305 processPool->gpuProcessExited(processIdentifier(), reason); 306 } 307 308 void GPUProcessProxy::processIsReadyToExit() 309 { 310 RELEASE_LOG(Process, "%p - GPUProcessProxy::processIsReadyToExit:", this); 311 terminate(); 312 gpuProcessExited(GPUProcessTerminationReason::IdleExit); // May cause |this| to get deleted. 295 313 } 296 314 297 315 void GPUProcessProxy::didClose(IPC::Connection&) 298 316 { 299 // This will cause us to be deleted.300 gpuProcess Crashed();317 RELEASE_LOG_ERROR(Process, "%p - GPUProcessProxy::didClose:", this); 318 gpuProcessExited(GPUProcessTerminationReason::Crash); // May cause |this| to get deleted. 301 319 } 302 320 … … 320 338 321 339 if (!IPC::Connection::identifierIsValid(connectionIdentifier)) { 322 gpuProcess Crashed();340 gpuProcessExited(GPUProcessTerminationReason::Crash); 323 341 return; 324 342 } -
trunk/Source/WebKit/UIProcess/GPU/GPUProcessProxy.h
r275805 r276148 31 31 #include "GPUProcessProxyMessagesReplies.h" 32 32 #include "ProcessLauncher.h" 33 #include "ProcessTerminationReason.h" 33 34 #include "ProcessThrottler.h" 34 35 #include "ProcessThrottlerClient.h" … … 102 103 void processWillShutDown(IPC::Connection&) override; 103 104 104 void gpuProcess Crashed();105 void gpuProcessExited(GPUProcessTerminationReason); 105 106 106 107 // ProcessThrottlerClient … … 118 119 119 120 void terminateWebProcess(WebCore::ProcessIdentifier); 121 void processIsReadyToExit(); 120 122 121 123 #if HAVE(VISIBILITY_PROPAGATION_VIEW) -
trunk/Source/WebKit/UIProcess/GPU/GPUProcessProxy.messages.in
r275768 r276148 29 29 #endif 30 30 31 ProcessIsReadyToExit() 31 32 TerminateWebProcess(WebCore::ProcessIdentifier webProcessIdentifier) 32 33 } -
trunk/Source/WebKit/UIProcess/PageClient.h
r275768 r276148 343 343 344 344 #if ENABLE(GPU_PROCESS) 345 virtual void gpuProcess Crashed() { }345 virtual void gpuProcessDidExit() { } 346 346 #endif 347 347 -
trunk/Source/WebKit/UIProcess/WebPageProxy.cpp
r276120 r276148 10398 10398 10399 10399 #if ENABLE(GPU_PROCESS) 10400 void WebPageProxy::gpuProcess Crashed()10400 void WebPageProxy::gpuProcessExited(GPUProcessTerminationReason) 10401 10401 { 10402 10402 #if HAVE(VISIBILITY_PROPAGATION_VIEW) … … 10404 10404 #endif 10405 10405 10406 pageClient().gpuProcess Crashed();10406 pageClient().gpuProcessDidExit(); 10407 10407 10408 10408 #if ENABLE(MEDIA_STREAM) -
trunk/Source/WebKit/UIProcess/WebPageProxy.h
r276120 r276148 1238 1238 1239 1239 #if ENABLE(GPU_PROCESS) 1240 void gpuProcess Crashed();1240 void gpuProcessExited(GPUProcessTerminationReason); 1241 1241 #endif 1242 1242 -
trunk/Source/WebKit/UIProcess/WebProcessPool.cpp
r275916 r276148 505 505 } 506 506 507 void WebProcessPool::gpuProcess Crashed(ProcessID identifier)508 { 509 WEBPROCESSPOOL_RELEASE_LOG _ERROR(Process, "gpuProcessCrashed: PID=%d", identifier);507 void WebProcessPool::gpuProcessExited(ProcessID identifier, GPUProcessTerminationReason reason) 508 { 509 WEBPROCESSPOOL_RELEASE_LOG(Process, "gpuProcessDidExit: PID=%d, reason=%u", identifier, static_cast<unsigned>(reason)); 510 510 m_gpuProcess = nullptr; 511 511 512 m_client.gpuProcessDidCrash(this, identifier); 512 if (reason == GPUProcessTerminationReason::Crash) 513 m_client.gpuProcessDidCrash(this, identifier); 514 513 515 Vector<Ref<WebProcessProxy>> processes = m_processes; 514 516 for (auto& process : processes) 515 process->gpuProcessCrashed(); 516 517 if (++m_recentGPUProcessCrashCount > maximumGPUProcessRelaunchAttemptsBeforeKillingWebProcesses) { 518 WEBPROCESSPOOL_RELEASE_LOG_ERROR(Process, "gpuProcessCrashed: GPU Process has crashed more than %u times in the last %g seconds, terminating all WebProcesses", maximumGPUProcessRelaunchAttemptsBeforeKillingWebProcesses, resetGPUProcessCrashCountDelay.seconds()); 519 m_resetGPUProcessCrashCountTimer.stop(); 520 m_recentGPUProcessCrashCount = 0; 521 terminateAllWebContentProcesses(); 522 } else if (!m_resetGPUProcessCrashCountTimer.isActive()) 523 m_resetGPUProcessCrashCountTimer.startOneShot(resetGPUProcessCrashCountDelay); 517 process->gpuProcessExited(reason); 518 519 if (reason == GPUProcessTerminationReason::Crash) { 520 if (++m_recentGPUProcessCrashCount > maximumGPUProcessRelaunchAttemptsBeforeKillingWebProcesses) { 521 WEBPROCESSPOOL_RELEASE_LOG_ERROR(Process, "gpuProcessDidExit: GPU Process has crashed more than %u times in the last %g seconds, terminating all WebProcesses", maximumGPUProcessRelaunchAttemptsBeforeKillingWebProcesses, resetGPUProcessCrashCountDelay.seconds()); 522 m_resetGPUProcessCrashCountTimer.stop(); 523 m_recentGPUProcessCrashCount = 0; 524 terminateAllWebContentProcesses(); 525 } else if (!m_resetGPUProcessCrashCountTimer.isActive()) 526 m_resetGPUProcessCrashCountTimer.startOneShot(resetGPUProcessCrashCountDelay); 527 } 524 528 } 525 529 -
trunk/Source/WebKit/UIProcess/WebProcessPool.h
r275916 r276148 358 358 359 359 #if ENABLE(GPU_PROCESS) 360 void gpuProcess Crashed(ProcessID);360 void gpuProcessExited(ProcessID, GPUProcessTerminationReason); 361 361 362 362 void getGPUProcessConnection(WebProcessProxy&, GPUProcessConnectionParameters&&, Messages::WebProcessProxy::GetGPUProcessConnectionDelayedReply&&); -
trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp
r275916 r276148 787 787 } 788 788 789 void WebProcessProxy::gpuProcess Crashed()789 void WebProcessProxy::gpuProcessExited(GPUProcessTerminationReason reason) 790 790 { 791 791 for (auto& page : copyToVectorOf<RefPtr<WebPageProxy>>(m_pageMap.values())) 792 page->gpuProcess Crashed();792 page->gpuProcessExited(reason); 793 793 } 794 794 #endif -
trunk/Source/WebKit/UIProcess/WebProcessProxy.h
r275937 r276148 377 377 378 378 #if ENABLE(GPU_PROCESS) 379 void gpuProcess Crashed();379 void gpuProcessExited(GPUProcessTerminationReason); 380 380 #endif 381 381 -
trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.h
r275768 r276148 82 82 83 83 #if ENABLE(GPU_PROCESS) 84 void gpuProcess Crashed() override;84 void gpuProcessDidExit() override; 85 85 #endif 86 86 void preferencesDidChange() override; -
trunk/Source/WebKit/UIProcess/ios/PageClientImplIOS.mm
r275768 r276148 213 213 214 214 #if ENABLE(GPU_PROCESS) 215 void PageClientImpl::gpuProcess Crashed()216 { 217 [m_contentView _gpuProcess Crashed];215 void PageClientImpl::gpuProcessDidExit() 216 { 217 [m_contentView _gpuProcessDidExit]; 218 218 } 219 219 #endif -
trunk/Source/WebKit/UIProcess/ios/WKContentView.h
r276051 r276148 99 99 - (void)_processDidExit; 100 100 #if ENABLE(GPU_PROCESS) 101 - (void)_gpuProcess Crashed;101 - (void)_gpuProcessDidExit; 102 102 #endif 103 103 - (void)_processWillSwap; -
trunk/Source/WebKit/UIProcess/ios/WKContentView.mm
r276051 r276148 657 657 658 658 #if ENABLE(GPU_PROCESS) 659 - (void)_gpuProcess Crashed659 - (void)_gpuProcessDidExit 660 660 { 661 661 #if HAVE(VISIBILITY_PROPAGATION_VIEW) -
trunk/Tools/ChangeLog
r276139 r276148 1 2021-04-16 Chris Dumez <cdumez@apple.com> 2 3 Exit the GPUProcess when under memory pressure if it is not being used 4 https://bugs.webkit.org/show_bug.cgi?id=224556 5 6 Reviewed by Darin Adler. 7 8 Add API test coverage. 9 10 * TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm: 11 (runMemoryPressureExitTest): 12 (TEST): 13 1 14 2021-04-16 Aakash Jain <aakash_jain@apple.com> 2 15 -
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/GPUProcess.mm
r275887 r276148 35 35 #import <WebKit/WKWebViewConfiguration.h> 36 36 #import <WebKit/WKWebViewPrivate.h> 37 #import <notify.h> 38 #import <wtf/Function.h> 37 39 #import <wtf/RetainPtr.h> 38 40 … … 491 493 TestWebKitAPI::Util::run(&done); 492 494 } 495 496 static void runMemoryPressureExitTest(Function<void(WKWebView *)>&& loadTestPageSynchronously) 497 { 498 auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]); 499 WKPreferencesSetBoolValueForKeyForTesting((__bridge WKPreferencesRef)[configuration preferences], true, WKStringCreateWithUTF8CString("UseGPUProcessForMediaEnabled")); 500 WKPreferencesSetBoolValueForKeyForTesting((__bridge WKPreferencesRef)[configuration preferences], true, WKStringCreateWithUTF8CString("CaptureVideoInGPUProcessEnabled")); 501 WKPreferencesSetBoolValueForKeyForTesting((__bridge WKPreferencesRef)[configuration preferences], true, WKStringCreateWithUTF8CString("UseGPUProcessForCanvasRenderingEnabled")); 502 WKPreferencesSetBoolValueForKeyForTesting((__bridge WKPreferencesRef)[configuration preferences], false, WKStringCreateWithUTF8CString("UseGPUProcessForDOMRenderingEnabled")); 503 504 auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 400, 400) configuration:configuration.get()]); 505 loadTestPageSynchronously(webView.get()); 506 507 // A GPUProcess should get launched. 508 while (![configuration.get().processPool _gpuProcessIdentifier]) 509 TestWebKitAPI::Util::sleep(0.1); 510 auto gpuProcessPID = [configuration.get().processPool _gpuProcessIdentifier]; 511 512 // Simulate memory pressure (notifyutil -p org.WebKit.lowMemory). 513 notify_post("org.WebKit.lowMemory"); 514 515 // Make sure the GPUProcess does not exit since it is still needed. 516 TestWebKitAPI::Util::sleep(0.5); 517 EXPECT_EQ(gpuProcessPID, [configuration.get().processPool _gpuProcessIdentifier]); 518 519 // Navigate to another page that no longer requires the GPUProcess. 520 [webView synchronouslyLoadTestPageNamed:@"simple"]; 521 522 // The GPUProcess should exit on memory pressure. 523 do { 524 // Simulate memory pressure (notifyutil -p org.WebKit.lowMemory). 525 notify_post("org.WebKit.lowMemory"); 526 TestWebKitAPI::Util::sleep(0.1); 527 } while ([configuration.get().processPool _gpuProcessIdentifier]); 528 529 // The GPUProcess should not relaunch. 530 TestWebKitAPI::Util::sleep(0.5); 531 EXPECT_EQ(0, [configuration.get().processPool _gpuProcessIdentifier]); 532 } 533 534 TEST(GPUProcess, ExitsUnderMemoryPressureCanvasCase) 535 { 536 runMemoryPressureExitTest([](WKWebView *webView) { 537 [webView synchronouslyLoadHTMLString:testCanvasPage]; 538 539 __block bool done = false; 540 [webView evaluateJavaScript:@"context.fillStyle = '#00FF00'; context.fillRect(0, 0, 400, 400);" completionHandler:^(id result, NSError *error) { 541 EXPECT_TRUE(!error); 542 done = true; 543 }]; 544 TestWebKitAPI::Util::run(&done); 545 done = false; 546 [webView evaluateJavaScript:@"context.getImageData(0, 0, 400, 400).width" completionHandler:^(id result, NSError *error) { 547 EXPECT_TRUE(!error); 548 done = true; 549 }]; 550 TestWebKitAPI::Util::run(&done); 551 }); 552 } 553 554 TEST(GPUProcess, ExitsUnderMemoryPressureVideoCase) 555 { 556 runMemoryPressureExitTest([](WKWebView *webView) { 557 [webView synchronouslyLoadTestPageNamed:@"large-videos-with-audio"]; 558 559 __block bool done = false; 560 [webView evaluateJavaScript:@"document.getElementsByTagName('video')[0].play() && true" completionHandler:^(id result, NSError *error) { 561 EXPECT_TRUE(!error); 562 done = true; 563 }]; 564 TestWebKitAPI::Util::run(&done); 565 }); 566 } 567 568 TEST(GPUProcess, ExitsUnderMemoryPressureWebAudioCase) 569 { 570 runMemoryPressureExitTest([](WKWebView *webView) { 571 [webView synchronouslyLoadTestPageNamed:@"audio-context-playing"]; 572 573 // evaluateJavaScript gives us the user gesture we need to reliably start audio playback on all platforms. 574 __block bool done = false; 575 [webView evaluateJavaScript:@"startPlaying()" completionHandler:^(id result, NSError *error) { 576 EXPECT_TRUE(!error); 577 done = true; 578 }]; 579 TestWebKitAPI::Util::run(&done); 580 }); 581 }
Note:
See TracChangeset
for help on using the changeset viewer.