summaryrefslogtreecommitdiffstats
path: root/src/core/web_engine_context.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/web_engine_context.cpp')
-rw-r--r--src/core/web_engine_context.cpp101
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 &params, const gpu::GpuPreferences &gpuPreferences)
+{
+ struct Controller : content::GpuThreadController
+ {
+ Controller(const content::InProcessChildThreadParams &params, 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 &params, 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