diff options
author | Jüri Valdmann <juri.valdmann@qt.io> | 2018-08-20 12:31:52 +0200 |
---|---|---|
committer | Jüri Valdmann <juri.valdmann@qt.io> | 2018-10-23 11:39:25 +0000 |
commit | bc2ae1dbebea3b6c71237fc3d073cec4335037d8 (patch) | |
tree | a4eb4d51ea4d13684179804369a602a1d4728007 /src/core | |
parent | b84324ece095ad1f5a16326c49bdf1428ff5f866 (diff) |
Support running GPU service on UI thread
Create content::GpuProcess on UI thread if threaded OpenGL is not supported.
Fixes: QTBUG-71126
Change-Id: I7965dec66c8b8e9c92d292731d21ee0df5056a2e
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/web_engine_context.cpp | 68 | ||||
-rw-r--r-- | src/core/web_engine_context.h | 15 |
2 files changed, 83 insertions, 0 deletions
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp index b7cf1344b..7e91b3bdb 100644 --- a/src/core/web_engine_context.cpp +++ b/src/core/web_engine_context.cpp @@ -57,6 +57,8 @@ #include "content/browser/gpu/gpu_main_thread_factory.h" #include "content/browser/renderer_host/render_process_host_impl.h" #include "content/browser/utility_process_host.h" +#include "content/gpu/gpu_child_thread.h" +#include "content/gpu/gpu_process.h" #include "content/gpu/in_process_gpu_thread.h" #include "content/public/app/content_main.h" #include "content/public/app/content_main_runner.h" @@ -216,6 +218,12 @@ void WebEngineContext::destroy() { if (m_devtoolsServer) m_devtoolsServer->stop(); + + // 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(); + base::MessagePump::Delegate *delegate = static_cast<base::MessageLoop *>(m_runLoop->delegate_); // Flush the UI message loop before quitting. @@ -539,6 +547,10 @@ WebEngineContext::WebEngineContext() content::UtilityProcessHost::RegisterUtilityMainThreadFactory(content::CreateInProcessUtilityThread); content::RenderProcessHostImpl::RegisterRendererMainThreadFactory(content::CreateInProcessRendererThread); content::RegisterGpuMainThreadFactory(content::CreateInProcessGpuThread); +#ifndef QT_NO_OPENGL + if (!QOpenGLContext::supportsThreadedOpenGL()) + content::RegisterGpuMainThreadFactory(createGpuThreadController); +#endif mojo::core::Init(); @@ -599,4 +611,60 @@ printing::PrintJobManager* WebEngineContext::getPrintJobManager() return m_printJobManager.get(); } #endif + +// static +std::unique_ptr<content::GpuThreadController> WebEngineContext::createGpuThreadController( + const content::InProcessChildThreadParams ¶ms, const gpu::GpuPreferences &gpuPreferences) +{ + struct Controller : content::GpuThreadController + { + Controller(const content::InProcessChildThreadParams ¶ms, const gpu::GpuPreferences &gpuPreferences) + { + content::BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, + base::BindOnce(&WebEngineContext::createGpuProcess, params, gpuPreferences)); + } + ~Controller() + { + content::BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, + base::BindOnce(&WebEngineContext::destroyGpuProcess)); + } + }; + return std::make_unique<Controller>(params, gpuPreferences); +} + +// static +void WebEngineContext::createGpuProcess( + const content::InProcessChildThreadParams ¶ms, const gpu::GpuPreferences &gpuPreferences) +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + WebEngineContext *context = current(); + if (!context || context->m_gpuProcessDestroyed) + return; + + context->m_gpuProcess = std::make_unique<content::GpuProcess>(base::ThreadPriority::NORMAL); + auto gpuInit = std::make_unique<gpu::GpuInit>(); + gpuInit->InitializeInProcess(base::CommandLine::ForCurrentProcess(), gpuPreferences); + auto childThread = new content::GpuChildThread(params, std::move(gpuInit)); + childThread->Init(base::Time::Now()); + context->m_gpuProcess->set_main_thread(childThread); +} + +// static +void WebEngineContext::destroyGpuProcess() +{ + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + WebEngineContext *context = current(); + if (!context) + return; + + // viz::GpuServiceImpl::~GpuServiceImpl waits for io task. + base::ScopedAllowBaseSyncPrimitivesForTesting allow; + context->m_gpuProcess.reset(); + context->m_gpuProcessDestroyed = true; +} + } // namespace diff --git a/src/core/web_engine_context.h b/src/core/web_engine_context.h index ce71984d4..036dc4ccb 100644 --- a/src/core/web_engine_context.h +++ b/src/core/web_engine_context.h @@ -52,6 +52,13 @@ class RunLoop; namespace content { class BrowserMainRunner; class ContentMainRunner; +class GpuProcess; +class GpuThreadController; +class InProcessChildThreadParams; +} + +namespace gpu { +struct GpuPreferences; } #if QT_CONFIG(webengine_printing_and_pdf) @@ -93,6 +100,12 @@ private: WebEngineContext(); ~WebEngineContext(); + static std::unique_ptr<content::GpuThreadController> createGpuThreadController( + const content::InProcessChildThreadParams ¶ms, const gpu::GpuPreferences &gpuPreferences); + static void createGpuProcess( + const content::InProcessChildThreadParams ¶ms, const gpu::GpuPreferences &gpuPreferences); + static void destroyGpuProcess(); + std::unique_ptr<base::RunLoop> m_runLoop; std::unique_ptr<ContentMainDelegateQt> m_mainDelegate; std::unique_ptr<content::ContentMainRunner> m_contentRunner; @@ -100,6 +113,8 @@ private: std::unique_ptr<QObject> m_globalQObject; std::unique_ptr<ProfileAdapter> m_defaultProfileAdapter; std::unique_ptr<DevToolsServerQt> m_devtoolsServer; + std::unique_ptr<content::GpuProcess> m_gpuProcess; + bool m_gpuProcessDestroyed = false; QVector<ProfileAdapter*> m_profileAdapters; #if QT_CONFIG(webengine_printing_and_pdf) |