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.cpp701
1 files changed, 419 insertions, 282 deletions
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 2329d27e4..94110d51c 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -1,53 +1,19 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWebEngine module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "web_engine_context.h"
#include <math.h>
+#include <QtGui/private/qrhi_p.h>
#include "base/base_switches.h"
+#include "base/functional/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/power_monitor/power_monitor.h"
#include "base/power_monitor/power_monitor_device_source.h"
#include "base/run_loop.h"
-#include "base/task/post_task.h"
+#include "base/strings/string_split.h"
#include "base/task/sequence_manager/thread_controller_with_message_pump_impl.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "base/threading/thread_restrictions.h"
@@ -56,6 +22,7 @@
#include "chrome/browser/media/webrtc/webrtc_log_uploader.h"
#endif
#include "chrome/common/chrome_switches.h"
+#include "content/common/process_visibility_tracker.h"
#include "content/gpu/gpu_child_thread.h"
#include "content/browser/compositor/surface_utils.h"
#include "content/browser/compositor/viz_process_transport_factory.h"
@@ -69,29 +36,35 @@
#include "components/web_cache/browser/web_cache_manager.h"
#include "content/app/mojo_ipc_support.h"
#include "content/browser/devtools/devtools_http_handler.h"
+#include "content/browser/gpu/gpu_main_thread_factory.h"
+#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/scheduler/browser_task_executor.h"
#include "content/browser/startup_data_impl.h"
#include "content/browser/startup_helper.h"
+#include "content/browser/utility_process_host.h"
+#include "content/gpu/in_process_gpu_thread.h"
#include "content/public/app/content_main.h"
#include "content/public/app/content_main_runner.h"
#include "content/public/browser/browser_main_runner.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
+#if QT_CONFIG(webengine_pepper_plugins)
#include "content/public/browser/plugin_service.h"
+#endif
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_paths.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
-#include "content/public/common/network_service_util.h"
+#include "content/renderer/in_process_renderer_thread.h"
+#include "content/utility/in_process_utility_thread.h"
#include "gpu/command_buffer/service/gpu_switches.h"
-#include "gpu/command_buffer/service/sync_point_manager.h"
+#include "gpu/config/gpu_finch_features.h"
#include "media/audio/audio_manager.h"
#include "media/base/media_switches.h"
#include "mojo/core/embedder/embedder.h"
#include "net/base/port_util.h"
-#include "ppapi/buildflags/buildflags.h"
#include "sandbox/policy/switches.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/network_switches.h"
@@ -102,14 +75,15 @@
#include "ui/base/ui_base_features.h"
#include "ui/events/event_switches.h"
#include "ui/native_theme/native_theme_features.h"
+#include "ui/gl/gl_utils.h"
#include "ui/gl/gl_switches.h"
-#if defined(OS_WIN)
+#if defined(Q_OS_WIN)
#include "sandbox/win/src/sandbox_types.h"
#include "content/public/app/sandbox_helper_win.h"
-#endif // OS_WIN
+#endif // Q_OS_WIN
#if defined(Q_OS_MACOS)
-#include "base/mac/foundation_util.h"
+#include "base/apple/foundation_util.h"
#endif
#if QT_CONFIG(accessibility)
@@ -136,11 +110,13 @@
#include <qopenglcontext_platform.h>
#endif
#include <QQuickWindow>
+#include <QRegularExpression>
#include <QStringList>
#include <QSurfaceFormat>
#include <QNetworkProxy>
#include <QtGui/qpa/qplatformintegration.h>
#include <QtGui/private/qguiapplication_p.h>
+#include <QtQuick/private/qsgrhisupport_p.h>
#include <QLoggingCategory>
#if QT_CONFIG(opengl)
@@ -149,23 +125,19 @@ Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context();
QT_END_NAMESPACE
#endif
+#define STRINGIFY_LITERAL(x) #x
+#define STRINGIFY_EXPANDED(x) STRINGIFY_LITERAL(x)
+
namespace QtWebEngineCore {
-#if QT_CONFIG(opengl)
-static bool usingANGLE()
-{
-#if defined(Q_OS_WIN)
- if (qt_gl_global_share_context())
- return qt_gl_global_share_context()->isOpenGLES();
- return QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES;
-#else
- return false;
-#endif
-}
+Q_LOGGING_CATEGORY(webEngineContextLog, "qt.webenginecontext")
-static bool usingDefaultSGBackend()
+static bool usingSupportedSGBackend()
{
- if (QQuickWindow::graphicsApi() != QSGRendererInterface::OpenGL)
+ if (QQuickWindow::graphicsApi() != QSGRendererInterface::OpenGL
+ && QQuickWindow::graphicsApi() != QSGRendererInterface::Vulkan
+ && QQuickWindow::graphicsApi() != QSGRendererInterface::Metal
+ && QQuickWindow::graphicsApi() != QSGRendererInterface::Direct3D11)
return false;
const QStringList args = QGuiApplication::arguments();
@@ -185,109 +157,254 @@ static bool usingDefaultSGBackend()
if (device.isEmpty())
device = qEnvironmentVariable("QMLSCENE_DEVICE");
- return device.isEmpty();
+ return device.isEmpty() || device == QLatin1String("rhi");
}
+#if QT_CONFIG(opengl)
bool usingSoftwareDynamicGL()
{
+ const char openGlVar[] = "QT_OPENGL";
if (QCoreApplication::testAttribute(Qt::AA_UseSoftwareOpenGL))
return true;
+
+ if (qEnvironmentVariableIsSet(openGlVar)) {
+ const QByteArray requested = qgetenv(openGlVar);
+ if (requested == "software")
+ return true;
+ }
#if defined(Q_OS_WIN)
HMODULE handle = QNativeInterface::QWGLContext::openGLModuleHandle();
wchar_t path[MAX_PATH];
DWORD size = GetModuleFileName(handle, path, MAX_PATH);
QFileInfo openGLModule(QString::fromWCharArray(path, size));
- return openGLModule.fileName() == QLatin1String("opengl32sw.dll");
+ return openGLModule.fileName().contains(QLatin1String("opengl32sw"),Qt::CaseInsensitive);
#else
return false;
#endif
}
-static const char *getGLType(bool enableGLSoftwareRendering)
+static bool openGLPlatformSupport()
{
- const char *glType = nullptr;
- const bool tryGL = (usingDefaultSGBackend() && !usingSoftwareDynamicGL()
- && QGuiApplicationPrivate::platformIntegration()->hasCapability(
- QPlatformIntegration::OpenGL))
- || enableGLSoftwareRendering;
- if (tryGL) {
- if (!qt_gl_global_share_context() || !qt_gl_global_share_context()->isValid()) {
- qWarning("WebEngineContext used before QtWebEngineCore::initialize() or OpenGL context "
- "creation failed.");
- } else {
- const QSurfaceFormat sharedFormat = qt_gl_global_share_context()->format();
- switch (sharedFormat.renderableType()) {
- case QSurfaceFormat::OpenGL:
- glType = gl::kGLImplementationDesktopName;
- // Check if Core profile was requested and is supported.
- if (sharedFormat.profile() == QSurfaceFormat::CoreProfile) {
-#ifdef Q_OS_MACOS
- glType = gl::kGLImplementationCoreProfileName;
+ return QGuiApplicationPrivate::platformIntegration()->hasCapability(
+ QPlatformIntegration::OpenGL);
+}
+
+static std::string getGLType(bool enableGLSoftwareRendering, bool disableGpu)
+{
+ const bool tryGL =
+ usingSupportedSGBackend() && !usingSoftwareDynamicGL() && openGLPlatformSupport();
+ if (disableGpu || (!tryGL && !enableGLSoftwareRendering))
+ return gl::kGLImplementationDisabledName;
+
+#if defined(Q_OS_MACOS)
+ return gl::kGLImplementationANGLEName;
#else
- qWarning("An OpenGL Core Profile was requested, but it is not supported "
- "on the current platform. Falling back to a non-Core profile. "
- "Note that this might cause rendering issues.");
+#if defined(Q_OS_WIN)
+ if (QQuickWindow::graphicsApi() == QSGRendererInterface::Direct3D11
+ || QQuickWindow::graphicsApi() == QSGRendererInterface::Vulkan) {
+ return gl::kGLImplementationANGLEName;
+ }
#endif
- }
- break;
- case QSurfaceFormat::OpenGLES:
- glType = usingANGLE() ? gl::kGLImplementationANGLEName
- : gl::kGLImplementationEGLName;
- break;
- case QSurfaceFormat::OpenVG:
- case QSurfaceFormat::DefaultRenderableType:
- default:
- // Shared contex created but no rederable type set.
- qWarning("Unsupported rendering surface format. Please open bug report at "
- "https://bugreports.qt.io");
- }
+
+ if (!qt_gl_global_share_context() || !qt_gl_global_share_context()->isValid()) {
+ qWarning("WebEngineContext is used before QtWebEngineQuick::initialize() or OpenGL context "
+ "creation failed.");
+ return gl::kGLImplementationDisabledName;
+ }
+
+ const QSurfaceFormat sharedFormat = qt_gl_global_share_context()->format();
+
+ switch (sharedFormat.renderableType()) {
+ case QSurfaceFormat::OpenGL:
+ if (sharedFormat.profile() == QSurfaceFormat::CoreProfile) {
+ qWarning("An OpenGL Core Profile was requested, but it is not supported "
+ "on the current platform. Falling back to a non-Core profile. "
+ "Note that this might cause rendering issues.");
}
+ return gl::kGLImplementationDesktopName;
+ case QSurfaceFormat::OpenGLES:
+ return gl::kGLImplementationEGLName;
+ case QSurfaceFormat::OpenVG:
+ case QSurfaceFormat::DefaultRenderableType:
+ default:
+ // Shared contex created but no rederable type set.
+ qWarning("Unsupported rendering surface format. Please open bug report at "
+ "https://bugreports.qt.io");
}
- return glType;
+
+ return gl::kGLImplementationDisabledName;
+#endif // defined(Q_OS_MACOS)
}
#else
-static const char *getGLType(bool enableGLSoftwareRendering)
+static std::string getGLType(bool /*enableGLSoftwareRendering*/, bool disableGpu)
{
- return nullptr;
+ if (disableGpu)
+ return gl::kGLImplementationDisabledName;
+#if defined(Q_OS_MACOS)
+ return gl::kGLImplementationANGLEName;
+#elif defined(Q_OS_WIN)
+ if (QQuickWindow::graphicsApi() == QSGRendererInterface::Direct3D11
+ || QQuickWindow::graphicsApi() == QSGRendererInterface::Vulkan) {
+ return gl::kGLImplementationANGLEName;
+ }
+#endif
+ return gl::kGLImplementationDisabledName;
}
#endif // QT_CONFIG(opengl)
+static std::string getVulkanType(base::CommandLine *cmd)
+{
+#if QT_CONFIG(webengine_vulkan)
+ if (cmd->HasSwitch(switches::kUseVulkan))
+ return cmd->GetSwitchValueASCII(switches::kUseVulkan);
+#endif
+
+ return "disabled";
+}
+
+static std::string getAngleType(const std::string &glType, base::CommandLine *cmd)
+{
+ if (glType == gl::kGLImplementationANGLEName) {
+ if (cmd->HasSwitch(switches::kUseANGLE))
+ return cmd->GetSwitchValueASCII(switches::kUseANGLE);
+
+#if defined(Q_OS_WIN)
+ return gl::kANGLEImplementationD3D11Name;
+#elif defined(Q_OS_MACOS)
+ return gl::kANGLEImplementationMetalName;
+#else
+ return gl::kANGLEImplementationDefaultName;
+#endif
+ }
+
+ return "disabled";
+}
+
+static quint64 getGPUVendorId()
+{
+#if QT_CONFIG(webengine_vulkan)
+ QVulkanInstance vulkanInstance;
+ vulkanInstance.setApiVersion(QVersionNumber(1, 1));
+ if (vulkanInstance.create()) {
+ QRhiVulkanInitParams params;
+ params.inst = &vulkanInstance;
+ QScopedPointer<QRhi> rhi(QRhi::create(QRhi::Vulkan, &params, QRhi::Flags(), nullptr));
+ return rhi->driverInfo().vendorId;
+ }
+#endif
+
+ return 0;
+}
+
+#if defined(Q_OS_WIN)
+static QString getAdapterLuid() {
+ static const bool preferSoftwareDevice = qEnvironmentVariableIntValue("QSG_RHI_PREFER_SOFTWARE_RENDERER");
+ QRhiD3D11InitParams rhiParams;
+ QRhi::Flags flags;
+ if (preferSoftwareDevice) {
+ flags |= QRhi::PreferSoftwareRenderer;
+ }
+ QScopedPointer<QRhi> rhi(QRhi::create(QRhi::D3D11,&rhiParams,flags,nullptr));
+ // mimic what QSGRhiSupport and QBackingStoreRhi does
+ if (!rhi && !preferSoftwareDevice) {
+ flags |= QRhi::PreferSoftwareRenderer;
+ rhi.reset(QRhi::create(QRhi::D3D11, &rhiParams, flags));
+ }
+ if (rhi) {
+ const QRhiD3D11NativeHandles *handles =
+ static_cast<const QRhiD3D11NativeHandles *>(rhi->nativeHandles());
+ Q_ASSERT(handles);
+ return QString("%1,%2").arg(handles->adapterLuidHigh).arg(handles->adapterLuidLow);
+ } else {
+ return QString();
+ }
+}
+#endif
+
#if QT_CONFIG(webengine_pepper_plugins)
void dummyGetPluginCallback(const std::vector<content::WebPluginInfo>&)
{
}
#endif
-static void logContext(const char *glType, base::CommandLine *cmd)
+static void logContext(const std::string &glType, base::CommandLine *cmd)
{
- QLoggingCategory webEngineContextLog("qt.webenginecontext");
- if (webEngineContextLog.isInfoEnabled()) {
+ if (Q_UNLIKELY(webEngineContextLog().isDebugEnabled())) {
+ QStringList log;
+ log << "\n";
+
+ log << "Chromium GL Backend:" << glType.c_str() << "\n";
+ log << "Chromium ANGLE Backend:" << getAngleType(glType, cmd).c_str() << "\n";
+ log << "Chromium Vulkan Backend:" << getVulkanType(cmd).c_str() << "\n";
+ log << "\n";
+
+ log << "QSG RHI Backend:" << QSGRhiSupport::instance()->rhiBackendName() << "\n";
+ log << "QSG RHI Backend Supported:" << (usingSupportedSGBackend() ? "yes" : "no") << "\n";
+ log << "GPU Vendor:";
+ if (quint64 vendorId = getGPUVendorId()) {
+ switch (vendorId) {
+ case 0x1002:
+ log << "AMD";
+ break;
+ case 0x10DE:
+ log << "NVIDIA";
+ break;
+ case 0x8086:
+ log << "Intel";
+ break;
+ case 0x1010:
+ log << "ImgTec";
+ break;
+ case 0x13B5:
+ log << "ARM";
+ break;
+ case 0x5143:
+ log << "Qualcomm";
+ break;
+ default:
+ break;
+ }
+ log << QString("(0x%1)\n").arg(vendorId, 0, 16);
+ } else {
+ log << "Unable to detect\n";
+ }
+ log << "\n";
+
#if QT_CONFIG(opengl)
- const QSurfaceFormat sharedFormat = qt_gl_global_share_context()->format();
- const auto profile = QMetaEnum::fromType<QSurfaceFormat::OpenGLContextProfile>().valueToKey(
- sharedFormat.profile());
- const auto type = QMetaEnum::fromType<QSurfaceFormat::RenderableType>().valueToKey(
- sharedFormat.renderableType());
- const base::CommandLine::SwitchMap switch_map = cmd->GetSwitches();
- QStringList params;
- for (const auto &pair : switch_map)
- params << " * " << toQt(pair.first)
- << toQt(pair.second) << "\n";
- qCInfo(webEngineContextLog,
- "\n\nGLImplementation: %s\n"
- "Surface Type: %s\n"
- "Surface Profile: %s\n"
- "Surface Version: %d.%d\n"
- "Using Default SG Backend: %s\n"
- "Using Software Dynamic GL: %s\n"
- "Using Angle: %s\n\n"
- "Init Parameters:\n %s",
- glType, type, profile, sharedFormat.majorVersion(), sharedFormat.minorVersion(),
- usingDefaultSGBackend() ? "yes" : "no", usingSoftwareDynamicGL() ? "yes" : "no",
- usingANGLE() ? "yes" : "no", qPrintable(params.join(" ")));
-#else
- qCInfo(webEngineContextLog) << "WebEngine compiled with no opengl enabled.";
-#endif //QT_CONFIG(opengl)
+#if defined(USE_OZONE)
+ log << "Using GLX:" << (GLContextHelper::getGlxPlatformInterface() ? "yes" : "no") << "\n";
+ log << "Using EGL:" << (GLContextHelper::getEglPlatformInterface() ? "yes" : "no") << "\n";
+#endif
+ log << "Using Shared GL:" << (qt_gl_global_share_context() ? "yes" : "no") << "\n";
+ if (qt_gl_global_share_context()) {
+ log << "Using Software Dynamic GL:" << (usingSoftwareDynamicGL() ? "yes" : "no")
+ << "\n";
+
+ const QSurfaceFormat sharedFormat = qt_gl_global_share_context()
+ ? qt_gl_global_share_context()->format()
+ : QSurfaceFormat::defaultFormat();
+ const auto profile =
+ QMetaEnum::fromType<QSurfaceFormat::OpenGLContextProfile>().valueToKey(
+ sharedFormat.profile());
+ const auto type = QMetaEnum::fromType<QSurfaceFormat::RenderableType>().valueToKey(
+ sharedFormat.renderableType());
+ log << "Surface Type:" << type << "\n";
+ log << "Surface Profile:" << profile << "\n";
+ log << "Surface Version:"
+ << QString("%1.%2")
+ .arg(sharedFormat.majorVersion())
+ .arg(sharedFormat.minorVersion())
+ << "\n";
+ }
+ log << "\n";
+#endif // QT_CONFIG(opengl)
+
+ log << "Init Parameters:\n";
+ const base::CommandLine::SwitchMap switchMap = cmd->GetSwitches();
+ for (const auto &pair : switchMap)
+ log << " * " << toQt(pair.first) << toQt(pair.second) << "\n";
+
+ qCDebug(webEngineContextLog) << qPrintable(log.join(" "));
}
}
@@ -314,26 +431,14 @@ static void setupProxyPac(base::CommandLine *commandLine)
}
}
-static bool waitForViz = false;
-static void completeVizCleanup()
-{
- waitForViz = false;
-}
-
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;
- waitForViz = true;
content::GetHostFrameSinkManager()->SetConnectionLostCallback(base::DoNothing());
auto factory = static_cast<content::VizProcessTransportFactory*>(content::ImageTransportFactory::GetInstance());
factory->PrepareForShutDown();
- vizCompositorThreadRunner->CleanupForShutdown(base::BindOnce(&completeVizCleanup));
}
static QStringList parseEnvCommandLine(const QString &cmdLine)
@@ -384,7 +489,7 @@ static QStringList parseEnvCommandLine(const QString &cmdLine)
scoped_refptr<QtWebEngineCore::WebEngineContext> WebEngineContext::m_handle;
bool WebEngineContext::m_destroyed = false;
-
+bool WebEngineContext::m_closingDown = false;
void WebEngineContext::destroyProfileAdapter()
{
if (content::RenderProcessHost::run_renderer_in_process()) {
@@ -446,11 +551,6 @@ void WebEngineContext::destroy()
// 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.
cleanupVizProcess();
- while (waitForViz) {
- flushMessages();
- QThread::msleep(50);
- }
- destroyGpuProcess();
// Flush the UI message loop before quitting.
flushMessages();
@@ -485,7 +585,6 @@ void WebEngineContext::destroy()
GLContextHelper::destroy();
// These would normally be in the content-runner, but we allocated them separately:
- m_startupData.reset();
m_mojoIpcSupport.reset();
m_discardableSharedMemoryManager.reset();
@@ -508,7 +607,6 @@ WebEngineContext::~WebEngineContext()
Q_ASSERT(!m_devtoolsServer);
Q_ASSERT(!m_browserRunner);
Q_ASSERT(m_profileAdapters.isEmpty());
- delete s_syncPointManager.fetchAndStoreRelaxed(nullptr);
}
WebEngineContext *WebEngineContext::current()
@@ -553,6 +651,7 @@ void WebEngineContext::destroyContextPostRoutine()
// Destroy WebEngineContext before its static pointer is zeroed and destructor called.
// Before destroying MessageLoop via destroying BrowserMainRunner destructor
// WebEngineContext's pointer is used.
+ m_closingDown = true;
m_handle->destroy();
#if !defined(NDEBUG)
if (!m_handle->HasOneRef())
@@ -581,18 +680,6 @@ ProxyAuthentication WebEngineContext::qProxyNetworkAuthentication(QString host,
const static char kChromiumFlagsEnv[] = "QTWEBENGINE_CHROMIUM_FLAGS";
const static char kDisableSandboxEnv[] = "QTWEBENGINE_DISABLE_SANDBOX";
-const static char kDisableInProcGpuThread[] = "QTWEBENGINE_DISABLE_GPU_THREAD";
-
-// static
-bool WebEngineContext::isGpuServiceOnUIThread()
-{
- static bool threadedGpu =
-#if QT_CONFIG(opengl) && !defined(Q_OS_MACOS)
- QOpenGLContext::supportsThreadedOpenGL() &&
-#endif
- !qEnvironmentVariableIsSet(kDisableInProcGpuThread);
- return !threadedGpu;
-}
static void initializeFeatureList(base::CommandLine *commandLine, std::vector<std::string> enableFeatures, std::vector<std::string> disableFeatures)
{
@@ -644,7 +731,7 @@ WebEngineContext::WebEngineContext()
#if defined(Q_OS_MACOS)
// The bundled handling is currently both completely broken in Chromium,
// and unnecessary for us.
- base::mac::SetOverrideAmIBundled(false);
+ base::apple::SetOverrideAmIBundled(false);
#endif
base::ThreadPoolInstance::Create("Browser");
@@ -670,16 +757,11 @@ WebEngineContext::WebEngineContext()
// Allow us to inject javascript like any webview toolkit.
content::RenderFrameHost::AllowInjectingJavaScript();
- QStringList appArgs = QCoreApplication::arguments();
-
bool useEmbeddedSwitches = false;
-#if defined(QTWEBENGINE_EMBEDDED_SWITCHES)
- useEmbeddedSwitches = !appArgs.contains(QStringLiteral("--disable-embedded-switches"));
-#else
- useEmbeddedSwitches = appArgs.contains(QStringLiteral("--enable-embedded-switches"));
-#endif
+ bool enableGLSoftwareRendering = false;
+ base::CommandLine *parsedCommandLine =
+ initCommandLine(useEmbeddedSwitches, enableGLSoftwareRendering);
- base::CommandLine* parsedCommandLine = commandLine();
setupProxyPac(parsedCommandLine);
parsedCommandLine->AppendSwitchPath(switches::kBrowserSubprocessPath, WebEngineLibraryInfo::getPath(content::CHILD_PROCESS_EXE));
@@ -696,39 +778,77 @@ WebEngineContext::WebEngineContext()
qInfo() << "Sandboxing disabled by user.";
}
- parsedCommandLine->AppendSwitch(switches::kEnableThreadedCompositing);
-
// Do not advertise a feature we have removed at compile time
parsedCommandLine->AppendSwitch(switches::kDisableSpeechAPI);
std::vector<std::string> disableFeatures;
std::vector<std::string> enableFeatures;
+ enableFeatures.push_back(features::kNetworkServiceInProcess.name);
enableFeatures.push_back(features::kTracingServiceInProcess.name);
- disableFeatures.push_back(network::features::kDnsOverHttpsUpgrade.name);
-
// When enabled, event.movement is calculated in blink instead of in browser.
disableFeatures.push_back(features::kConsolidatedMovementXY.name);
// Avoid crashing when websites tries using this feature (since 83)
disableFeatures.push_back(features::kInstalledApp.name);
+ // Not implemented but it overrides the devtools eyedropper
+ // Should be sync with kEyeDropper base::Feature
+ parsedCommandLine->AppendSwitchASCII(switches::kDisableBlinkFeatures, "EyeDropperAPI");
+ disableFeatures.push_back(features::kEyeDropper.name);
+
// Explicitly tell Chromium about default-on features we do not support
disableFeatures.push_back(features::kBackgroundFetch.name);
disableFeatures.push_back(features::kWebOTP.name);
disableFeatures.push_back(features::kWebPayments.name);
disableFeatures.push_back(features::kWebUsb.name);
- disableFeatures.push_back(media::kPictureInPicture.name);
if (useEmbeddedSwitches) {
// embedded switches are based on the switches for Android, see content/browser/android/content_startup_flags.cc
enableFeatures.push_back(features::kOverlayScrollbar.name);
parsedCommandLine->AppendSwitch(switches::kEnableViewport);
- parsedCommandLine->AppendSwitch(switches::kMainFrameResizesAreOrientationChanges);
parsedCommandLine->AppendSwitch(cc::switches::kDisableCompositedAntialiasing);
}
+#if QT_CONFIG(webengine_vulkan) && defined(USE_OZONE)
+ if (QQuickWindow::graphicsApi() == QSGRendererInterface::Vulkan) {
+ enableFeatures.push_back(features::kVulkan.name);
+ parsedCommandLine->AppendSwitchASCII(switches::kUseVulkan,
+ switches::kVulkanImplementationNameNative);
+ const char deviceExtensionsVar[] = "QT_VULKAN_DEVICE_EXTENSIONS";
+ QByteArrayList requiredDeviceExtensions = { "VK_KHR_external_memory_fd",
+ "VK_EXT_external_memory_dma_buf",
+ "VK_EXT_image_drm_format_modifier" };
+ if (qEnvironmentVariableIsSet(deviceExtensionsVar)) {
+ QByteArrayList envExtList = qgetenv(deviceExtensionsVar).split(';');
+ int found = 0;
+ for (const QByteArray &ext : requiredDeviceExtensions) {
+ if (envExtList.contains(ext))
+ found++;
+ }
+ if (found != requiredDeviceExtensions.size()) {
+ qWarning().nospace()
+ << "Vulkan rendering may fail because " << deviceExtensionsVar
+ << " environment variable is already set but it doesn't contain"
+ << " some of the required Vulkan device extensions:\n"
+ << qPrintable(requiredDeviceExtensions.join('\n'));
+ }
+ } else {
+ qputenv(deviceExtensionsVar, requiredDeviceExtensions.join(';'));
+ }
+ }
+#endif // QT_CONFIG(webengine_vulkan) && defined(USE_OZONE)
+
+#if defined(Q_OS_WIN)
+ if (QQuickWindow::graphicsApi() == QSGRendererInterface::Direct3D11
+ || QQuickWindow::graphicsApi() == QSGRendererInterface::Vulkan) {
+ const QString luid = getAdapterLuid();
+ if (!luid.isEmpty())
+ parsedCommandLine->AppendSwitchASCII(switches::kUseAdapterLuid, luid.toStdString());
+ }
+#endif
+
initializeFeatureList(parsedCommandLine, enableFeatures, disableFeatures);
GLContextHelper::initialize();
@@ -737,84 +857,91 @@ WebEngineContext::WebEngineContext()
// bitmaps, use software rendering via software OpenGL. This might be less
// performant, but at least provides WebGL support.
// TODO(miklocek), check if this still works with latest chromium
- const bool enableGLSoftwareRendering = appArgs.contains(QStringLiteral("--enable-webgl-software-rendering"));
- const char *glType = getGLType(enableGLSoftwareRendering);
-
- if (glType) {
-#if QT_CONFIG(opengl)
+ const bool disableGpu = parsedCommandLine->HasSwitch(switches::kDisableGpu);
+ std::string glType;
+ if (parsedCommandLine->HasSwitch(switches::kUseGL))
+ glType = parsedCommandLine->GetSwitchValueASCII(switches::kUseGL);
+ else {
+ glType = getGLType(enableGLSoftwareRendering, disableGpu);
parsedCommandLine->AppendSwitchASCII(switches::kUseGL, glType);
- parsedCommandLine->AppendSwitch(switches::kInProcessGPU);
+ }
+
+ parsedCommandLine->AppendSwitch(switches::kInProcessGPU);
+
+ if (glType != gl::kGLImplementationDisabledName) {
if (enableGLSoftwareRendering) {
parsedCommandLine->AppendSwitch(switches::kDisableGpuRasterization);
parsedCommandLine->AppendSwitch(switches::kIgnoreGpuBlocklist);
}
- const QSurfaceFormat sharedFormat = QOpenGLContext::globalShareContext()->format();
- if (sharedFormat.profile() == QSurfaceFormat::CompatibilityProfile)
- parsedCommandLine->AppendSwitch(switches::kCreateDefaultGLContext);
+#if QT_CONFIG(opengl)
+ if (glType != gl::kGLImplementationANGLEName) {
+ QOpenGLContext *shareContext = QOpenGLContext::globalShareContext();
+ Q_ASSERT(shareContext);
+ const QSurfaceFormat sharedFormat = shareContext->format();
+ if (sharedFormat.profile() == QSurfaceFormat::CompatibilityProfile)
+ parsedCommandLine->AppendSwitch(switches::kCreateDefaultGLContext);
#if defined(Q_OS_WIN)
- // This switch is used in Chromium's gl_context_wgl.cc file to determine whether to create
- // 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. 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 = QOpenGLContext::globalShareContext()->isOpenGLES()
- && QOpenGLContext::globalShareContext()->format().majorVersion() == 2;
- if (!usingANGLE() || isGLES2Context)
- parsedCommandLine->AppendSwitch(switches::kDisableES3GLContext);
+ // This switch is used in Chromium's gl_context_wgl.cc file to determine whether to create
+ // 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. See GLContextWGL::Initialize().
+ if (sharedFormat.renderableType() == QSurfaceFormat::OpenGL
+ && sharedFormat.profile() != QSurfaceFormat::CoreProfile) {
+ gl::GlWorkarounds workarounds = gl::GetGlWorkarounds();
+ workarounds.disable_es3gl_context = true;
+ gl::SetGlWorkarounds(workarounds);
+ }
#endif
+ }
#endif //QT_CONFIG(opengl)
- } else {
+ } else if (!disableGpu) {
parsedCommandLine->AppendSwitch(switches::kDisableGpu);
}
+ logContext(glType, parsedCommandLine);
+
registerMainThreadFactories();
content::ContentMainParams contentMainParams(m_mainDelegate.get());
-#if defined(OS_WIN)
+ contentMainParams.setup_signal_handlers = false;
+#if defined(Q_OS_WIN)
contentMainParams.sandbox_info = QtWebEngineSandbox::staticSandboxInterfaceInfo();
- sandbox::SandboxInterfaceInfo sandbox_info = {0};
+ sandbox::SandboxInterfaceInfo sandbox_info = {nullptr};
if (!contentMainParams.sandbox_info) {
content::InitializeSandboxInfo(&sandbox_info);
contentMainParams.sandbox_info = &sandbox_info;
}
#endif
- m_contentRunner->Initialize(contentMainParams);
+ m_contentRunner->Initialize(std::move(contentMainParams));
mojo::core::Configuration mojoConfiguration;
mojoConfiguration.is_broker_process = true;
mojo::core::Init(mojoConfiguration);
- // This block mirrors ContentMainRunnerImpl::RunServiceManager():
- m_mainDelegate->PreCreateMainMessageLoop();
+ // This block mirrors ContentMainRunnerImpl::RunBrowser():
+ m_mainDelegate->PreBrowserMain();
base::MessagePump::OverrideMessagePumpForUIFactory(messagePumpFactory);
content::BrowserTaskExecutor::Create();
- m_mainDelegate->PostEarlyInitialization(false);
+ m_mainDelegate->PostEarlyInitialization({});
content::StartBrowserThreadPool();
content::BrowserTaskExecutor::PostFeatureListSetup();
- tracing::InitTracingPostThreadPoolStartAndFeatureList();
- m_discardableSharedMemoryManager = std::make_unique<discardable_memory::DiscardableSharedMemoryManager>();
+ tracing::InitTracingPostThreadPoolStartAndFeatureList(false);
base::PowerMonitor::Initialize(std::make_unique<base::PowerMonitorDeviceSource>());
+ content::ProcessVisibilityTracker::GetInstance();
+ m_discardableSharedMemoryManager = std::make_unique<discardable_memory::DiscardableSharedMemoryManager>();
m_mojoIpcSupport = std::make_unique<content::MojoIpcSupport>(content::BrowserTaskExecutor::CreateIOThread());
download::SetIOTaskRunner(m_mojoIpcSupport->io_thread()->task_runner());
- m_startupData = m_mojoIpcSupport->CreateBrowserStartupData();
+ std::unique_ptr<content::StartupData> startupData = m_mojoIpcSupport->CreateBrowserStartupData();
// Once the MessageLoop has been created, attach a top-level RunLoop.
m_runLoop.reset(new base::RunLoop);
m_runLoop->BeforeRun();
- content::MainFunctionParams mainParams(*base::CommandLine::ForCurrentProcess());
- mainParams.startup_data = m_startupData.get();
- m_browserRunner->Initialize(mainParams);
+ content::MainFunctionParams mainParams(base::CommandLine::ForCurrentProcess());
+ mainParams.startup_data = std::move(startupData);
+ m_browserRunner->Initialize(std::move(mainParams));
m_devtoolsServer.reset(new DevToolsServerQt());
m_devtoolsServer->start();
@@ -826,14 +953,7 @@ WebEngineContext::WebEngineContext()
// Initialize WebCacheManager here to ensure its subscription to render process creation events.
web_cache::WebCacheManager::GetInstance();
- base::ThreadRestrictions::SetIOAllowed(true);
-
- if (parsedCommandLine->HasSwitch(network::switches::kExplicitlyAllowedPorts)) {
- std::string allowedPorts = parsedCommandLine->GetSwitchValueASCII(network::switches::kExplicitlyAllowedPorts);
- net::SetExplicitlyAllowedPorts(allowedPorts);
- }
-
-#if defined(OS_LINUX)
+#if defined(Q_OS_LINUX)
media::AudioManager::SetGlobalAppName(QCoreApplication::applicationName().toStdString());
#endif
@@ -844,7 +964,7 @@ WebEngineContext::WebEngineContext()
// be created from the FILE thread, and that GetPluginInfoArray is synchronous, it
// can't loads plugins synchronously from the IO thread to serve the render process' request
// and we need to make sure that it happened beforehand.
- content::PluginService::GetInstance()->GetPlugins(base::Bind(&dummyGetPluginCallback));
+ content::PluginService::GetInstance()->GetPlugins(base::BindOnce(&dummyGetPluginCallback));
#endif
#if QT_CONFIG(webengine_printing_and_pdf)
@@ -856,8 +976,6 @@ WebEngineContext::WebEngineContext()
#endif
content::WebUIControllerFactory::RegisterFactory(WebUIControllerFactoryQt::GetInstance());
-
- logContext(glType, parsedCommandLine);
}
#if QT_CONFIG(webengine_printing_and_pdf)
@@ -877,87 +995,106 @@ WebRtcLogUploader *WebEngineContext::webRtcLogUploader()
#endif
-static QMutex s_spmMutex;
-QAtomicPointer<gpu::SyncPointManager> WebEngineContext::s_syncPointManager;
-
-gpu::SyncPointManager *WebEngineContext::syncPointManager()
+base::CommandLine *WebEngineContext::initCommandLine(bool &useEmbeddedSwitches,
+ bool &enableGLSoftwareRendering)
{
- if (gpu::SyncPointManager *spm = s_syncPointManager.loadAcquire())
- return spm;
- QMutexLocker lock(&s_spmMutex);
- if (!s_syncPointManager)
- s_syncPointManager.storeRelaxed(new gpu::SyncPointManager());
- return s_syncPointManager.loadRelaxed();
-}
+ if (!base::CommandLine::CreateEmpty())
+ qFatal("base::CommandLine has been initialized unexpectedly.");
-base::CommandLine* WebEngineContext::commandLine() {
- if (base::CommandLine::CreateEmpty()) {
- base::CommandLine* parsedCommandLine = base::CommandLine::ForCurrentProcess();
- QStringList appArgs = QCoreApplication::arguments();
- if (qEnvironmentVariableIsSet(kChromiumFlagsEnv)) {
- appArgs = appArgs.mid(0, 1); // Take application name and drop the rest
- appArgs.append(parseEnvCommandLine(qEnvironmentVariable(kChromiumFlagsEnv)));
+ QStringList appArgs = QCoreApplication::arguments();
+ if (appArgs.empty()) {
+ qFatal("Argument list is empty, the program name is not passed to QCoreApplication. "
+ "base::CommandLine cannot be properly initialized.");
+ }
+
+ base::CommandLine *parsedCommandLine = base::CommandLine::ForCurrentProcess();
+ int index = appArgs.indexOf(QRegularExpression(QLatin1String("--webEngineArgs"),
+ QRegularExpression::CaseInsensitiveOption));
+ if (qEnvironmentVariableIsSet(kChromiumFlagsEnv)) {
+ appArgs = appArgs.mid(0, 1); // Take application name and drop the rest
+ appArgs.append(parseEnvCommandLine(qEnvironmentVariable(kChromiumFlagsEnv)));
+ if (index > -1)
+ qWarning("Note 'webEngineArgs' are overridden by QTWEBENGINE_CHROMIUM_FLAGS");
+ } else {
+ if (index > -1) {
+ appArgs.erase(appArgs.begin() + 1, appArgs.begin() + index + 1);
+ } else {
+ appArgs = appArgs.mid(0, 1);
}
-#ifdef Q_OS_WIN
- appArgs.removeAll(QStringLiteral("--enable-webgl-software-rendering"));
+ }
+#if defined(QTWEBENGINE_EMBEDDED_SWITCHES)
+ useEmbeddedSwitches = !appArgs.contains(QStringLiteral("--disable-embedded-switches"));
+#else
+ useEmbeddedSwitches = appArgs.contains(QStringLiteral("--enable-embedded-switches"));
#endif
- appArgs.removeAll(QStringLiteral("--disable-embedded-switches"));
- appArgs.removeAll(QStringLiteral("--enable-embedded-switches"));
+ enableGLSoftwareRendering =
+ appArgs.removeAll(QStringLiteral("--enable-webgl-software-rendering"));
+ appArgs.removeAll(QStringLiteral("--disable-embedded-switches"));
+ appArgs.removeAll(QStringLiteral("--enable-embedded-switches"));
+
+ bool isRemoteDebugPort =
+ (-1
+ != appArgs.indexOf(QRegularExpression(QStringLiteral("--remote-debugging-port=.*"),
+ QRegularExpression::CaseInsensitiveOption)))
+ || !qEnvironmentVariable("QTWEBENGINE_REMOTE_DEBUGGING").isEmpty();
+ bool isRemoteAllowOrigins =
+ (-1
+ != appArgs.indexOf(QRegularExpression(QStringLiteral("--remote-allow-origins=.*"),
+ QRegularExpression::CaseInsensitiveOption)));
+
+ if (isRemoteDebugPort && !isRemoteAllowOrigins) {
+ appArgs.append(QStringLiteral("--remote-allow-origins=*"));
+ qWarning("Added {--remote-allow-origins=*} to command-line arguments "
+ "to avoid web socket connection errors during remote debugging.");
+ }
- base::CommandLine::StringVector argv;
- argv.resize(appArgs.size());
+ base::CommandLine::StringVector argv;
+ argv.resize(appArgs.size());
#if defined(Q_OS_WIN)
- for (int i = 0; i < appArgs.size(); ++i)
- argv[i] = toString16(appArgs[i]);
+ for (int i = 0; i < appArgs.size(); ++i)
+ argv[i] = appArgs[i].toStdWString();
#else
- for (int i = 0; i < appArgs.size(); ++i)
- argv[i] = appArgs[i].toStdString();
+ for (int i = 0; i < appArgs.size(); ++i)
+ argv[i] = appArgs[i].toStdString();
#endif
- parsedCommandLine->InitFromArgv(argv);
- return parsedCommandLine;
- } else {
- return base::CommandLine::ForCurrentProcess();
- }
+ parsedCommandLine->InitFromArgv(argv);
+
+ return parsedCommandLine;
+}
+
+bool WebEngineContext::closingDown()
+{
+ return m_closingDown;
+}
+
+void WebEngineContext::registerMainThreadFactories()
+{
+ content::UtilityProcessHost::RegisterUtilityMainThreadFactory(content::CreateInProcessUtilityThread);
+ content::RenderProcessHostImpl::RegisterRendererMainThreadFactory(content::CreateInProcessRendererThread);
+ content::RegisterGpuMainThreadFactory(content::CreateInProcessGpuThread);
}
} // namespace
QT_BEGIN_NAMESPACE
-/*!
- \relates <qtwebenginecoreglobal.h>
- \since 6.2
-
- Returns the version number of Qt WebEngine at run-time as a string
- (for example, "6.2.0"). This may be a different version than the
- version the application was compiled against, and a different version
- than Qt.
-*/
const char *qWebEngineVersion() noexcept
{
- return QTWEBENGINECORE_VERSION_STR;
+ return STRINGIFY_EXPANDED(QTWEBENGINECORE_VERSION_STR);
}
-/*!
- \relates <qtwebenginecoreglobal.h>
- \since 6.2
+const char *qWebEngineProcessName() noexcept
+{
+ return STRINGIFY_EXPANDED(QTWEBENGINEPROCESS_NAME);
+}
- Returns the version number of Chromium used by Qt WebEngine at run-time
- as a string (for example, "83.0.4103.122").
-*/
const char *qWebEngineChromiumVersion() noexcept
{
- return CHROMIUM_VERSION;
+ return STRINGIFY_EXPANDED(CHROMIUM_VERSION);
}
-/*!
- \relates <qtwebenginecoreglobal.h>
- \since 6.3
-
- Returns the version number of last Chromium version security patches have been
- merged from.
-*/
const char *qWebEngineChromiumSecurityPatchVersion() noexcept
{
- return "92.0.4515.166"; // FIXME: Remember to update
+ return "122.0.6261.128"; // FIXME: Remember to update
}
+
QT_END_NAMESPACE