From bdb1c18e411a1660f038e4f0e219d363d38e987a Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 22 Mar 2016 15:32:36 +0100 Subject: [PATCH] windows: Fall back to D3D9 when 11 fails It is assumed that this happens automatically but that is not always the case. Do not become stuck with a non-functional D3D11-backed EGL environment. Instead, try again as if QT_ANGLE_PLATFORM=d3d9 was requested. Task-number: QTBUG-52056 Change-Id: I12ac6ca5f1d06f9504d05120d8e1053e97edfab3 Reviewed-by: Friedemann Kleint --- .../platforms/windows/qwindowseglcontext.cpp | 71 ++++++++++++------- .../platforms/windows/qwindowseglcontext.h | 2 + 2 files changed, 47 insertions(+), 26 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp index 787a072a7a1..9ae1ca8acbe 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp @@ -347,6 +347,45 @@ QWindowsEGLStaticContext::QWindowsEGLStaticContext(EGLDisplay display) { } +bool QWindowsEGLStaticContext::initializeAngle(QWindowsOpenGLTester::Renderers preferredType, HDC dc, + EGLDisplay *display, EGLint *major, EGLint *minor) +{ +#ifdef EGL_ANGLE_platform_angle + 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_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE, EGL_NONE } + }; + const EGLint *attributes = 0; + if (preferredType & QWindowsOpenGLTester::AngleRendererD3d11) + attributes = anglePlatformAttributes[0]; + else if (preferredType & QWindowsOpenGLTester::AngleRendererD3d9) + attributes = anglePlatformAttributes[1]; + else if (preferredType & QWindowsOpenGLTester::AngleRendererD3d11Warp) + attributes = anglePlatformAttributes[2]; + if (attributes) { + *display = libEGL.eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, dc, attributes); + if (!libEGL.eglInitialize(*display, major, minor)) { + libEGL.eglTerminate(*display); + *display = EGL_NO_DISPLAY; + *major = *minor = 0; + return false; + } + } + } +#else // EGL_ANGLE_platform_angle + Q_UNUSED(preferredType); + Q_UNUSED(dc); + Q_UNUSED(display); + Q_UNUSED(major); + Q_UNUSED(minor); +#endif + return true; +} + QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester::Renderers preferredType) { const HDC dc = QWindowsContext::instance()->displayContext(); @@ -367,33 +406,13 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester: EGLDisplay display = EGL_NO_DISPLAY; EGLint major = 0; EGLint minor = 0; -#ifdef EGL_ANGLE_platform_angle - 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_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE, EGL_NONE } - }; - const EGLint *attributes = 0; - if (preferredType & QWindowsOpenGLTester::AngleRendererD3d11) - attributes = anglePlatformAttributes[0]; - else if (preferredType & QWindowsOpenGLTester::AngleRendererD3d9) - attributes = anglePlatformAttributes[1]; - else if (preferredType & QWindowsOpenGLTester::AngleRendererD3d11Warp) - attributes = anglePlatformAttributes[2]; - if (attributes) { - display = libEGL.eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, dc, attributes); - if (!libEGL.eglInitialize(display, &major, &minor)) { - display = EGL_NO_DISPLAY; - major = minor = 0; - } - } + + if (!initializeAngle(preferredType, dc, &display, &major, &minor) + && (preferredType & QWindowsOpenGLTester::AngleRendererD3d11)) { + preferredType &= ~QWindowsOpenGLTester::AngleRendererD3d11; + initializeAngle(preferredType, dc, &display, &major, &minor); } -#else // EGL_ANGLE_platform_angle - Q_UNUSED(preferredType) -#endif + if (display == EGL_NO_DISPLAY) display = libEGL.eglGetDisplay(dc); if (!display) { diff --git a/src/plugins/platforms/windows/qwindowseglcontext.h b/src/plugins/platforms/windows/qwindowseglcontext.h index 6945939941d..1a6058c9210 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.h +++ b/src/plugins/platforms/windows/qwindowseglcontext.h @@ -271,6 +271,8 @@ public: private: explicit QWindowsEGLStaticContext(EGLDisplay display); + static bool initializeAngle(QWindowsOpenGLTester::Renderers preferredType, HDC dc, + EGLDisplay *display, EGLint *major, EGLint *minor); const EGLDisplay m_display; };