From c7d46325e635d1fb4482b53dce866e2c55026a7e Mon Sep 17 00:00:00 2001
From: Alexandru Croitor <alexandru.croitor@qt.io>
Date: Tue, 22 Aug 2017 19:08:15 +0200
Subject: [PATCH] Allow WebGL to work with a software OpenGL implementation on
 Windows

A user can explicitly request software OpenGL rendering via
opengl32sw.dll instead of Skia rendering, by passing the
--enable-webgl-software-rendering command line argument.

This will make sure not to disable GPU processing if and only if
software OpenGL rendering is used on Windows (via
QT_OPENGL=software environment variable, or the
Qt::AA_UseSoftwareOpenGL attribute), so that WebGL is not disabled.

Software OpenGL rendering will still use Skia on platforms other than
Windows.

Change-Id: I8b3601b144e09e3a732abfb74dbbf6f924889b5a
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
---
 src/3rdparty                    |  2 +-
 src/core/gl_surface_qt.cpp      |  6 +++++
 src/core/web_engine_context.cpp | 48 ++++++++++++++++++++++-----------
 src/core/web_engine_context.h   |  2 ++
 4 files changed, 41 insertions(+), 17 deletions(-)

diff --git a/src/3rdparty b/src/3rdparty
index 5ebd47322..b8c39b181 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit 5ebd47322d60f40129fa9dacad04bee643a1b7d5
+Subproject commit b8c39b181f30d6068a958d39c2034932216778b9
diff --git a/src/core/gl_surface_qt.cpp b/src/core/gl_surface_qt.cpp
index 766c14738..930fc23a3 100644
--- a/src/core/gl_surface_qt.cpp
+++ b/src/core/gl_surface_qt.cpp
@@ -48,6 +48,7 @@
 #include <QGuiApplication>
 #include "gl_context_qt.h"
 #include "qtwebenginecoreglobal_p.h"
+#include "web_engine_context.h"
 
 #include "base/logging.h"
 #include "gpu/ipc/service/image_transport_surface.h"
@@ -618,6 +619,11 @@ bool InitializeGLOneOffPlatform()
     return false;
 }
 
+bool usingSoftwareDynamicGL()
+{
+    return QtWebEngineCore::usingSoftwareDynamicGL();
+}
+
 scoped_refptr<GLSurface>
 CreateOffscreenGLSurface(const gfx::Size& size)
 {
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 98d90cb8f..900b82eb9 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -133,21 +133,6 @@ bool usingANGLE()
 #endif
 }
 
-bool usingSoftwareDynamicGL()
-{
-    if (QCoreApplication::testAttribute(Qt::AA_UseSoftwareOpenGL))
-        return true;
-#if defined(Q_OS_WIN)
-    HMODULE handle = static_cast<HMODULE>(QOpenGLContext::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");
-#else
-    return false;
-#endif
-}
-
 bool usingQtQuick2DRenderer()
 {
     const QStringList args = QGuiApplication::arguments();
@@ -184,6 +169,21 @@ void dummyGetPluginCallback(const std::vector<content::WebPluginInfo>&)
 
 namespace QtWebEngineCore {
 
+bool usingSoftwareDynamicGL()
+{
+    if (QCoreApplication::testAttribute(Qt::AA_UseSoftwareOpenGL))
+        return true;
+#if defined(Q_OS_WIN)
+    HMODULE handle = static_cast<HMODULE>(QOpenGLContext::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");
+#else
+    return false;
+#endif
+}
+
 void WebEngineContext::destroyBrowserContext()
 {
     m_defaultBrowserContext.reset();
@@ -284,6 +284,9 @@ WebEngineContext::WebEngineContext()
         appArgs.append(QString::fromLocal8Bit(qgetenv(kChromiumFlagsEnv)).split(' '));
     }
 
+    bool enableWebGLSoftwareRendering =
+            appArgs.removeAll(QStringLiteral("--enable-webgl-software-rendering"));
+
     bool useEmbeddedSwitches = false;
 #if defined(QTWEBENGINE_EMBEDDED_SWITCHES)
     useEmbeddedSwitches = !appArgs.removeAll(QStringLiteral("--disable-embedded-switches"));
@@ -363,7 +366,20 @@ WebEngineContext::WebEngineContext()
 
     const char *glType = 0;
 #ifndef QT_NO_OPENGL
-    if (!usingANGLE() && !usingSoftwareDynamicGL() && !usingQtQuick2DRenderer()) {
+
+    bool tryGL =
+            !usingANGLE()
+            && (!usingSoftwareDynamicGL()
+#ifdef Q_OS_WIN
+                // If user requested WebGL support on Windows, instead of using Skia rendering to
+                // bitmaps, use software rendering via opengl32sw.dll. This might be less
+                // performant, but at least provides WebGL support.
+                || enableWebGLSoftwareRendering
+#endif
+                )
+            && !usingQtQuick2DRenderer();
+
+    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.
diff --git a/src/core/web_engine_context.h b/src/core/web_engine_context.h
index 386f43035..92c45e260 100644
--- a/src/core/web_engine_context.h
+++ b/src/core/web_engine_context.h
@@ -74,6 +74,8 @@ class ContentMainDelegateQt;
 class DevToolsServerQt;
 class SurfaceFactoryQt;
 
+bool usingSoftwareDynamicGL();
+
 class WebEngineContext : public base::RefCounted<WebEngineContext> {
 public:
     static scoped_refptr<WebEngineContext> current();
-- 
GitLab