diff options
Diffstat (limited to 'src/core/web_engine_context.cpp')
-rw-r--r-- | src/core/web_engine_context.cpp | 101 |
1 files changed, 92 insertions, 9 deletions
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp index 1361ebbed..f9d9631fd 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" @@ -214,6 +216,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. @@ -414,10 +422,23 @@ WebEngineContext::WebEngineContext() // an OpenGL Core Profile context. If the switch is not set, it would always try to create a // Core Profile context, even if Qt uses a legacy profile, which causes // "Could not share GL contexts" warnings, because it's not possible to share between Core and - // legacy profiles. - // Given that Core profile is not currently supported on Windows anyway, pass this switch to - // get rid of the warnings. - parsedCommandLine->AppendSwitch(switches::kDisableES3GLContext); + // legacy profiles. See GLContextWGL::Initialize(). + // Given that Desktop GL Core profile is not currently supported on Windows anyway, pass this + // switch to get rid of the warnings. + // + // The switch is also used to determine which version of OpenGL ES to use (2 or 3) when using + // ANGLE. + // If the switch is not set, Chromium will always try to create an ES3 context, even if Qt uses + // an ES2 context, which causes resource sharing issues (black screen), + // see gpu::gles2::GenerateGLContextAttribs(). + // Make sure to disable ES3 context creation when using ES2. + const bool isGLES2Context = qt_gl_global_share_context() + && qt_gl_global_share_context()->isOpenGLES() + && qt_gl_global_share_context()->format().majorVersion() == 2; + const bool isDesktopGLOrSoftware = !usingANGLE(); + + if (isDesktopGLOrSoftware || isGLES2Context) + parsedCommandLine->AppendSwitch(switches::kDisableES3GLContext); #endif // Needed to allow navigations within pages that were set using setHtml(). One example is // tst_QWebEnginePage::acceptNavigationRequest. @@ -450,8 +471,7 @@ WebEngineContext::WebEngineContext() #ifndef QT_NO_OPENGL bool tryGL = - !usingANGLE() - && (!usingSoftwareDynamicGL() + (!usingSoftwareDynamicGL() // If user requested WebGL support instead of using Skia rendering to // bitmaps, use software rendering via software OpenGL. This might be less // performant, but at least provides WebGL support. @@ -461,10 +481,13 @@ WebEngineContext::WebEngineContext() if (tryGL) { if (qt_gl_global_share_context() && qt_gl_global_share_context()->isValid()) { - // If the native handle is QEGLNativeContext try to use GL ES/2, if there is no native handle - // assume we are using wayland and try GL ES/2, and finally Ozone demands GL ES/2 too. + // If the native handle is QEGLNativeContext try to use GL ES/2. + // If there is no native handle, assume we are using wayland and try GL ES/2. + // If we are using ANGLE on Windows, use OpenGL ES (2 or 3). if (qt_gl_global_share_context()->nativeHandle().isNull() - || !strcmp(qt_gl_global_share_context()->nativeHandle().typeName(), "QEGLNativeContext")) + || !strcmp(qt_gl_global_share_context()->nativeHandle().typeName(), + "QEGLNativeContext") + || usingANGLE()) { if (qt_gl_global_share_context()->isOpenGLES()) { glType = gl::kGLImplementationEGLName; @@ -533,6 +556,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(); @@ -593,4 +620,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 |