summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@theqtcompany.com>2015-03-09 13:54:29 +0100
committerLaszlo Agocs <laszlo.agocs@theqtcompany.com>2015-03-11 19:23:17 +0000
commit85620bd788d351018e9fa0b0f567b19a773be52b (patch)
tree7307e1b5ef650d168571351c2549827eb343b1c6 /src
parent22afbc153628348bc6d4ee0655ea6a6584a13322 (diff)
windows: Introduce a built-in GPU blacklist
Use a built-in JSON file in case the QT_OPENGL_BUGLIST environment variable is not set. When QT_OPENGL_BUGLIST is set, the built-in list is ignored. To make the implementation simpler and more readable, some of the code in QWindowsOpenGLTester is reshuffled a bit. It also caches the results now, so it is safe and fast to call supportedRenderers() and friends multiple times. The blacklist currently contains the Intel card from QTBUG-43263 (Intel GMA / HD3000 ?) and may also apply to QTBUG-42240. [ChangeLog][QtGui] Qt now contains a built-in GPU driver blacklist for Windows that disables the usage of desktop OpenGL with some older cards that are known to be unstable with opengl32.dll. Task-number: QTBUG-42240 Task-number: QTBUG-43263 Change-Id: I1ecd65b51fca77925317d52048e7ab01d9b8797c Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r--src/gui/opengl/qopengl_p.h18
-rw-r--r--src/plugins/platforms/windows/openglblacklists.qrc5
-rw-r--r--src/plugins/platforms/windows/openglblacklists/default.json18
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp8
-rw-r--r--src/plugins/platforms/windows/qwindowsopengltester.cpp72
-rw-r--r--src/plugins/platforms/windows/qwindowsopengltester.h3
-rw-r--r--src/plugins/platforms/windows/windows.pri2
7 files changed, 91 insertions, 35 deletions
diff --git a/src/gui/opengl/qopengl_p.h b/src/gui/opengl/qopengl_p.h
index 377440455a..e04ae05120 100644
--- a/src/gui/opengl/qopengl_p.h
+++ b/src/gui/opengl/qopengl_p.h
@@ -77,6 +77,9 @@ public:
struct Gpu {
Gpu() : vendorId(0), deviceId(0) {}
bool isValid() const { return deviceId; }
+ bool equals(const Gpu &other) const {
+ return vendorId == other.vendorId && deviceId == other.deviceId && driverVersion == other.driverVersion;
+ }
uint vendorId;
uint deviceId;
@@ -93,6 +96,21 @@ public:
static QSet<QString> gpuFeatures(const Gpu &gpu, const QString &fileName);
};
+inline bool operator==(const QOpenGLConfig::Gpu &a, const QOpenGLConfig::Gpu &b)
+{
+ return a.equals(b);
+}
+
+inline bool operator!=(const QOpenGLConfig::Gpu &a, const QOpenGLConfig::Gpu &b)
+{
+ return !a.equals(b);
+}
+
+inline uint qHash(const QOpenGLConfig::Gpu &gpu)
+{
+ return qHash(gpu.vendorId) + qHash(gpu.deviceId) + qHash(gpu.driverVersion);
+}
+
QT_END_NAMESPACE
#endif // QOPENGL_H
diff --git a/src/plugins/platforms/windows/openglblacklists.qrc b/src/plugins/platforms/windows/openglblacklists.qrc
new file mode 100644
index 0000000000..9f0c186c21
--- /dev/null
+++ b/src/plugins/platforms/windows/openglblacklists.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/qt-project.org/windows/openglblacklists">
+ <file alias="default.json">openglblacklists/default.json</file>
+ </qresource>
+</RCC>
diff --git a/src/plugins/platforms/windows/openglblacklists/default.json b/src/plugins/platforms/windows/openglblacklists/default.json
new file mode 100644
index 0000000000..0217b79ecf
--- /dev/null
+++ b/src/plugins/platforms/windows/openglblacklists/default.json
@@ -0,0 +1,18 @@
+{
+ "name": "Qt built-in GPU driver blacklist",
+ "version": "5.5",
+ "entries": [
+ {
+ "id": 1,
+ "description": "Desktop OpenGL is unreliable on Intel HD3000/GMA (QTBUG-43263, QTBUG-42240)",
+ "vendor_id": "0x8086",
+ "device_id": [ "0x0A16" ],
+ "os": {
+ "type": "win"
+ },
+ "features": [
+ "disable_desktopgl"
+ ]
+ }
+ ]
+}
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index 9fd18a1ef4..1041ecf44d 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -79,9 +79,7 @@
# include "qwindowsglcontext.h"
#endif
-#ifndef Q_OS_WINCE
-# include "qwindowsopengltester.h"
-#endif
+#include "qwindowsopengltester.h"
QT_BEGIN_NAMESPACE
@@ -209,6 +207,10 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList &paramL
: m_options(0)
, m_fontDatabase(0)
{
+#ifndef Q_OS_WINCE
+ Q_INIT_RESOURCE(openglblacklists);
+#endif
+
static bool dpiAwarenessSet = false;
int tabletAbsoluteRange = -1;
// Default to per-monitor awareness to avoid being scaled when monitors with different DPI
diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp
index ba4c95544e..67548a0836 100644
--- a/src/plugins/platforms/windows/qwindowsopengltester.cpp
+++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp
@@ -42,14 +42,16 @@
#include <QtCore/QFileInfo>
#include <QtCore/QStandardPaths>
#include <QtCore/QLibraryInfo>
+#include <QtCore/QHash>
+#ifndef QT_NO_OPENGL
#include <private/qopengl_p.h>
+#endif
#ifndef Q_OS_WINCE
# include <QtCore/qt_windows.h>
# include <private/qsystemlibrary_p.h>
# include <d3d9.h>
-# include <GL/gl.h>
#endif
QT_BEGIN_NAMESPACE
@@ -206,56 +208,62 @@ static inline QString resolveBugListFile(const QString &fileName)
return QStandardPaths::locate(QStandardPaths::ConfigLocation, fileName);
}
-static void readDriverBugList(const GpuDescription &gpu,
- QWindowsOpenGLTester::Renderers *result)
+typedef QHash<QOpenGLConfig::Gpu, QWindowsOpenGLTester::Renderers> SupportedRenderersCache;
+Q_GLOBAL_STATIC(SupportedRenderersCache, supportedRenderersCache)
+
+#endif // !Q_OS_WINCE
+
+QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::detectSupportedRenderers(const GpuDescription &gpu, bool glesOnly)
{
- const char bugListFileVar[] = "QT_OPENGL_BUGLIST";
- if (!qEnvironmentVariableIsSet(bugListFileVar))
- return;
- const QString fileName = resolveBugListFile(QFile::decodeName(qgetenv(bugListFileVar)));
- if (fileName.isEmpty())
- return;
+ Q_UNUSED(gpu)
+#ifndef Q_OS_WINCE
QOpenGLConfig::Gpu qgpu;
qgpu.deviceId = gpu.deviceId;
qgpu.vendorId = gpu.vendorId;
qgpu.driverVersion = gpu.driverVersion;
- const QSet<QString> features = QOpenGLConfig::gpuFeatures(qgpu, fileName);
+ SupportedRenderersCache *srCache = supportedRenderersCache();
+ SupportedRenderersCache::const_iterator it = srCache->find(qgpu);
+ if (it != srCache->cend())
+ return *it;
+
+ QWindowsOpenGLTester::Renderers result(QWindowsOpenGLTester::AngleRendererD3d11
+ | QWindowsOpenGLTester::AngleRendererD3d9
+ | QWindowsOpenGLTester::AngleRendererD3d11Warp
+ | QWindowsOpenGLTester::SoftwareRasterizer);
+
+ if (!glesOnly && testDesktopGL())
+ result |= QWindowsOpenGLTester::DesktopGl;
+
+ QSet<QString> features;
+ const char bugListFileVar[] = "QT_OPENGL_BUGLIST";
+ if (qEnvironmentVariableIsSet(bugListFileVar)) {
+ const QString fileName = resolveBugListFile(QFile::decodeName(qgetenv(bugListFileVar)));
+ if (!fileName.isEmpty())
+ features = QOpenGLConfig::gpuFeatures(qgpu, fileName);
+ } else {
+ features = QOpenGLConfig::gpuFeatures(qgpu, QStringLiteral(":/qt-project.org/windows/openglblacklists/default.json"));
+ }
+ qCDebug(lcQpaGl) << "GPU features:" << features;
+
if (features.contains(QStringLiteral("disable_desktopgl"))) { // Qt-specific
qCWarning(lcQpaGl) << "Disabling Desktop GL: " << gpu;
- *result &= ~QWindowsOpenGLTester::DesktopGl;
+ result &= ~QWindowsOpenGLTester::DesktopGl;
}
if (features.contains(QStringLiteral("disable_angle"))) { // Qt-specific keyword
qCWarning(lcQpaGl) << "Disabling ANGLE: " << gpu;
- *result &= ~QWindowsOpenGLTester::GlesMask;
+ result &= ~QWindowsOpenGLTester::GlesMask;
} else {
if (features.contains(QStringLiteral("disable_d3d11"))) { // standard keyword
qCWarning(lcQpaGl) << "Disabling D3D11: " << gpu;
- *result &= ~QWindowsOpenGLTester::AngleRendererD3d11;
+ result &= ~QWindowsOpenGLTester::AngleRendererD3d11;
}
if (features.contains(QStringLiteral("disable_d3d9"))) { // Qt-specific
qCWarning(lcQpaGl) << "Disabling D3D9: " << gpu;
- *result &= ~QWindowsOpenGLTester::AngleRendererD3d9;
+ result &= ~QWindowsOpenGLTester::AngleRendererD3d9;
}
}
-}
-#endif // !Q_OS_WINCE
-
-static inline QWindowsOpenGLTester::Renderers
- detectSupportedRenderers(const GpuDescription &gpu, bool glesOnly)
-{
- Q_UNUSED(gpu)
-#ifndef Q_OS_WINCE
- // Add checks for card types with known issues here.
- QWindowsOpenGLTester::Renderers result(QWindowsOpenGLTester::AngleRendererD3d11
- | QWindowsOpenGLTester::AngleRendererD3d9
- | QWindowsOpenGLTester::AngleRendererD3d11Warp
- | QWindowsOpenGLTester::SoftwareRasterizer);
-
- if (!glesOnly && QWindowsOpenGLTester::testDesktopGL())
- result |= QWindowsOpenGLTester::DesktopGl;
-
- readDriverBugList(gpu, &result);
+ srCache->insert(qgpu, result);
return result;
#else // !Q_OS_WINCE
return QWindowsOpenGLTester::Gles;
diff --git a/src/plugins/platforms/windows/qwindowsopengltester.h b/src/plugins/platforms/windows/qwindowsopengltester.h
index 7b6164946e..748885542d 100644
--- a/src/plugins/platforms/windows/qwindowsopengltester.h
+++ b/src/plugins/platforms/windows/qwindowsopengltester.h
@@ -80,9 +80,12 @@ public:
static Renderer requestedGlesRenderer();
static Renderer requestedRenderer();
+
static Renderers supportedGlesRenderers();
static Renderers supportedRenderers();
+private:
+ static QWindowsOpenGLTester::Renderers detectSupportedRenderers(const GpuDescription &gpu, bool glesOnly);
static bool testDesktopGL();
};
diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri
index 246598677f..77393033c7 100644
--- a/src/plugins/platforms/windows/windows.pri
+++ b/src/plugins/platforms/windows/windows.pri
@@ -118,6 +118,8 @@ contains(QT_CONFIG,dynamicgl) {
RESOURCES += $$PWD/cursors.qrc
}
+!wince*: RESOURCES += $$PWD/openglblacklists.qrc
+
contains(QT_CONFIG, freetype) {
DEFINES *= QT_NO_FONTCONFIG
QT_FREETYPE_DIR = $$QT_SOURCE_TREE/src/3rdparty/freetype