diff options
author | Jüri Valdmann <juri.valdmann@qt.io> | 2020-01-16 11:51:23 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-01-30 13:40:04 +0100 |
commit | 7f1649b438329ec4f698389bbc44ee8d694e4801 (patch) | |
tree | 6dffd749ee94f8d488ad2eccda2d58c9fc8040c4 /src | |
parent | 97b047203345474cc9733f801cc5a447040bcea5 (diff) |
Cleanup FrameSinkManagerImpl before shutting down GPU service
We changed RootCompositorFrameSinks to be destroyed asynchronously (in
HostFrameSinkManager::InvalidateFrameSinkId) which means that one can still
exist during shutdown in GpuThreadControllerQt::destroyGpuProcess. This results
in a deadlock in single threaded GPU mode: in destroyGpuProcess we wait for the
viz thread to exit, but the FrameSinkManagerImpl on the viz thread will try to
destroy the RootCompositorFrameSink, which waits for work to be done on the
GPU=UI thread, which is waiting for the viz thread to exit.
Fix by destroying all RootCompositorFrameSinks before destroyGpuProcess.
Change-Id: I4cf135f29b90ae0bf78525d5747567dc10a775e6
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/web_engine_context.cpp | 14 | ||||
-rw-r--r-- | src/core/web_engine_context.h | 3 | ||||
-rw-r--r-- | src/core/web_engine_context_threads.cpp | 20 |
3 files changed, 28 insertions, 9 deletions
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp index 69769bdf1..c34d3c612 100644 --- a/src/core/web_engine_context.cpp +++ b/src/core/web_engine_context.cpp @@ -260,7 +260,7 @@ void WebEngineContext::destroy() // Normally the GPU thread is shut down when the GpuProcessHost is destroyed // on IO thread (triggered by ~BrowserMainRunner). But by that time the UI // task runner is not working anymore so we need to do this earlier. - destroyGpuProcess(); + destroyGpuProcess(m_threadedGpu); base::MessagePump::Delegate *delegate = static_cast<base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl *>( @@ -412,7 +412,8 @@ static void appendToFeatureSwitch(base::CommandLine *commandLine, const char *fe } WebEngineContext::WebEngineContext() - : m_mainDelegate(new ContentMainDelegateQt) + : m_threadedGpu(true) + , m_mainDelegate(new ContentMainDelegateQt) , m_globalQObject(new QObject()) { #if defined(Q_OS_MACOS) @@ -515,13 +516,12 @@ WebEngineContext::WebEngineContext() parsedCommandLine->AppendSwitch(switches::kDisableES3GLContext); #endif - bool threadedGpu = true; #ifndef QT_NO_OPENGL - threadedGpu = QOpenGLContext::supportsThreadedOpenGL(); + m_threadedGpu = QOpenGLContext::supportsThreadedOpenGL(); #endif - threadedGpu = threadedGpu && !qEnvironmentVariableIsSet(kDisableInProcGpuThread); + m_threadedGpu = m_threadedGpu && !qEnvironmentVariableIsSet(kDisableInProcGpuThread); - bool enableViz = ((threadedGpu && !parsedCommandLine->HasSwitch("disable-viz-display-compositor")) + bool enableViz = ((m_threadedGpu && !parsedCommandLine->HasSwitch("disable-viz-display-compositor")) || parsedCommandLine->HasSwitch("enable-viz-display-compositor")); parsedCommandLine->RemoveSwitch("disable-viz-display-compositor"); parsedCommandLine->RemoveSwitch("enable-viz-display-compositor"); @@ -660,7 +660,7 @@ WebEngineContext::WebEngineContext() parsedCommandLine->AppendSwitch(switches::kDisableGpu); } - registerMainThreadFactories(threadedGpu); + registerMainThreadFactories(m_threadedGpu); SetContentClient(new ContentClientQt); diff --git a/src/core/web_engine_context.h b/src/core/web_engine_context.h index ac0536596..edced9b42 100644 --- a/src/core/web_engine_context.h +++ b/src/core/web_engine_context.h @@ -129,8 +129,9 @@ private: ~WebEngineContext(); static void registerMainThreadFactories(bool threaded); - static void destroyGpuProcess(); + static void destroyGpuProcess(bool threaded); + bool m_threadedGpu; std::unique_ptr<base::RunLoop> m_runLoop; std::unique_ptr<ContentMainDelegateQt> m_mainDelegate; std::unique_ptr<content::ContentMainRunner> m_contentRunner; diff --git a/src/core/web_engine_context_threads.cpp b/src/core/web_engine_context_threads.cpp index e92cf3e9b..f0f055676 100644 --- a/src/core/web_engine_context_threads.cpp +++ b/src/core/web_engine_context_threads.cpp @@ -57,6 +57,8 @@ #include <memory> +#include <QEventLoop> + namespace QtWebEngineCore { struct GpuThreadControllerQt : content::GpuThreadController @@ -90,6 +92,20 @@ struct GpuThreadControllerQt : content::GpuThreadController s_gpuProcess->set_main_thread(childThread); } + static void cleanupVizProcess() + { + auto gpuChildThread = content::GpuChildThread::instance(); + if (!gpuChildThread) + return; + auto vizMain = gpuChildThread->viz_main(); + auto vizCompositorThreadRunner = vizMain->viz_compositor_thread_runner(); + if (!vizCompositorThreadRunner) + return; + QEventLoop loop; + vizCompositorThreadRunner->CleanupForShutdown(base::BindOnce(&QEventLoop::quit, base::Unretained(&loop))); + loop.exec(); + } + static void destroyGpuProcess() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); @@ -117,8 +133,10 @@ static std::unique_ptr<content::GpuThreadController> createGpuThreadController( } // static -void WebEngineContext::destroyGpuProcess() +void WebEngineContext::destroyGpuProcess(bool threaded) { + if (!threaded) + GpuThreadControllerQt::cleanupVizProcess(); GpuThreadControllerQt::destroyGpuProcess(); } |