diff options
Diffstat (limited to 'src/plugins/platforms/windows')
-rw-r--r-- | src/plugins/platforms/windows/.prev_CMakeLists.txt | 34 | ||||
-rw-r--r-- | src/plugins/platforms/windows/CMakeLists.txt | 28 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowseglcontext.cpp | 918 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowseglcontext.h | 176 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsintegration.cpp | 27 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsnativeinterface.cpp | 19 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsopenglcontext.h | 2 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsopengltester.cpp | 52 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsopengltester.h | 7 | ||||
-rw-r--r-- | src/plugins/platforms/windows/windows.pri | 24 |
10 files changed, 23 insertions, 1264 deletions
diff --git a/src/plugins/platforms/windows/.prev_CMakeLists.txt b/src/plugins/platforms/windows/.prev_CMakeLists.txt index 29bd26a67e..c87a51e04a 100644 --- a/src/plugins/platforms/windows/.prev_CMakeLists.txt +++ b/src/plugins/platforms/windows/.prev_CMakeLists.txt @@ -132,34 +132,20 @@ qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_directwrite3 #### Keys ignored in scope 6:.:.:windows.pro:NOT TARGET___equals____ss_QT_DEFAULT_QPA_PLUGIN: # PLUGIN_EXTENDS = "-" -qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_opengl AND NOT QT_FEATURE_dynamicgl AND NOT QT_FEATURE_opengles2 +qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_opengl AND NOT QT_FEATURE_dynamicgl PUBLIC_LIBRARIES opengl32 ) -qt_extend_target(QWindowsIntegrationPlugin CONDITION mingw +qt_extend_target(QWindowsIntegrationPlugin CONDITION MINGW PUBLIC_LIBRARIES uuid ) qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_opengl SOURCES - qwindowsopenglcontext.h -) - -qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_opengles2 - SOURCES - qwindowseglcontext.cpp qwindowseglcontext.h -) - -qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_opengl AND NOT QT_FEATURE_opengles2 - SOURCES qwindowsglcontext.cpp qwindowsglcontext.h -) - -qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_dynamicgl - SOURCES - qwindowseglcontext.cpp qwindowseglcontext.h + qwindowsopenglcontext.h ) qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_systemtrayicon @@ -228,19 +214,7 @@ qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_accessibility AN Qt::WindowsUIAutomationSupportPrivate ) -qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_accessibility AND mingw +qt_extend_target(QWindowsIntegrationPlugin CONDITION MINGW AND QT_FEATURE_accessibility PUBLIC_LIBRARIES uuid ) - -qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_combined_angle_lib - DEFINES - LIBEGL_NAME= - LIBGLESV2_NAME= -) - -qt_extend_target(QWindowsIntegrationPlugin CONDITION NOT QT_FEATURE_combined_angle_lib - DEFINES - LIBEGL_NAME= - LIBGLESV2_NAME= -) diff --git a/src/plugins/platforms/windows/CMakeLists.txt b/src/plugins/platforms/windows/CMakeLists.txt index ba39c7567d..c79a5a335b 100644 --- a/src/plugins/platforms/windows/CMakeLists.txt +++ b/src/plugins/platforms/windows/CMakeLists.txt @@ -43,7 +43,6 @@ qt_internal_add_plugin(QWindowsIntegrationPlugin ${CMAKE_CURRENT_SOURCE_DIR} LIBRARIES advapi32 - d3d9 gdi32 ole32 shell32 @@ -131,34 +130,20 @@ qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_directwrite3 #### Keys ignored in scope 6:.:.:windows.pro:NOT TARGET___equals____ss_QT_DEFAULT_QPA_PLUGIN: # PLUGIN_EXTENDS = "-" -qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_opengl AND NOT QT_FEATURE_dynamicgl AND NOT QT_FEATURE_opengles2 +qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_opengl AND NOT QT_FEATURE_dynamicgl PUBLIC_LIBRARIES opengl32 ) -qt_extend_target(QWindowsIntegrationPlugin CONDITION mingw +qt_extend_target(QWindowsIntegrationPlugin CONDITION MINGW PUBLIC_LIBRARIES uuid ) qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_opengl SOURCES - qwindowsopenglcontext.h -) - -qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_opengles2 - SOURCES - qwindowseglcontext.cpp qwindowseglcontext.h -) - -qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_opengl AND NOT QT_FEATURE_opengles2 - SOURCES qwindowsglcontext.cpp qwindowsglcontext.h -) - -qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_dynamicgl - SOURCES - qwindowseglcontext.cpp qwindowseglcontext.h + qwindowsopenglcontext.h ) qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_systemtrayicon @@ -227,12 +212,7 @@ qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_accessibility AN Qt::WindowsUIAutomationSupportPrivate ) -qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_accessibility AND mingw +qt_extend_target(QWindowsIntegrationPlugin CONDITION MINGW AND QT_FEATURE_accessibility PUBLIC_LIBRARIES uuid ) - -# special case: -# qt_extend_target(QWindowsIntegrationPlugin CONDITION QT_FEATURE_combined_angle_lib ... -# qt_extend_target(QWindowsIntegrationPlugin CONDITION NOT QT_FEATURE_combined_angle_lib ... - diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp deleted file mode 100644 index d0b3568dad..0000000000 --- a/src/plugins/platforms/windows/qwindowseglcontext.cpp +++ /dev/null @@ -1,918 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwindowseglcontext.h" -#include "qwindowscontext.h" -#include "qwindowswindow.h" - -#include <QtCore/qdebug.h> -#include <QtGui/qopenglcontext.h> - -#if QT_CONFIG(angle) || defined(QT_OPENGL_DYNAMIC) -# include <EGL/eglext.h> -#endif - -QT_BEGIN_NAMESPACE - -/*! - \class QWindowsEGLStaticContext - \brief Static data for QWindowsEGLContext. - - Keeps the display. The class is shared via QSharedPointer in the windows, the - contexts and in QWindowsIntegration. The display will be closed if the last instance - is deleted. - - No EGL or OpenGL functions are called directly. Instead, they are resolved - dynamically. This works even if the plugin links directly to libegl/libglesv2 so - there is no need to differentiate between dynamic or Angle-only builds in here. - - \internal -*/ - -QWindowsLibEGL QWindowsEGLStaticContext::libEGL; -QWindowsLibGLESv2 QWindowsEGLStaticContext::libGLESv2; - -#if !defined(QT_STATIC) || defined(QT_OPENGL_DYNAMIC) - -#ifdef Q_CC_MINGW -static void *resolveFunc(HMODULE lib, const char *name) -{ - QString baseNameStr = QString::fromLatin1(name); - QString nameStr; - void *proc = 0; - - // Play nice with 32-bit mingw: Try func first, then func@0, func@4, - // func@8, func@12, ..., func@64. The def file does not provide any aliases - // in libEGL and libGLESv2 in these builds which results in exporting - // function names like eglInitialize@12. This cannot be fixed without - // breaking binary compatibility. So be flexible here instead. - - int argSize = -1; - while (!proc && argSize <= 64) { - nameStr = baseNameStr; - if (argSize >= 0) - nameStr += u'@' + QString::number(argSize); - argSize = argSize < 0 ? 0 : argSize + 4; - proc = (void *) ::GetProcAddress(lib, nameStr.toLatin1().constData()); - } - return proc; -} -#else -static inline void *resolveFunc(HMODULE lib, const char *name) -{ - return ::GetProcAddress(lib, name); -} -#endif // Q_CC_MINGW - -void *QWindowsLibEGL::resolve(const char *name) -{ - return m_lib ? resolveFunc(m_lib, name) : nullptr; -} - -#endif // !QT_STATIC - -#if !defined(QT_STATIC) || defined(QT_OPENGL_DYNAMIC) -# define RESOLVE(signature, name) signature(resolve( #name )); -#else -# define RESOLVE(signature, name) signature(&::name); -#endif - -bool QWindowsLibEGL::init() -{ - const char dllName[] = QT_STRINGIFY(LIBEGL_NAME) -#if defined(QT_DEBUG) - "d" -#endif - ""; - - qCDebug(lcQpaGl) << "Qt: Using EGL from" << dllName; - -#if !defined(QT_STATIC) || defined(QT_OPENGL_DYNAMIC) - m_lib = ::LoadLibraryW((const wchar_t *) QString::fromLatin1(dllName).utf16()); - if (!m_lib) { - qErrnoWarning(::GetLastError(), "Failed to load %s", dllName); - return false; - } -#endif - - eglGetError = RESOLVE((EGLint (EGLAPIENTRY *)(void)), eglGetError); - eglGetDisplay = RESOLVE((EGLDisplay (EGLAPIENTRY *)(EGLNativeDisplayType)), eglGetDisplay); - eglInitialize = RESOLVE((EGLBoolean (EGLAPIENTRY *)(EGLDisplay, EGLint *, EGLint *)), eglInitialize); - eglTerminate = RESOLVE((EGLBoolean (EGLAPIENTRY *)(EGLDisplay)), eglTerminate); - eglChooseConfig = RESOLVE((EGLBoolean (EGLAPIENTRY *)(EGLDisplay, const EGLint *, EGLConfig *, EGLint, EGLint *)), eglChooseConfig); - eglGetConfigAttrib = RESOLVE((EGLBoolean (EGLAPIENTRY *)(EGLDisplay, EGLConfig, EGLint, EGLint *)), eglGetConfigAttrib); - eglCreateWindowSurface = RESOLVE((EGLSurface (EGLAPIENTRY *)(EGLDisplay, EGLConfig, EGLNativeWindowType, const EGLint *)), eglCreateWindowSurface); - eglCreatePbufferSurface = RESOLVE((EGLSurface (EGLAPIENTRY *)(EGLDisplay , EGLConfig, const EGLint *)), eglCreatePbufferSurface); - eglDestroySurface = RESOLVE((EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLSurface )), eglDestroySurface); - eglBindAPI = RESOLVE((EGLBoolean (EGLAPIENTRY * )(EGLenum )), eglBindAPI); - eglSwapInterval = RESOLVE((EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLint )), eglSwapInterval); - eglCreateContext = RESOLVE((EGLContext (EGLAPIENTRY *)(EGLDisplay , EGLConfig , EGLContext , const EGLint *)), eglCreateContext); - eglDestroyContext = RESOLVE((EGLBoolean (EGLAPIENTRY *)(EGLDisplay, EGLContext)), eglDestroyContext); - eglMakeCurrent = RESOLVE((EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLSurface , EGLSurface , EGLContext )), eglMakeCurrent); - eglGetCurrentContext = RESOLVE((EGLContext (EGLAPIENTRY *)(void)), eglGetCurrentContext); - eglGetCurrentSurface = RESOLVE((EGLSurface (EGLAPIENTRY *)(EGLint )), eglGetCurrentSurface); - eglGetCurrentDisplay = RESOLVE((EGLDisplay (EGLAPIENTRY *)(void)), eglGetCurrentDisplay); - eglSwapBuffers = RESOLVE((EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLSurface)), eglSwapBuffers); - eglGetProcAddress = RESOLVE((QFunctionPointer (EGLAPIENTRY * )(const char *)), eglGetProcAddress); - - if (!eglGetError || !eglGetDisplay || !eglInitialize || !eglGetProcAddress) - return false; - - eglGetPlatformDisplayEXT = nullptr; -#ifdef EGL_ANGLE_platform_angle - eglGetPlatformDisplayEXT = reinterpret_cast<EGLDisplay (EGLAPIENTRY *)(EGLenum, void *, const EGLint *)>(eglGetProcAddress("eglGetPlatformDisplayEXT")); -#endif - - return true; -} - -#if !defined(QT_STATIC) || defined(QT_OPENGL_DYNAMIC) -void *QWindowsLibGLESv2::resolve(const char *name) -{ - return m_lib ? resolveFunc(m_lib, name) : nullptr; -} -#endif // !QT_STATIC - -bool QWindowsLibGLESv2::init() -{ - - const char dllName[] = QT_STRINGIFY(LIBGLESV2_NAME) -#if defined(QT_DEBUG) - "d" -#endif - ""; - - qCDebug(lcQpaGl) << "Qt: Using OpenGL ES 2.0 from" << dllName; -#if !defined(QT_STATIC) || defined(QT_OPENGL_DYNAMIC) - m_lib = ::LoadLibraryW(reinterpret_cast<LPCWSTR>(QString::fromLatin1(dllName).utf16())); - if (!m_lib) { - qErrnoWarning(int(GetLastError()), "Failed to load %s", dllName); - return false; - } -#endif // !QT_STATIC - - void (APIENTRY * glBindTexture)(GLenum target, GLuint texture) = RESOLVE((void (APIENTRY *)(GLenum , GLuint )), glBindTexture); - GLuint (APIENTRY * glCreateShader)(GLenum type) = RESOLVE((GLuint (APIENTRY *)(GLenum )), glCreateShader); - void (APIENTRY * glClearDepthf)(GLclampf depth) = RESOLVE((void (APIENTRY *)(GLclampf )), glClearDepthf); - glGetString = RESOLVE((const GLubyte * (APIENTRY *)(GLenum )), glGetString); - - return glBindTexture && glCreateShader && glClearDepthf; -} - -QWindowsEGLStaticContext::QWindowsEGLStaticContext(EGLDisplay display) - : m_display(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 = nullptr; - 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(); - if (!dc){ - qWarning("%s: No Display", __FUNCTION__); - return nullptr; - } - - if (!libEGL.init()) { - qWarning("%s: Failed to load and resolve libEGL functions", __FUNCTION__); - return nullptr; - } - if (!libGLESv2.init()) { - qWarning("%s: Failed to load and resolve libGLESv2 functions", __FUNCTION__); - return nullptr; - } - - EGLDisplay display = EGL_NO_DISPLAY; - EGLint major = 0; - EGLint minor = 0; - - if (!initializeAngle(preferredType, dc, &display, &major, &minor) - && (preferredType & QWindowsOpenGLTester::AngleRendererD3d11)) { - preferredType &= ~QWindowsOpenGLTester::AngleRendererD3d11; - initializeAngle(preferredType, dc, &display, &major, &minor); - } - - if (display == EGL_NO_DISPLAY) - display = libEGL.eglGetDisplay(dc); - if (!display) { - qWarning("%s: Could not obtain EGL display", __FUNCTION__); - return nullptr; - } - - if (!major && !libEGL.eglInitialize(display, &major, &minor)) { - int err = libEGL.eglGetError(); - qWarning("%s: Could not initialize EGL display: error 0x%x", __FUNCTION__, err); - if (err == 0x3001) - qWarning("%s: When using ANGLE, check if d3dcompiler_4x.dll is available", __FUNCTION__); - return nullptr; - } - - qCDebug(lcQpaGl) << __FUNCTION__ << "Created EGL display" << display << 'v' <<major << '.' << minor; - return new QWindowsEGLStaticContext(display); -} - -QWindowsEGLStaticContext::~QWindowsEGLStaticContext() -{ - qCDebug(lcQpaGl) << __FUNCTION__ << "Releasing EGL display " << m_display; - libEGL.eglTerminate(m_display); -} - -QWindowsOpenGLContext *QWindowsEGLStaticContext::createContext(QOpenGLContext *context) -{ - return new QWindowsEGLContext(this, context->format(), context->shareHandle()); -} - -void *QWindowsEGLStaticContext::createWindowSurface(void *nativeWindow, void *nativeConfig, int *err) -{ - *err = 0; - EGLSurface surface = libEGL.eglCreateWindowSurface(m_display, nativeConfig, - static_cast<EGLNativeWindowType>(nativeWindow), nullptr); - if (surface == EGL_NO_SURFACE) { - *err = libEGL.eglGetError(); - qWarning("%s: Could not create the EGL window surface: 0x%x", __FUNCTION__, *err); - } - - return surface; -} - -void QWindowsEGLStaticContext::destroyWindowSurface(void *nativeSurface) -{ - libEGL.eglDestroySurface(m_display, nativeSurface); -} - -QSurfaceFormat QWindowsEGLStaticContext::formatFromConfig(EGLDisplay display, EGLConfig config, - const QSurfaceFormat &referenceFormat) -{ - QSurfaceFormat format; - EGLint redSize = 0; - EGLint greenSize = 0; - EGLint blueSize = 0; - EGLint alphaSize = 0; - EGLint depthSize = 0; - EGLint stencilSize = 0; - EGLint sampleCount = 0; - - libEGL.eglGetConfigAttrib(display, config, EGL_RED_SIZE, &redSize); - libEGL.eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &greenSize); - libEGL.eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blueSize); - libEGL.eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alphaSize); - libEGL.eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE, &depthSize); - libEGL.eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &stencilSize); - libEGL.eglGetConfigAttrib(display, config, EGL_SAMPLES, &sampleCount); - - format.setRenderableType(QSurfaceFormat::OpenGLES); - format.setVersion(referenceFormat.majorVersion(), referenceFormat.minorVersion()); - format.setProfile(referenceFormat.profile()); - format.setOptions(referenceFormat.options()); - - format.setRedBufferSize(redSize); - format.setGreenBufferSize(greenSize); - format.setBlueBufferSize(blueSize); - format.setAlphaBufferSize(alphaSize); - format.setDepthBufferSize(depthSize); - format.setStencilBufferSize(stencilSize); - format.setSamples(sampleCount); - format.setStereo(false); - format.setSwapInterval(referenceFormat.swapInterval()); - - // Clear the EGL error state because some of the above may - // have errored out because the attribute is not applicable - // to the surface type. Such errors don't matter. - libEGL.eglGetError(); - - return format; -} - -/*! - \class QWindowsEGLContext - \brief Open EGL context. - - \section1 Using QWindowsEGLContext for Desktop with ANGLE - \section2 Build Instructions - \list - \o Install the Direct X SDK - \o Checkout and build ANGLE (SVN repository) as explained here: - \l{https://chromium.googlesource.com/angle/angle/+/master/README.md} - When building for 64bit, de-activate the "WarnAsError" option - in every project file (as otherwise integer conversion - warnings will break the build). - \o Run configure.exe with the options "-opengl es2". - \o Build qtbase and test some examples. - \endlist - - \internal -*/ - -QWindowsEGLContext::QWindowsEGLContext(QWindowsEGLStaticContext *staticContext, - const QSurfaceFormat &format, - QPlatformOpenGLContext *share) - : m_staticContext(staticContext) - , m_eglDisplay(staticContext->display()) -{ - if (!m_staticContext) - return; - - m_eglConfig = chooseConfig(format); - m_format = m_staticContext->formatFromConfig(m_eglDisplay, m_eglConfig, format); - m_shareContext = share ? static_cast<QWindowsEGLContext *>(share)->m_eglContext : nullptr; - - QVector<EGLint> contextAttrs; - const int major = m_format.majorVersion(); - const int minor = m_format.minorVersion(); - if (major > 3 || (major == 3 && minor > 0)) - qWarning("QWindowsEGLContext: ANGLE only partially supports OpenGL ES > 3.0"); - contextAttrs.append(EGL_CONTEXT_MAJOR_VERSION); - contextAttrs.append(major); - contextAttrs.append(EGL_CONTEXT_MINOR_VERSION); - contextAttrs.append(minor); - contextAttrs.append(EGL_NONE); - - QWindowsEGLStaticContext::libEGL.eglBindAPI(m_api); - m_eglContext = QWindowsEGLStaticContext::libEGL.eglCreateContext(m_eglDisplay, m_eglConfig, m_shareContext, contextAttrs.constData()); - if (m_eglContext == EGL_NO_CONTEXT && m_shareContext != EGL_NO_CONTEXT) { - m_shareContext = nullptr; - m_eglContext = QWindowsEGLStaticContext::libEGL.eglCreateContext(m_eglDisplay, m_eglConfig, nullptr, contextAttrs.constData()); - } - - if (m_eglContext == EGL_NO_CONTEXT) { - int err = QWindowsEGLStaticContext::libEGL.eglGetError(); - qWarning("QWindowsEGLContext: Failed to create context, eglError: %x, this: %p", err, this); - // ANGLE gives bad alloc when it fails to reset a previously lost D3D device. - // A common cause for this is disabling the graphics adapter used by the app. - if (err == EGL_BAD_ALLOC) - qWarning("QWindowsEGLContext: Graphics device lost. (Did the adapter get disabled?)"); - return; - } - - // Make the context current to ensure the GL version query works. This needs a surface too. - const EGLint pbufferAttributes[] = { - EGL_WIDTH, 1, - EGL_HEIGHT, 1, - EGL_LARGEST_PBUFFER, EGL_FALSE, - EGL_NONE - }; - EGLSurface pbuffer = QWindowsEGLStaticContext::libEGL.eglCreatePbufferSurface(m_eglDisplay, m_eglConfig, pbufferAttributes); - if (pbuffer == EGL_NO_SURFACE) - return; - - EGLDisplay prevDisplay = QWindowsEGLStaticContext::libEGL.eglGetCurrentDisplay(); - if (prevDisplay == EGL_NO_DISPLAY) // when no context is current - prevDisplay = m_eglDisplay; - EGLContext prevContext = QWindowsEGLStaticContext::libEGL.eglGetCurrentContext(); - EGLSurface prevSurfaceDraw = QWindowsEGLStaticContext::libEGL.eglGetCurrentSurface(EGL_DRAW); - EGLSurface prevSurfaceRead = QWindowsEGLStaticContext::libEGL.eglGetCurrentSurface(EGL_READ); - - if (QWindowsEGLStaticContext::libEGL.eglMakeCurrent(m_eglDisplay, pbuffer, pbuffer, m_eglContext)) { - const GLubyte *s = QWindowsEGLStaticContext::libGLESv2.glGetString(GL_VERSION); - if (s) { - QByteArray version = QByteArray(reinterpret_cast<const char *>(s)); - int major, minor; - if (QPlatformOpenGLContext::parseOpenGLVersion(version, major, minor)) { - m_format.setMajorVersion(major); - m_format.setMinorVersion(minor); - } - } - m_format.setProfile(QSurfaceFormat::NoProfile); - m_format.setOptions(QSurfaceFormat::FormatOptions()); - QWindowsEGLStaticContext::libEGL.eglMakeCurrent(prevDisplay, prevSurfaceDraw, prevSurfaceRead, prevContext); - } - QWindowsEGLStaticContext::libEGL.eglDestroySurface(m_eglDisplay, pbuffer); -} - -QWindowsEGLContext::~QWindowsEGLContext() -{ - if (m_eglContext != EGL_NO_CONTEXT) { - QWindowsEGLStaticContext::libEGL.eglDestroyContext(m_eglDisplay, m_eglContext); - m_eglContext = EGL_NO_CONTEXT; - } -} - -bool QWindowsEGLContext::makeCurrent(QPlatformSurface *surface) -{ - Q_ASSERT(surface->surface()->supportsOpenGL()); - - QWindowsEGLStaticContext::libEGL.eglBindAPI(m_api); - - auto *window = static_cast<QWindowsWindow *>(surface); - window->aboutToMakeCurrent(); - int err = 0; - auto eglSurface = static_cast<EGLSurface>(window->surface(m_eglConfig, &err)); - if (eglSurface == EGL_NO_SURFACE) { - if (err == EGL_CONTEXT_LOST) { - m_eglContext = EGL_NO_CONTEXT; - qCDebug(lcQpaGl) << "Got EGL context lost in createWindowSurface() for context" << this; - } else if (err == EGL_BAD_ACCESS) { - // With ANGLE this means no (D3D) device and can happen when disabling/changing graphics adapters. - qCDebug(lcQpaGl) << "Bad access (missing device?) in createWindowSurface() for context" << this; - // Simulate context loss as the context is useless. - QWindowsEGLStaticContext::libEGL.eglDestroyContext(m_eglDisplay, m_eglContext); - m_eglContext = EGL_NO_CONTEXT; - } - return false; - } - - // shortcut: on some GPUs, eglMakeCurrent is not a cheap operation - if (QWindowsEGLStaticContext::libEGL.eglGetCurrentContext() == m_eglContext && - QWindowsEGLStaticContext::libEGL.eglGetCurrentDisplay() == m_eglDisplay && - QWindowsEGLStaticContext::libEGL.eglGetCurrentSurface(EGL_READ) == eglSurface && - QWindowsEGLStaticContext::libEGL.eglGetCurrentSurface(EGL_DRAW) == eglSurface) { - return true; - } - - const bool ok = QWindowsEGLStaticContext::libEGL.eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_eglContext); - if (ok) { - const int requestedSwapInterval = surface->format().swapInterval(); - if (requestedSwapInterval >= 0 && m_swapInterval != requestedSwapInterval) { - m_swapInterval = requestedSwapInterval; - QWindowsEGLStaticContext::libEGL.eglSwapInterval(m_staticContext->display(), m_swapInterval); - } - } else { - err = QWindowsEGLStaticContext::libEGL.eglGetError(); - // EGL_CONTEXT_LOST (loss of the D3D device) is not necessarily fatal. - // Qt Quick is able to recover for example. - if (err == EGL_CONTEXT_LOST) { - m_eglContext = EGL_NO_CONTEXT; - qCDebug(lcQpaGl) << "Got EGL context lost in makeCurrent() for context" << this; - // Drop the surface. Will recreate on the next makeCurrent. - window->invalidateSurface(); - } else { - qWarning("%s: Failed to make surface current. eglError: %x, this: %p", __FUNCTION__, err, this); - } - } - - return ok; -} - -void QWindowsEGLContext::doneCurrent() -{ - QWindowsEGLStaticContext::libEGL.eglBindAPI(m_api); - bool ok = QWindowsEGLStaticContext::libEGL.eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - if (!ok) - qWarning("%s: Failed to make no context/surface current. eglError: %d, this: %p", __FUNCTION__, - QWindowsEGLStaticContext::libEGL.eglGetError(), this); -} - -void QWindowsEGLContext::swapBuffers(QPlatformSurface *surface) -{ - QWindowsEGLStaticContext::libEGL.eglBindAPI(m_api); - auto *window = static_cast<QWindowsWindow *>(surface); - int err = 0; - auto eglSurface = static_cast<EGLSurface>(window->surface(m_eglConfig, &err)); - if (eglSurface == EGL_NO_SURFACE) { - if (err == EGL_CONTEXT_LOST) { - m_eglContext = EGL_NO_CONTEXT; - qCDebug(lcQpaGl) << "Got EGL context lost in createWindowSurface() for context" << this; - } - return; - } - - bool ok = QWindowsEGLStaticContext::libEGL.eglSwapBuffers(m_eglDisplay, eglSurface); - if (!ok) { - err = QWindowsEGLStaticContext::libEGL.eglGetError(); - if (err == EGL_CONTEXT_LOST) { - m_eglContext = EGL_NO_CONTEXT; - qCDebug(lcQpaGl) << "Got EGL context lost in eglSwapBuffers()"; - } else { - qWarning("%s: Failed to swap buffers. eglError: %d, this: %p", __FUNCTION__, err, this); - } - } -} - -QFunctionPointer QWindowsEGLContext::getProcAddress(const char *procName) -{ - QWindowsEGLStaticContext::libEGL.eglBindAPI(m_api); - - QFunctionPointer procAddress = nullptr; - - // Special logic for ANGLE extensions for blitFramebuffer and - // renderbufferStorageMultisample. In version 2 contexts the extensions - // must be used instead of the suffixless, version 3.0 functions. - if (m_format.majorVersion() < 3) { - if (!strcmp(procName, "glBlitFramebuffer") || !strcmp(procName, "glRenderbufferStorageMultisample")) { - char extName[32 + 5 + 1]; - strcpy(extName, procName); - strcat(extName, "ANGLE"); - procAddress = reinterpret_cast<QFunctionPointer>(QWindowsEGLStaticContext::libEGL.eglGetProcAddress(extName)); - } - } - - if (!procAddress) - procAddress = reinterpret_cast<QFunctionPointer>(QWindowsEGLStaticContext::libEGL.eglGetProcAddress(procName)); - - // We support AllGLFunctionsQueryable, which means this function must be able to - // return a function pointer for standard GLES2 functions too. These are not - // guaranteed to be queryable via eglGetProcAddress(). - if (!procAddress) { -#if defined(QT_STATIC) && !defined(QT_OPENGL_DYNAMIC) - static struct StdFunc { - const char *name; - void *func; - } standardFuncs[] = { - { "glBindTexture", (void *) ::glBindTexture }, - { "glBlendFunc", (void *) ::glBlendFunc }, - { "glClear", (void *) ::glClear }, - { "glClearColor", (void *) ::glClearColor }, - { "glClearStencil", (void *) ::glClearStencil }, - { "glColorMask", (void *) ::glColorMask }, - { "glCopyTexImage2D", (void *) ::glCopyTexImage2D }, - { "glCopyTexSubImage2D", (void *) ::glCopyTexSubImage2D }, - { "glCullFace", (void *) ::glCullFace }, - { "glDeleteTextures", (void *) ::glDeleteTextures }, - { "glDepthFunc", (void *) ::glDepthFunc }, - { "glDepthMask", (void *) ::glDepthMask }, - { "glDisable", (void *) ::glDisable }, - { "glDrawArrays", (void *) ::glDrawArrays }, - { "glDrawElements", (void *) ::glDrawElements }, - { "glEnable", (void *) ::glEnable }, - { "glFinish", (void *) ::glFinish }, - { "glFlush", (void *) ::glFlush }, - { "glFrontFace", (void *) ::glFrontFace }, - { "glGenTextures", (void *) ::glGenTextures }, - { "glGetBooleanv", (void *) ::glGetBooleanv }, - { "glGetError", (void *) ::glGetError }, - { "glGetFloatv", (void *) ::glGetFloatv }, - { "glGetIntegerv", (void *) ::glGetIntegerv }, - { "glGetString", (void *) ::glGetString }, - { "glGetTexParameterfv", (void *) ::glGetTexParameterfv }, - { "glGetTexParameteriv", (void *) ::glGetTexParameteriv }, - { "glHint", (void *) ::glHint }, - { "glIsEnabled", (void *) ::glIsEnabled }, - { "glIsTexture", (void *) ::glIsTexture }, - { "glLineWidth", (void *) ::glLineWidth }, - { "glPixelStorei", (void *) ::glPixelStorei }, - { "glPolygonOffset", (void *) ::glPolygonOffset }, - { "glReadPixels", (void *) ::glReadPixels }, - { "glScissor", (void *) ::glScissor }, - { "glStencilFunc", (void *) ::glStencilFunc }, - { "glStencilMask", (void *) ::glStencilMask }, - { "glStencilOp", (void *) ::glStencilOp }, - { "glTexImage2D", (void *) ::glTexImage2D }, - { "glTexParameterf", (void *) ::glTexParameterf }, - { "glTexParameterfv", (void *) ::glTexParameterfv }, - { "glTexParameteri", (void *) ::glTexParameteri }, - { "glTexParameteriv", (void *) ::glTexParameteriv }, - { "glTexSubImage2D", (void *) ::glTexSubImage2D }, - { "glViewport", (void *) ::glViewport }, - - { "glActiveTexture", (void *) ::glActiveTexture }, - { "glAttachShader", (void *) ::glAttachShader }, - { "glBindAttribLocation", (void *) ::glBindAttribLocation }, - { "glBindBuffer", (void *) ::glBindBuffer }, - { "glBindFramebuffer", (void *) ::glBindFramebuffer }, - { "glBindRenderbuffer", (void *) ::glBindRenderbuffer }, - { "glBlendColor", (void *) ::glBlendColor }, - { "glBlendEquation", (void *) ::glBlendEquation }, - { "glBlendEquationSeparate", (void *) ::glBlendEquationSeparate }, - { "glBlendFuncSeparate", (void *) ::glBlendFuncSeparate }, - { "glBufferData", (void *) ::glBufferData }, - { "glBufferSubData", (void *) ::glBufferSubData }, - { "glCheckFramebufferStatus", (void *) ::glCheckFramebufferStatus }, - { "glCompileShader", (void *) ::glCompileShader }, - { "glCompressedTexImage2D", (void *) ::glCompressedTexImage2D }, - { "glCompressedTexSubImage2D", (void *) ::glCompressedTexSubImage2D }, - { "glCreateProgram", (void *) ::glCreateProgram }, - { "glCreateShader", (void *) ::glCreateShader }, - { "glDeleteBuffers", (void *) ::glDeleteBuffers }, - { "glDeleteFramebuffers", (void *) ::glDeleteFramebuffers }, - { "glDeleteProgram", (void *) ::glDeleteProgram }, - { "glDeleteRenderbuffers", (void *) ::glDeleteRenderbuffers }, - { "glDeleteShader", (void *) ::glDeleteShader }, - { "glDetachShader", (void *) ::glDetachShader }, - { "glDisableVertexAttribArray", (void *) ::glDisableVertexAttribArray }, - { "glEnableVertexAttribArray", (void *) ::glEnableVertexAttribArray }, - { "glFramebufferRenderbuffer", (void *) ::glFramebufferRenderbuffer }, - { "glFramebufferTexture2D", (void *) ::glFramebufferTexture2D }, - { "glGenBuffers", (void *) ::glGenBuffers }, - { "glGenerateMipmap", (void *) ::glGenerateMipmap }, - { "glGenFramebuffers", (void *) ::glGenFramebuffers }, - { "glGenRenderbuffers", (void *) ::glGenRenderbuffers }, - { "glGetActiveAttrib", (void *) ::glGetActiveAttrib }, - { "glGetActiveUniform", (void *) ::glGetActiveUniform }, - { "glGetAttachedShaders", (void *) ::glGetAttachedShaders }, - { "glGetAttribLocation", (void *) ::glGetAttribLocation }, - { "glGetBufferParameteriv", (void *) ::glGetBufferParameteriv }, - { "glGetFramebufferAttachmentParameteriv", (void *) ::glGetFramebufferAttachmentParameteriv }, - { "glGetProgramiv", (void *) ::glGetProgramiv }, - { "glGetProgramInfoLog", (void *) ::glGetProgramInfoLog }, - { "glGetRenderbufferParameteriv", (void *) ::glGetRenderbufferParameteriv }, - { "glGetShaderiv", (void *) ::glGetShaderiv }, - { "glGetShaderInfoLog", (void *) ::glGetShaderInfoLog }, - { "glGetShaderPrecisionFormat", (void *) ::glGetShaderPrecisionFormat }, - { "glGetShaderSource", (void *) ::glGetShaderSource }, - { "glGetUniformfv", (void *) ::glGetUniformfv }, - { "glGetUniformiv", (void *) ::glGetUniformiv }, - { "glGetUniformLocation", (void *) ::glGetUniformLocation }, - { "glGetVertexAttribfv", (void *) ::glGetVertexAttribfv }, - { "glGetVertexAttribiv", (void *) ::glGetVertexAttribiv }, - { "glGetVertexAttribPointerv", (void *) ::glGetVertexAttribPointerv }, - { "glIsBuffer", (void *) ::glIsBuffer }, - { "glIsFramebuffer", (void *) ::glIsFramebuffer }, - { "glIsProgram", (void *) ::glIsProgram }, - { "glIsRenderbuffer", (void *) ::glIsRenderbuffer }, - { "glIsShader", (void *) ::glIsShader }, - { "glLinkProgram", (void *) ::glLinkProgram }, - { "glReleaseShaderCompiler", (void *) ::glReleaseShaderCompiler }, - { "glRenderbufferStorage", (void *) ::glRenderbufferStorage }, - { "glSampleCoverage", (void *) ::glSampleCoverage }, - { "glShaderBinary", (void *) ::glShaderBinary }, - { "glShaderSource", (void *) ::glShaderSource }, - { "glStencilFuncSeparate", (void *) ::glStencilFuncSeparate }, - { "glStencilMaskSeparate", (void *) ::glStencilMaskSeparate }, - { "glStencilOpSeparate", (void *) ::glStencilOpSeparate }, - { "glUniform1f", (void *) ::glUniform1f }, - { "glUniform1fv", (void *) ::glUniform1fv }, - { "glUniform1i", (void *) ::glUniform1i }, - { "glUniform1iv", (void *) ::glUniform1iv }, - { "glUniform2f", (void *) ::glUniform2f }, - { "glUniform2fv", (void *) ::glUniform2fv }, - { "glUniform2i", (void *) ::glUniform2i }, - { "glUniform2iv", (void *) ::glUniform2iv }, - { "glUniform3f", (void *) ::glUniform3f }, - { "glUniform3fv", (void *) ::glUniform3fv }, - { "glUniform3i", (void *) ::glUniform3i }, - { "glUniform3iv", (void *) ::glUniform3iv }, - { "glUniform4f", (void *) ::glUniform4f }, - { "glUniform4fv", (void *) ::glUniform4fv }, - { "glUniform4i", (void *) ::glUniform4i }, - { "glUniform4iv", (void *) ::glUniform4iv }, - { "glUniformMatrix2fv", (void *) ::glUniformMatrix2fv }, - { "glUniformMatrix3fv", (void *) ::glUniformMatrix3fv }, - { "glUniformMatrix4fv", (void *) ::glUniformMatrix4fv }, - { "glUseProgram", (void *) ::glUseProgram }, - { "glValidateProgram", (void *) ::glValidateProgram }, - { "glVertexAttrib1f", (void *) ::glVertexAttrib1f }, - { "glVertexAttrib1fv", (void *) ::glVertexAttrib1fv }, - { "glVertexAttrib2f", (void *) ::glVertexAttrib2f }, - { "glVertexAttrib2fv", (void *) ::glVertexAttrib2fv }, - { "glVertexAttrib3f", (void *) ::glVertexAttrib3f }, - { "glVertexAttrib3fv", (void *) ::glVertexAttrib3fv }, - { "glVertexAttrib4f", (void *) ::glVertexAttrib4f }, - { "glVertexAttrib4fv", (void *) ::glVertexAttrib4fv }, - { "glVertexAttribPointer", (void *) ::glVertexAttribPointer }, - - { "glClearDepthf", (void *) ::glClearDepthf }, - { "glDepthRangef", (void *) ::glDepthRangef } - }; - for (size_t i = 0; i < sizeof(standardFuncs) / sizeof(StdFunc); ++i) - if (!qstrcmp(procName, standardFuncs[i].name)) - return reinterpret_cast<QFunctionPointer>(standardFuncs[i].func); -#else - procAddress = reinterpret_cast<QFunctionPointer>(QWindowsEGLStaticContext::libGLESv2.resolve(procName)); -#endif -} - - if (QWindowsContext::verbose > 1) - qCDebug(lcQpaGl) << __FUNCTION__ << procName << QWindowsEGLStaticContext::libEGL.eglGetCurrentContext() << "returns" << procAddress; - - return procAddress; -} - -static QVector<EGLint> createConfigAttributesFromFormat(const QSurfaceFormat &format) -{ - int redSize = format.redBufferSize(); - int greenSize = format.greenBufferSize(); - int blueSize = format.blueBufferSize(); - int alphaSize = format.alphaBufferSize(); - int depthSize = format.depthBufferSize(); - int stencilSize = format.stencilBufferSize(); - int sampleCount = format.samples(); - - QVector<EGLint> configAttributes; - configAttributes.reserve(16); - - configAttributes.append(EGL_RED_SIZE); - configAttributes.append(redSize > 0 ? redSize : 0); - - configAttributes.append(EGL_GREEN_SIZE); - configAttributes.append(greenSize > 0 ? greenSize : 0); - - configAttributes.append(EGL_BLUE_SIZE); - configAttributes.append(blueSize > 0 ? blueSize : 0); - - configAttributes.append(EGL_ALPHA_SIZE); - configAttributes.append(alphaSize > 0 ? alphaSize : 0); - - configAttributes.append(EGL_DEPTH_SIZE); - configAttributes.append(depthSize > 0 ? depthSize : 0); - - configAttributes.append(EGL_STENCIL_SIZE); - configAttributes.append(stencilSize > 0 ? stencilSize : 0); - - configAttributes.append(EGL_SAMPLES); - configAttributes.append(sampleCount > 0 ? sampleCount : 0); - - configAttributes.append(EGL_SAMPLE_BUFFERS); - configAttributes.append(sampleCount > 0); - - return configAttributes; -} - -static bool reduceConfigAttributes(QVector<EGLint> *configAttributes) -{ - int i = -1; - - i = configAttributes->indexOf(EGL_SWAP_BEHAVIOR); - if (i >= 0) { - configAttributes->remove(i,2); - } - - i = configAttributes->indexOf(EGL_BUFFER_SIZE); - if (i >= 0) { - if (configAttributes->at(i+1) == 16) { - configAttributes->remove(i,2); - return true; - } - } - - i = configAttributes->indexOf(EGL_SAMPLES); - if (i >= 0) { - EGLint value = configAttributes->value(i+1, 0); - if (value > 1) - configAttributes->replace(i+1, qMin(EGLint(16), value / 2)); - else - configAttributes->remove(i, 2); - return true; - } - - i = configAttributes->indexOf(EGL_SAMPLE_BUFFERS); - if (i >= 0) { - configAttributes->remove(i,2); - return true; - } - - i = configAttributes->indexOf(EGL_ALPHA_SIZE); - if (i >= 0) { - configAttributes->remove(i,2); -#if defined(EGL_BIND_TO_TEXTURE_RGBA) && defined(EGL_BIND_TO_TEXTURE_RGB) - i = configAttributes->indexOf(EGL_BIND_TO_TEXTURE_RGBA); - if (i >= 0) { - configAttributes->replace(i,EGL_BIND_TO_TEXTURE_RGB); - configAttributes->replace(i+1,true); - - } -#endif - return true; - } - - i = configAttributes->indexOf(EGL_STENCIL_SIZE); - if (i >= 0) { - if (configAttributes->at(i + 1) > 1) - configAttributes->replace(i + 1, 1); - else - configAttributes->remove(i, 2); - return true; - } - - i = configAttributes->indexOf(EGL_DEPTH_SIZE); - if (i >= 0) { - if (configAttributes->at(i + 1) > 1) - configAttributes->replace(i + 1, 1); - else - configAttributes->remove(i, 2); - return true; - } -#ifdef EGL_BIND_TO_TEXTURE_RGB - i = configAttributes->indexOf(EGL_BIND_TO_TEXTURE_RGB); - if (i >= 0) { - configAttributes->remove(i,2); - return true; - } -#endif - - return false; -} - -EGLConfig QWindowsEGLContext::chooseConfig(const QSurfaceFormat &format) -{ - QVector<EGLint> configureAttributes = createConfigAttributesFromFormat(format); - configureAttributes.append(EGL_SURFACE_TYPE); - configureAttributes.append(EGL_WINDOW_BIT); - configureAttributes.append(EGL_RENDERABLE_TYPE); - configureAttributes.append(EGL_OPENGL_ES2_BIT); - configureAttributes.append(EGL_NONE); - - EGLDisplay display = m_staticContext->display(); - EGLConfig cfg = nullptr; - do { - // Get the number of matching configurations for this set of properties. - EGLint matching = 0; - if (!QWindowsEGLStaticContext::libEGL.eglChooseConfig(display, configureAttributes.constData(), nullptr, 0, &matching) || !matching) - continue; - - // Fetch all of the matching configurations and find the - // first that matches the pixel format we wanted. - int i = configureAttributes.indexOf(EGL_RED_SIZE); - int confAttrRed = configureAttributes.at(i+1); - i = configureAttributes.indexOf(EGL_GREEN_SIZE); - int confAttrGreen = configureAttributes.at(i+1); - i = configureAttributes.indexOf(EGL_BLUE_SIZE); - int confAttrBlue = configureAttributes.at(i+1); - i = configureAttributes.indexOf(EGL_ALPHA_SIZE); - int confAttrAlpha = i == -1 ? 0 : configureAttributes.at(i+1); - - QVector<EGLConfig> configs(matching); - QWindowsEGLStaticContext::libEGL.eglChooseConfig(display, configureAttributes.constData(), configs.data(), configs.size(), &matching); - if (!cfg && matching > 0) - cfg = configs.constFirst(); - - EGLint red = 0; - EGLint green = 0; - EGLint blue = 0; - EGLint alpha = 0; - for (const EGLConfig &config : configs) { - if (confAttrRed) - QWindowsEGLStaticContext::libEGL.eglGetConfigAttrib(display, config, EGL_RED_SIZE, &red); - if (confAttrGreen) - QWindowsEGLStaticContext::libEGL.eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &green); - if (confAttrBlue) - QWindowsEGLStaticContext::libEGL.eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blue); - if (confAttrAlpha) - QWindowsEGLStaticContext::libEGL.eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &alpha); - - if (red == confAttrRed && green == confAttrGreen - && blue == confAttrBlue && alpha == confAttrAlpha) - return config; - } - } while (reduceConfigAttributes(&configureAttributes)); - - if (!cfg) - qWarning("Cannot find EGLConfig, returning null config"); - - return cfg; -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowseglcontext.h b/src/plugins/platforms/windows/qwindowseglcontext.h deleted file mode 100644 index d96e266159..0000000000 --- a/src/plugins/platforms/windows/qwindowseglcontext.h +++ /dev/null @@ -1,176 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWINDOWSEGLCONTEXT_H -#define QWINDOWSEGLCONTEXT_H - -#include "qwindowsopenglcontext.h" -#include "qwindowsopengltester.h" -#include <EGL/egl.h> - -QT_BEGIN_NAMESPACE - -struct QWindowsLibEGL -{ - bool init(); - - EGLint (EGLAPIENTRY * eglGetError)(void); - EGLDisplay (EGLAPIENTRY * eglGetDisplay)(EGLNativeDisplayType display_id); - EGLBoolean (EGLAPIENTRY * eglInitialize)(EGLDisplay dpy, EGLint *major, EGLint *minor); - EGLBoolean (EGLAPIENTRY * eglTerminate)(EGLDisplay dpy); - EGLBoolean (EGLAPIENTRY * eglChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list, - EGLConfig *configs, EGLint config_size, - EGLint *num_config); - EGLBoolean (EGLAPIENTRY * eglGetConfigAttrib)(EGLDisplay dpy, EGLConfig config, - EGLint attribute, EGLint *value); - EGLSurface (EGLAPIENTRY * eglCreateWindowSurface)(EGLDisplay dpy, EGLConfig config, - EGLNativeWindowType win, - const EGLint *attrib_list); - EGLSurface (EGLAPIENTRY * eglCreatePbufferSurface)(EGLDisplay dpy, EGLConfig config, - const EGLint *attrib_list); - EGLBoolean (EGLAPIENTRY * eglDestroySurface)(EGLDisplay dpy, EGLSurface surface); - EGLBoolean (EGLAPIENTRY * eglBindAPI)(EGLenum api); - EGLBoolean (EGLAPIENTRY * eglSwapInterval)(EGLDisplay dpy, EGLint interval); - EGLContext (EGLAPIENTRY * eglCreateContext)(EGLDisplay dpy, EGLConfig config, - EGLContext share_context, - const EGLint *attrib_list); - EGLBoolean (EGLAPIENTRY * eglDestroyContext)(EGLDisplay dpy, EGLContext ctx); - EGLBoolean (EGLAPIENTRY * eglMakeCurrent)(EGLDisplay dpy, EGLSurface draw, - EGLSurface read, EGLContext ctx); - EGLContext (EGLAPIENTRY * eglGetCurrentContext)(void); - EGLSurface (EGLAPIENTRY * eglGetCurrentSurface)(EGLint readdraw); - EGLDisplay (EGLAPIENTRY * eglGetCurrentDisplay)(void); - EGLBoolean (EGLAPIENTRY * eglSwapBuffers)(EGLDisplay dpy, EGLSurface surface); - QFunctionPointer (EGLAPIENTRY *eglGetProcAddress)(const char *procname); - - EGLDisplay (EGLAPIENTRY * eglGetPlatformDisplayEXT)(EGLenum platform, void *native_display, const EGLint *attrib_list); - -private: -#if !defined(QT_STATIC) || defined(QT_OPENGL_DYNAMIC) - void *resolve(const char *name); - HMODULE m_lib; -#endif -}; - -struct QWindowsLibGLESv2 -{ - bool init(); - -#if !defined(QT_STATIC) || defined(QT_OPENGL_DYNAMIC) - void *moduleHandle() const { return m_lib; } -#else - void *moduleHandle() const { return nullptr; } -#endif - - const GLubyte * (APIENTRY * glGetString)(GLenum name); - -#if !defined(QT_STATIC) || defined(QT_OPENGL_DYNAMIC) - void *resolve(const char *name); -private: - HMODULE m_lib; -#endif -}; - -class QWindowsEGLStaticContext : public QWindowsStaticOpenGLContext -{ - Q_DISABLE_COPY_MOVE(QWindowsEGLStaticContext) - -public: - static QWindowsEGLStaticContext *create(QWindowsOpenGLTester::Renderers preferredType); - ~QWindowsEGLStaticContext() override; - - EGLDisplay display() const { return m_display; } - - QWindowsOpenGLContext *createContext(QOpenGLContext *context) override; - void *moduleHandle() const override { return libGLESv2.moduleHandle(); } - QOpenGLContext::OpenGLModuleType moduleType() const override { return QOpenGLContext::LibGLES; } - - void *createWindowSurface(void *nativeWindow, void *nativeConfig, int *err) override; - void destroyWindowSurface(void *nativeSurface) override; - - QSurfaceFormat formatFromConfig(EGLDisplay display, EGLConfig config, const QSurfaceFormat &referenceFormat); - - static QWindowsLibEGL libEGL; - static QWindowsLibGLESv2 libGLESv2; - -private: - explicit QWindowsEGLStaticContext(EGLDisplay display); - static bool initializeAngle(QWindowsOpenGLTester::Renderers preferredType, HDC dc, - EGLDisplay *display, EGLint *major, EGLint *minor); - - const EGLDisplay m_display; -}; - -class QWindowsEGLContext : public QWindowsOpenGLContext -{ -public: - QWindowsEGLContext(QWindowsEGLStaticContext *staticContext, - const QSurfaceFormat &format, - QPlatformOpenGLContext *share); - ~QWindowsEGLContext() override; - - bool makeCurrent(QPlatformSurface *surface) override; - void doneCurrent() override; - void swapBuffers(QPlatformSurface *surface) override; - QFunctionPointer getProcAddress(const char *procName) override; - - QSurfaceFormat format() const override { return m_format; } - bool isSharing() const override { return m_shareContext != EGL_NO_CONTEXT; } - bool isValid() const override { return m_eglContext != EGL_NO_CONTEXT; } - - void *nativeContext() const override { return m_eglContext; } - void *nativeDisplay() const override { return m_eglDisplay; } - void *nativeConfig() const override { return m_eglConfig; } - -private: - EGLConfig chooseConfig(const QSurfaceFormat &format); - - QWindowsEGLStaticContext *m_staticContext; - EGLContext m_eglContext; - EGLContext m_shareContext; - EGLDisplay m_eglDisplay; - EGLConfig m_eglConfig; - QSurfaceFormat m_format; - EGLenum m_api = EGL_OPENGL_ES_API; - int m_swapInterval = -1; -}; - -QT_END_NAMESPACE - -#endif // QWINDOWSEGLCONTEXT_H diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 9add72d266..315b65acfe 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -84,10 +84,7 @@ #include <limits.h> -#if QT_CONFIG(opengles2) || defined(QT_OPENGL_DYNAMIC) -# include "qwindowseglcontext.h" -#endif -#if !defined(QT_NO_OPENGL) && !QT_CONFIG(opengles2) +#if !defined(QT_NO_OPENGL) # include "qwindowsglcontext.h" #endif @@ -418,13 +415,6 @@ QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::doCreate() } 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(requestedRenderer); case QWindowsOpenGLTester::SoftwareRasterizer: if (QWindowsStaticOpenGLContext *swCtx = QOpenGLStaticContext::create(true)) return swCtx; @@ -450,17 +440,8 @@ QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::doCreate() return glCtx; } } - if (QWindowsOpenGLTester::Renderers glesRenderers = supportedRenderers & QWindowsOpenGLTester::GlesMask) { - if (QWindowsEGLStaticContext *eglCtx = QWindowsEGLStaticContext::create(glesRenderers)) - return eglCtx; - } return QOpenGLStaticContext::create(true); -#elif QT_CONFIG(opengles2) - QWindowsOpenGLTester::Renderers glesRenderers = QWindowsOpenGLTester::requestedGlesRenderer(); - if (glesRenderers == QWindowsOpenGLTester::InvalidRenderer) - glesRenderers = QWindowsOpenGLTester::supportedRenderers(QWindowsOpenGLTester::AngleRendererD3d11); - return QWindowsEGLStaticContext::create(glesRenderers); -#elif !defined(QT_NO_OPENGL) +#else return QOpenGLStaticContext::create(); #endif } @@ -483,9 +464,7 @@ QPlatformOpenGLContext *QWindowsIntegration::createPlatformOpenGLContext(QOpenGL QOpenGLContext::OpenGLModuleType QWindowsIntegration::openGLModuleType() { -#if QT_CONFIG(opengles2) - return QOpenGLContext::LibGLES; -#elif !defined(QT_OPENGL_DYNAMIC) +#if !defined(QT_OPENGL_DYNAMIC) return QOpenGLContext::LibGL; #else if (const QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext()) diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp index a36da4c780..0cd361516e 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp @@ -60,9 +60,6 @@ QT_BEGIN_NAMESPACE enum ResourceType { RenderingContextType, - EglContextType, - EglDisplayType, - EglConfigType, HandleType, GlHandleType, GetDCType, @@ -74,9 +71,6 @@ static int resourceType(const QByteArray &key) { static const char *names[] = { // match ResourceType "renderingcontext", - "eglcontext", - "egldisplay", - "eglconfig", "handle", "glhandle", "getdc", @@ -207,19 +201,6 @@ void *QWindowsNativeInterface::nativeResourceForContext(const QByteArray &resour return nullptr; } - auto *glcontext = static_cast<QWindowsOpenGLContext *>(context->handle()); - switch (resourceType(resource)) { - case RenderingContextType: // Fall through. - case EglContextType: - return glcontext->nativeContext(); - case EglDisplayType: - return glcontext->nativeDisplay(); - case EglConfigType: - return glcontext->nativeConfig(); - default: - break; - } - qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData()); return nullptr; } diff --git a/src/plugins/platforms/windows/qwindowsopenglcontext.h b/src/plugins/platforms/windows/qwindowsopenglcontext.h index 1416a7e575..6d9c85f738 100644 --- a/src/plugins/platforms/windows/qwindowsopenglcontext.h +++ b/src/plugins/platforms/windows/qwindowsopenglcontext.h @@ -77,7 +77,7 @@ class QWindowsOpenGLContext : public QPlatformOpenGLContext { Q_DISABLE_COPY_MOVE(QWindowsOpenGLContext) public: - // Returns the native context handle (e.g. HGLRC for WGL, EGLContext for EGL). + // Returns the native context handle (e.g. HGLRC for WGL). virtual void *nativeContext() const = 0; // These should be implemented only for some winsys interfaces, for example EGL. diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp index d7d186e804..2d8e51eb3b 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.cpp +++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp @@ -235,39 +235,19 @@ QVariant GpuDescription::toVariant() const return result; } -QWindowsOpenGLTester::Renderer QWindowsOpenGLTester::requestedGlesRenderer() -{ - 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; - } - return QWindowsOpenGLTester::InvalidRenderer; -} - QWindowsOpenGLTester::Renderer QWindowsOpenGLTester::requestedRenderer() { 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_UseOpenGLES)) + qWarning("Qt::AA_UseOpenGLES is no longer supported in Qt 6"); 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 == "angle") + qWarning("QT_OPENGL=angle is no longer supported in Qt 6"); if (requested == "desktop") return QWindowsOpenGLTester::DesktopGl; if (requested == "software") @@ -311,16 +291,11 @@ QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::detectSupportedRenderers(c if (it != srCache->cend()) return *it; - QWindowsOpenGLTester::Renderers result(QWindowsOpenGLTester::AngleRendererD3d11 - | QWindowsOpenGLTester::AngleRendererD3d9 - | QWindowsOpenGLTester::AngleRendererD3d11Warp - | QWindowsOpenGLTester::SoftwareRasterizer); + QWindowsOpenGLTester::Renderers result(QWindowsOpenGLTester::SoftwareRasterizer); // Don't test for GL if explicitly requested or GLES only is requested - if (requested == DesktopGl - || ((requested & GlesMask) == 0 && testDesktopGL())) { - result |= QWindowsOpenGLTester::DesktopGl; - } + if (requested == DesktopGl || testDesktopGL()) + result |= QWindowsOpenGLTester::DesktopGl; QSet<QString> features; // empty by default -> nothing gets disabled if (!qEnvironmentVariableIsSet("QT_NO_OPENGL_BUGLIST")) { @@ -339,19 +314,6 @@ QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::detectSupportedRenderers(c qCDebug(lcQpaGl) << "Disabling Desktop GL: " << gpu; result &= ~QWindowsOpenGLTester::DesktopGl; } - if (features.contains(QStringLiteral("disable_angle"))) { // Qt-specific keyword - qCDebug(lcQpaGl) << "Disabling ANGLE: " << gpu; - result &= ~QWindowsOpenGLTester::GlesMask; - } else { - if (features.contains(QStringLiteral("disable_d3d11"))) { // standard keyword - qCDebug(lcQpaGl) << "Disabling D3D11: " << gpu; - result &= ~QWindowsOpenGLTester::AngleRendererD3d11; - } - if (features.contains(QStringLiteral("disable_d3d9"))) { // Qt-specific - qCDebug(lcQpaGl) << "Disabling D3D9: " << gpu; - result &= ~QWindowsOpenGLTester::AngleRendererD3d9; - } - } if (features.contains(QStringLiteral("disable_rotation"))) { qCDebug(lcQpaGl) << "Disabling rotation: " << gpu; result |= DisableRotationFlag; diff --git a/src/plugins/platforms/windows/qwindowsopengltester.h b/src/plugins/platforms/windows/qwindowsopengltester.h index 9576dfbae0..b9db2afd4b 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.h +++ b/src/plugins/platforms/windows/qwindowsopengltester.h @@ -77,12 +77,6 @@ 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, RendererMask = 0x00FF, DisableRotationFlag = 0x0100, @@ -90,7 +84,6 @@ public: }; Q_DECLARE_FLAGS(Renderers, Renderer) - static Renderer requestedGlesRenderer(); static Renderer requestedRenderer(); static QWindowsOpenGLTester::Renderers supportedRenderers(Renderer requested); diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri index 95ba961df1..b71c24068c 100644 --- a/src/plugins/platforms/windows/windows.pri +++ b/src/plugins/platforms/windows/windows.pri @@ -3,15 +3,14 @@ LIBS += -lwinspool -limm32 -loleaut32 QT_FOR_CONFIG += gui -qtConfig(opengl):!qtConfig(opengles2):!qtConfig(dynamicgl): LIBS *= -lopengl32 +qtConfig(opengl):!qtConfig(dynamicgl): LIBS *= -lopengl32 mingw: QMAKE_USE *= uuid -# For the dialog helpers: + LIBS += -lshlwapi -lwtsapi32 QMAKE_USE_PRIVATE += \ advapi32 \ - d3d9/nolink \ ole32 \ shell32 \ user32 \ @@ -70,20 +69,12 @@ INCLUDEPATH += $$PWD qtConfig(opengl): HEADERS += $$PWD/qwindowsopenglcontext.h -qtConfig(opengles2) { - SOURCES += $$PWD/qwindowseglcontext.cpp - HEADERS += $$PWD/qwindowseglcontext.h -} else: qtConfig(opengl) { +# Only WGL is supported in Qt 6, ANGLE is removed +qtConfig(opengl) { SOURCES += $$PWD/qwindowsglcontext.cpp HEADERS += $$PWD/qwindowsglcontext.h } -# Dynamic GL needs both WGL and EGL -qtConfig(dynamicgl) { - SOURCES += $$PWD/qwindowseglcontext.cpp - HEADERS += $$PWD/qwindowseglcontext.h -} - qtConfig(systemtrayicon) { SOURCES += $$PWD/qwindowssystemtrayicon.cpp HEADERS += $$PWD/qwindowssystemtrayicon.h @@ -121,10 +112,3 @@ RESOURCES += $$PWD/openglblacklists.qrc qtConfig(accessibility): include($$PWD/uiautomation/uiautomation.pri) -qtConfig(combined-angle-lib) { - DEFINES *= LIBEGL_NAME=$${LIBQTANGLE_NAME} - DEFINES *= LIBGLESV2_NAME=$${LIBQTANGLE_NAME} -} else { - DEFINES *= LIBEGL_NAME=$${LIBEGL_NAME} - DEFINES *= LIBGLESV2_NAME=$${LIBGLESV2_NAME} -} |