summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/platforms/windows/qwindowseglcontext.cpp19
-rw-r--r--src/plugins/platforms/windows/qwindowseglcontext.h3
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp76
-rw-r--r--src/plugins/platforms/windows/qwindowsopenglcontext.h3
-rw-r--r--src/plugins/platforms/windows/qwindowsopengltester.cpp82
-rw-r--r--src/plugins/platforms/windows/qwindowsopengltester.h21
6 files changed, 162 insertions, 42 deletions
diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp
index c0d0c1f77c..bde0503ee0 100644
--- a/src/plugins/platforms/windows/qwindowseglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp
@@ -340,7 +340,7 @@ QWindowsEGLStaticContext::QWindowsEGLStaticContext(EGLDisplay display, int versi
{
}
-QWindowsEGLStaticContext *QWindowsEGLStaticContext::create()
+QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester::Renderers preferredType)
{
const HDC dc = QWindowsContext::instance()->displayContext();
if (!dc){
@@ -359,27 +359,26 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create()
EGLDisplay display = EGL_NO_DISPLAY;
#ifdef EGL_ANGLE_platform_angle_opengl
- if (libEGL.eglGetPlatformDisplayEXT && qEnvironmentVariableIsSet("QT_ANGLE_PLATFORM")) {
+ if (libEGL.eglGetPlatformDisplayEXT
+ && (preferredType & QWindowsOpenGLTester::AngleBackendMask)) {
const EGLint anglePlatformAttributes[][5] = {
{ EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_NONE },
{ EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, EGL_NONE },
{ EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_USE_WARP_ANGLE, EGL_TRUE, EGL_NONE }
};
const EGLint *attributes = 0;
- const QByteArray anglePlatform = qgetenv("QT_ANGLE_PLATFORM");
- if (anglePlatform == "d3d11")
+ if (preferredType & QWindowsOpenGLTester::AngleRendererD3d11)
attributes = anglePlatformAttributes[0];
- else if (anglePlatform == "d3d9")
+ else if (preferredType & QWindowsOpenGLTester::AngleRendererD3d9)
attributes = anglePlatformAttributes[1];
- else if (anglePlatform == "warp")
+ else if (preferredType & QWindowsOpenGLTester::AngleRendererD3d11Warp)
attributes = anglePlatformAttributes[2];
- else
- qCWarning(lcQpaGl) << "Invalid value set for QT_ANGLE_PLATFORM:" << anglePlatform;
-
if (attributes)
display = libEGL.eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, dc, attributes);
}
-#endif // EGL_ANGLE_platform_angle_opengl
+#else // EGL_ANGLE_platform_angle_opengl
+ Q_UNUSED(preferredType)
+#endif
if (display == EGL_NO_DISPLAY)
display = libEGL.eglGetDisplay((EGLNativeDisplayType)dc);
if (!display) {
diff --git a/src/plugins/platforms/windows/qwindowseglcontext.h b/src/plugins/platforms/windows/qwindowseglcontext.h
index 63a7c25a6f..45ccbfb734 100644
--- a/src/plugins/platforms/windows/qwindowseglcontext.h
+++ b/src/plugins/platforms/windows/qwindowseglcontext.h
@@ -35,6 +35,7 @@
#define QWINDOWSEGLCONTEXT_H
#include "qwindowsopenglcontext.h"
+#include "qwindowsopengltester.h"
#include <EGL/egl.h>
QT_BEGIN_NAMESPACE
@@ -249,7 +250,7 @@ class QWindowsEGLStaticContext : public QWindowsStaticOpenGLContext
Q_DISABLE_COPY(QWindowsEGLStaticContext)
public:
- static QWindowsEGLStaticContext *create();
+ static QWindowsEGLStaticContext *create(QWindowsOpenGLTester::Renderers preferredType);
~QWindowsEGLStaticContext();
EGLDisplay display() const { return m_display; }
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index 54fb138d85..82686f38ad 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -328,47 +328,61 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons
}
#ifndef QT_NO_OPENGL
-static QWindowsStaticOpenGLContext *q_staticOpenGLContext = 0;
-QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::create()
+QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::doCreate()
{
- QWindowsStaticOpenGLContext *ctx = 0;
-
#if defined(QT_OPENGL_DYNAMIC)
- const QByteArray requested = qgetenv("QT_OPENGL"); // angle, desktop, software
- const bool angleRequested = QCoreApplication::testAttribute(Qt::AA_UseOpenGLES) || requested == "angle";
- const bool desktopRequested = QCoreApplication::testAttribute(Qt::AA_UseDesktopOpenGL) || requested == "desktop";
- const bool softwareRequested = QCoreApplication::testAttribute(Qt::AA_UseSoftwareOpenGL) || requested == "software";
-
+ QWindowsOpenGLTester::Renderer requestedRenderer = QWindowsOpenGLTester::requestedRenderer();
+ switch (requestedRenderer) {
+ case QWindowsOpenGLTester::DesktopGl:
+ if (QWindowsStaticOpenGLContext *glCtx = QOpenGLStaticContext::create())
+ return glCtx;
+ qCWarning(lcQpaGl, "System OpenGL failed. Falling back to Software OpenGL.");
+ return QOpenGLStaticContext::create(true);
// If ANGLE is requested, use it, don't try anything else.
- if (angleRequested) {
- ctx = QWindowsEGLStaticContext::create();
- } else {
- // If opengl32.dll seems to be OpenGL 2.x capable, or desktop OpenGL is requested, use it.
- if (!softwareRequested && (desktopRequested || QWindowsOpenGLTester::testDesktopGL()))
- ctx = QOpenGLStaticContext::create();
- // If failed and desktop OpenGL is not explicitly requested, try ANGLE.
- if (!ctx && !desktopRequested && !softwareRequested)
- ctx = QWindowsEGLStaticContext::create();
- // Try software.
- if (!ctx) {
- ctx = QOpenGLStaticContext::create(true);
- // If software was explicitly requested but failed, try the regular one.
- if (!ctx && softwareRequested && QWindowsOpenGLTester::testDesktopGL()) {
- qCWarning(lcQpaGl, "Software OpenGL failed. Falling back to system OpenGL.");
- ctx = QOpenGLStaticContext::create();
- }
- }
+ case QWindowsOpenGLTester::AngleRendererD3d9:
+ case QWindowsOpenGLTester::AngleRendererD3d11:
+ case QWindowsOpenGLTester::AngleRendererD3d11Warp:
+ return QWindowsEGLStaticContext::create(requestedRenderer);
+ case QWindowsOpenGLTester::Gles:
+ return QWindowsEGLStaticContext::create(QWindowsOpenGLTester::supportedGlesRenderers());
+ case QWindowsOpenGLTester::SoftwareRasterizer:
+ if (QWindowsStaticOpenGLContext *swCtx = QOpenGLStaticContext::create(true))
+ return swCtx;
+ qCWarning(lcQpaGl, "Software OpenGL failed. Falling back to system OpenGL.");
+ if (QWindowsOpenGLTester::supportedRenderers() & QWindowsOpenGLTester::DesktopGl)
+ return QOpenGLStaticContext::create();
+ return Q_NULLPTR;
+ default:
+ break;
}
+
+ const QWindowsOpenGLTester::Renderers supportedRenderers = QWindowsOpenGLTester::supportedRenderers();
+ if (supportedRenderers & QWindowsOpenGLTester::DesktopGl) {
+ if (QWindowsStaticOpenGLContext *glCtx = QOpenGLStaticContext::create())
+ return glCtx;
+ }
+ if (QWindowsOpenGLTester::Renderers glesRenderers = supportedRenderers & QWindowsOpenGLTester::GlesMask) {
+ if (QWindowsEGLStaticContext *eglCtx = QWindowsEGLStaticContext::create(glesRenderers))
+ return eglCtx;
+ }
+ return QOpenGLStaticContext::create(true);
#elif defined(QT_OPENGL_ES_2)
- ctx = QWindowsEGLStaticContext::create();
+ QWindowsOpenGLTester::Renderers glesRenderers = QWindowsOpenGLTester::requestedGlesRenderer();
+ if (glesRenderers == QWindowsOpenGLTester::InvalidRenderer)
+ glesRenderers = QWindowsOpenGLTester::supportedGlesRenderers();
+ return QWindowsEGLStaticContext::create(glesRenderers);
#elif !defined(QT_NO_OPENGL)
- ctx = QOpenGLStaticContext::create();
+ return QOpenGLStaticContext::create();
#endif
+}
- q_staticOpenGLContext = ctx;
+static QWindowsStaticOpenGLContext *q_staticOpenGLContext = 0;
- return ctx;
+QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::create()
+{
+ q_staticOpenGLContext = QWindowsStaticOpenGLContext::doCreate();
+ return q_staticOpenGLContext;
}
bool QWindowsIntegrationPrivate::ensureStaticOpenGLContext()
diff --git a/src/plugins/platforms/windows/qwindowsopenglcontext.h b/src/plugins/platforms/windows/qwindowsopenglcontext.h
index 2f724f3dd7..550bf00a40 100644
--- a/src/plugins/platforms/windows/qwindowsopenglcontext.h
+++ b/src/plugins/platforms/windows/qwindowsopenglcontext.h
@@ -58,6 +58,9 @@ public:
// reimplement these.
virtual void *createWindowSurface(void * /*nativeWindow*/, void * /*nativeConfig*/) { return 0; }
virtual void destroyWindowSurface(void * /*nativeSurface*/) { }
+
+private:
+ static QWindowsStaticOpenGLContext *doCreate();
};
class QWindowsOpenGLContext : public QPlatformOpenGLContext
diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp
index 5ef3dc0855..ac886b6bee 100644
--- a/src/plugins/platforms/windows/qwindowsopengltester.cpp
+++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp
@@ -37,6 +37,7 @@
#include <QtCore/QVariantMap>
#include <QtCore/QDebug>
#include <QtCore/QTextStream>
+#include <QtCore/QCoreApplication>
#ifndef Q_OS_WINCE
# include <QtCore/qt_windows.h>
@@ -171,6 +172,87 @@ QVariant GpuDescription::toVariant() const
return result;
}
+QWindowsOpenGLTester::Renderer QWindowsOpenGLTester::requestedGlesRenderer()
+{
+#ifndef Q_OS_WINCE
+ const char platformVar[] = "QT_ANGLE_PLATFORM";
+ if (qEnvironmentVariableIsSet(platformVar)) {
+ const QByteArray anglePlatform = qgetenv(platformVar);
+ if (anglePlatform == "d3d11")
+ return QWindowsOpenGLTester::AngleRendererD3d11;
+ if (anglePlatform == "d3d9")
+ return QWindowsOpenGLTester::AngleRendererD3d9;
+ if (anglePlatform == "warp")
+ return QWindowsOpenGLTester::AngleRendererD3d11Warp;
+ qCWarning(lcQpaGl) << "Invalid value set for " << platformVar << ": " << anglePlatform;
+ }
+#endif // !Q_OS_WINCE
+ return QWindowsOpenGLTester::InvalidRenderer;
+}
+
+QWindowsOpenGLTester::Renderer QWindowsOpenGLTester::requestedRenderer()
+{
+#ifndef Q_OS_WINCE
+ const char openGlVar[] = "QT_OPENGL";
+ if (QCoreApplication::testAttribute(Qt::AA_UseOpenGLES)) {
+ const Renderer glesRenderer = QWindowsOpenGLTester::requestedGlesRenderer();
+ return glesRenderer != InvalidRenderer ? glesRenderer : Gles;
+ }
+ if (QCoreApplication::testAttribute(Qt::AA_UseDesktopOpenGL))
+ return QWindowsOpenGLTester::DesktopGl;
+ if (QCoreApplication::testAttribute(Qt::AA_UseSoftwareOpenGL))
+ return QWindowsOpenGLTester::SoftwareRasterizer;
+ if (qEnvironmentVariableIsSet(openGlVar)) {
+ const QByteArray requested = qgetenv(openGlVar);
+ if (requested == "angle") {
+ const Renderer glesRenderer = QWindowsOpenGLTester::requestedGlesRenderer();
+ return glesRenderer != InvalidRenderer ? glesRenderer : Gles;
+ }
+ if (requested == "desktop")
+ return QWindowsOpenGLTester::DesktopGl;
+ if (requested == "software")
+ return QWindowsOpenGLTester::SoftwareRasterizer;
+ qCWarning(lcQpaGl) << "Invalid value set for " << openGlVar << ": " << requested;
+ }
+#endif // !Q_OS_WINCE
+ return QWindowsOpenGLTester::InvalidRenderer;
+}
+
+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;
+ return result;
+#else // !Q_OS_WINCE
+ return QWindowsOpenGLTester::Gles;
+#endif
+}
+
+QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::supportedGlesRenderers()
+{
+ const GpuDescription gpu = GpuDescription::detect();
+ const QWindowsOpenGLTester::Renderers result = detectSupportedRenderers(gpu, true);
+ qDebug(lcQpaGl) << __FUNCTION__ << gpu << "renderer: " << result;
+ return result;
+}
+
+QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::supportedRenderers()
+{
+ const GpuDescription gpu = GpuDescription::detect();
+ const QWindowsOpenGLTester::Renderers result = detectSupportedRenderers(gpu, false);
+ qDebug(lcQpaGl) << __FUNCTION__ << gpu << "renderer: " << result;
+ return result;
+}
+
bool QWindowsOpenGLTester::testDesktopGL()
{
#ifndef Q_OS_WINCE
diff --git a/src/plugins/platforms/windows/qwindowsopengltester.h b/src/plugins/platforms/windows/qwindowsopengltester.h
index 98b707dcd2..6238eea4b0 100644
--- a/src/plugins/platforms/windows/qwindowsopengltester.h
+++ b/src/plugins/platforms/windows/qwindowsopengltester.h
@@ -37,6 +37,7 @@
#include <qtwindowsglobal.h>
#include <QtCore/QByteArray>
+#include <QtCore/QFlags>
QT_BEGIN_NAMESPACE
@@ -92,9 +93,29 @@ QDebug operator<<(QDebug d, const GpuDescription &gd);
class QWindowsOpenGLTester
{
public:
+ enum Renderer {
+ InvalidRenderer = 0x0000,
+ DesktopGl = 0x0001,
+ AngleRendererD3d11 = 0x0002,
+ AngleRendererD3d9 = 0x0004,
+ AngleRendererD3d11Warp = 0x0008, // "Windows Advanced Rasterization Platform"
+ AngleBackendMask = AngleRendererD3d11 | AngleRendererD3d9 | AngleRendererD3d11Warp,
+ Gles = 0x0010, // ANGLE/unspecified or Generic GLES for Windows CE.
+ GlesMask = Gles | AngleBackendMask,
+ SoftwareRasterizer = 0x0020
+ };
+ Q_DECLARE_FLAGS(Renderers, Renderer)
+
+ static Renderer requestedGlesRenderer();
+ static Renderer requestedRenderer();
+ static Renderers supportedGlesRenderers();
+ static Renderers supportedRenderers();
+
static bool testDesktopGL();
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QWindowsOpenGLTester::Renderers)
+
QT_END_NAMESPACE
#endif // QWINDOWSOPENGLTESTER_H