Windows: Add infrastructure to be able to a GL renderer based on GPU.
Introduce flags for the renderer type and move code to qwindowsopengltester. Introduce QWindowsOpenGLTester::supportedGlesRenderers() where type-dependent checking can be added. Change-Id: I4bbffaf861cb0fdbea0919e081e3626fb5a872de Task-number: QTBUG-43263 Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>bb10
parent
0fa092cbae
commit
97a82f62c4
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -328,47 +328,61 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons
|
|||
}
|
||||
|
||||
#ifndef QT_NO_OPENGL
|
||||
|
||||
QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::doCreate()
|
||||
{
|
||||
#if defined(QT_OPENGL_DYNAMIC)
|
||||
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.
|
||||
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)
|
||||
QWindowsOpenGLTester::Renderers glesRenderers = QWindowsOpenGLTester::requestedGlesRenderer();
|
||||
if (glesRenderers == QWindowsOpenGLTester::InvalidRenderer)
|
||||
glesRenderers = QWindowsOpenGLTester::supportedGlesRenderers();
|
||||
return QWindowsEGLStaticContext::create(glesRenderers);
|
||||
#elif !defined(QT_NO_OPENGL)
|
||||
return QOpenGLStaticContext::create();
|
||||
#endif
|
||||
}
|
||||
|
||||
static QWindowsStaticOpenGLContext *q_staticOpenGLContext = 0;
|
||||
|
||||
QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::create()
|
||||
{
|
||||
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";
|
||||
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
#elif defined(QT_OPENGL_ES_2)
|
||||
ctx = QWindowsEGLStaticContext::create();
|
||||
#elif !defined(QT_NO_OPENGL)
|
||||
ctx = QOpenGLStaticContext::create();
|
||||
#endif
|
||||
|
||||
q_staticOpenGLContext = ctx;
|
||||
|
||||
return ctx;
|
||||
q_staticOpenGLContext = QWindowsStaticOpenGLContext::doCreate();
|
||||
return q_staticOpenGLContext;
|
||||
}
|
||||
|
||||
bool QWindowsIntegrationPrivate::ensureStaticOpenGLContext()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue