From e7f1106edb1ac37d92d7851c44cd8d99f68eaaf4 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 23 May 2012 15:07:06 +0200 Subject: [PATCH] Windows: Add ANGLE support. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add QWindowsEGLContext usable for ANGLE and Windows CE. - Add QWindowsEGLStaticContext containing the display for resource cleanup. - Add EGLSurface to QWindowsWindow. - Add a -angle option specifying the path to the external ANGLE installation to configure, add libraries to the mkspecs. Initial-patch-by: Jabot Corentin Task-number: QTBUG-24207 Change-Id: I5f80b1efb6996da7c5d70aa3720f7801c9e4c6af Reviewed-by: Samuel Rødal Reviewed-by: Girish Ramakrishnan --- dist/changes-5.0.0 | 2 +- mkspecs/features/win32/opengl.prf | 17 +- mkspecs/win32-msvc11/qmake.conf | 1 + mkspecs/win32-msvc2005/qmake.conf | 1 + mkspecs/win32-msvc2008/qmake.conf | 1 + mkspecs/win32-msvc2010/qmake.conf | 1 + src/opengl/qglshaderprogram.cpp | 3 +- .../platforms/windows/qwindowscontext.h | 2 + .../platforms/windows/qwindowseglcontext.cpp | 166 ++++++++++++++++++ .../platforms/windows/qwindowseglcontext.h | 90 ++++++++++ .../platforms/windows/qwindowsintegration.cpp | 41 ++++- .../platforms/windows/qwindowswindow.cpp | 33 ++++ .../platforms/windows/qwindowswindow.h | 22 +++ src/plugins/platforms/windows/windows.pro | 15 +- tools/configure/configureapp.cpp | 30 +++- 15 files changed, 411 insertions(+), 14 deletions(-) create mode 100644 src/plugins/platforms/windows/qwindowseglcontext.cpp create mode 100644 src/plugins/platforms/windows/qwindowseglcontext.h diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0 index f227a123f8..7b13952826 100644 --- a/dist/changes-5.0.0 +++ b/dist/changes-5.0.0 @@ -566,7 +566,7 @@ Qt for Linux/X11 Qt for Windows -------------- * Accessibility framework uses IAccessible2 - +* ANGLE can be used to provide Open GL ES 2.0 (see http://code.google.com/p/angleproject/) Qt for Mac OS X --------------- diff --git a/mkspecs/features/win32/opengl.prf b/mkspecs/features/win32/opengl.prf index 3414781c39..1b1603cf74 100644 --- a/mkspecs/features/win32/opengl.prf +++ b/mkspecs/features/win32/opengl.prf @@ -6,6 +6,19 @@ wince* { include(../unix/opengl.prf) } else { - QMAKE_LIBS += $$QMAKE_LIBS_OPENGL - QMAKE_LFLAGS += $$QMAKE_LFLAGS_OPENGL + contains(QT_CONFIG, opengles2) { +# For Desktop, use the ANGLE library location passed on from configure. + INCLUDEPATH += $$QMAKE_INCDIR_OPENGL_ES2 + LIBS += $$QMAKE_LIBS_OPENGL_ES2 + CONFIG(debug, debug|release) { + QMAKE_LIBDIR += $$QMAKE_LIBDIR_OPENGL_ES2_DEBUG + } else { + QMAKE_LIBDIR += $$QMAKE_LIBDIR_OPENGL_ES2_RELEASE + } + DEFINES += QT_OPENGL_ES_2 QT_OPENGL_ES_2_ANGLE + QT_CONFIG -= opengl + } else { + QMAKE_LIBS += $$QMAKE_LIBS_OPENGL + QMAKE_LFLAGS += $$QMAKE_LFLAGS_OPENGL + } } diff --git a/mkspecs/win32-msvc11/qmake.conf b/mkspecs/win32-msvc11/qmake.conf index 1180f3fb2f..3c33182e8c 100644 --- a/mkspecs/win32-msvc11/qmake.conf +++ b/mkspecs/win32-msvc11/qmake.conf @@ -69,6 +69,7 @@ QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib winspool.lib ws2_32.lib ole32.lib user32.lib advapi32.lib QMAKE_LIBS_NETWORK = ws2_32.lib QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib +QMAKE_LIBS_OPENGL_ES2 = libEGL.lib libGLESv2.lib gdi32.lib user32.lib QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib QMAKE_LIBS_QT_ENTRY = -lqtmain diff --git a/mkspecs/win32-msvc2005/qmake.conf b/mkspecs/win32-msvc2005/qmake.conf index 66f10236c0..2467dbc163 100644 --- a/mkspecs/win32-msvc2005/qmake.conf +++ b/mkspecs/win32-msvc2005/qmake.conf @@ -67,6 +67,7 @@ QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib winspool.lib ws2_32.lib ole32.lib user32.lib advapi32.lib QMAKE_LIBS_NETWORK = ws2_32.lib QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib +QMAKE_LIBS_OPENGL_ES2 = libEGL.lib libGLESv2.lib gdi32.lib user32.lib QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib QMAKE_LIBS_QT_ENTRY = -lqtmain diff --git a/mkspecs/win32-msvc2008/qmake.conf b/mkspecs/win32-msvc2008/qmake.conf index e360165ce3..72c9a9eaf6 100644 --- a/mkspecs/win32-msvc2008/qmake.conf +++ b/mkspecs/win32-msvc2008/qmake.conf @@ -69,6 +69,7 @@ QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib winspool.lib ws2_32.lib ole32.lib user32.lib advapi32.lib QMAKE_LIBS_NETWORK = ws2_32.lib QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib +QMAKE_LIBS_OPENGL_ES2 = libEGL.lib libGLESv2.lib gdi32.lib user32.lib QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib QMAKE_LIBS_QT_ENTRY = -lqtmain diff --git a/mkspecs/win32-msvc2010/qmake.conf b/mkspecs/win32-msvc2010/qmake.conf index 99645a0a96..c579257f63 100644 --- a/mkspecs/win32-msvc2010/qmake.conf +++ b/mkspecs/win32-msvc2010/qmake.conf @@ -69,6 +69,7 @@ QMAKE_LIBS_CORE = kernel32.lib user32.lib shell32.lib uuid.lib ole32.lib QMAKE_LIBS_GUI = gdi32.lib comdlg32.lib oleaut32.lib imm32.lib winmm.lib winspool.lib ws2_32.lib ole32.lib user32.lib advapi32.lib QMAKE_LIBS_NETWORK = ws2_32.lib QMAKE_LIBS_OPENGL = glu32.lib opengl32.lib gdi32.lib user32.lib +QMAKE_LIBS_OPENGL_ES2 = libEGL.lib libGLESv2.lib gdi32.lib user32.lib QMAKE_LIBS_COMPAT = advapi32.lib shell32.lib comdlg32.lib user32.lib gdi32.lib ws2_32.lib QMAKE_LIBS_QT_ENTRY = -lqtmain diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp index e73e63f6a3..1d87f57c44 100644 --- a/src/opengl/qglshaderprogram.cpp +++ b/src/opengl/qglshaderprogram.cpp @@ -237,7 +237,8 @@ bool QGLShaderPrivate::create() else shader = glCreateShader(GL_FRAGMENT_SHADER); if (!shader) { - qWarning() << "QGLShader: could not create shader"; + qWarning("%s: Could not create shader of type %d.", + Q_FUNC_INFO, int(shaderType)); return false; } shaderGuard = createSharedResourceGuard(context, shader, freeShaderFunc); diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h index 123eb6602d..4b221bdba3 100644 --- a/src/plugins/platforms/windows/qwindowscontext.h +++ b/src/plugins/platforms/windows/qwindowscontext.h @@ -48,6 +48,8 @@ #include #include +struct IBindCtx; + QT_BEGIN_NAMESPACE class QWindow; diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp new file mode 100644 index 0000000000..316c5b3113 --- /dev/null +++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp @@ -0,0 +1,166 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwindowseglcontext.h" +#include "qwindowscontext.h" +#include "qwindowswindow.h" + +#include +#include + +#include + +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. + + \internal + \ingroup qt-lighthouse-win +*/ + +QWindowsEGLStaticContext::QWindowsEGLStaticContext(EGLDisplay display, int version) + : m_display(display), m_version(version) +{ +} + +QWindowsEGLStaticContext *QWindowsEGLStaticContext::create() +{ + const HDC dc = QWindowsContext::instance()->displayContext(); + if (!dc){ + qWarning("%s: No Display", Q_FUNC_INFO); + return 0; + } + + EGLDisplay display = eglGetDisplay((EGLNativeDisplayType)dc); + if (!display) { + qWarning("%s: Could not obtain EGL display", Q_FUNC_INFO); + return 0; + } + + EGLint major; + EGLint minor; + if (!eglInitialize(display, &major, &minor)) { + qWarning("%s: Could not initialize egl display: error %d\n", + Q_FUNC_INFO, eglGetError()); + return 0; + } + if (QWindowsContext::verboseGL) + qDebug("%s: Created EGL display %p v%d.%d", + __FUNCTION__, display, major, minor); + return new QWindowsEGLStaticContext(display, (major << 8) | minor); +} + +QWindowsEGLStaticContext::~QWindowsEGLStaticContext() +{ + if (QWindowsContext::verboseGL) + qDebug("%s: Releasing EGL display %p", __FUNCTION__, m_display); + eglTerminate(m_display); +} + +/*! + \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{http://code.google.com/p/angleproject/wiki/DevSetup}{ANGLE-Project}. + 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 -angle ". + \o Build qtbase and test some examples. + \endlist + + \internal + \ingroup qt-lighthouse-win +*/ + +QWindowsEGLContext::QWindowsEGLContext(const QWindowsEGLStaticContextPtr &staticContext, + const QSurfaceFormat &format, + QPlatformOpenGLContext *share) + : QEGLPlatformContext(format, share, staticContext->display(), EGL_OPENGL_ES_API) + , m_staticContext(staticContext) +{ +} + +QWindowsEGLContext::~QWindowsEGLContext() +{ +} + +bool QWindowsEGLContext::hasThreadedOpenGLCapability() +{ +#ifdef QT_OPENGL_ES_2_ANGLE + return false; +#else + return true; +#endif +} + +EGLSurface QWindowsEGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface) +{ + const QWindowsWindow *window = static_cast(surface); + return window->eglSurfaceHandle(); +} + +bool QWindowsEGLContext::makeCurrent(QPlatformSurface *surface) +{ + bool ok = false; + QWindowsWindow *window = static_cast(surface); + if (EGLSurface eglSurface = window->ensureEglSurfaceHandle(m_staticContext, eglConfig())) { + ok = eglMakeCurrent(eglDisplay(), eglSurface, eglSurface, eglContext()); + if (!ok) + qWarning("%s: eglMakeCurrent() failed, eglError: 0x%x, this: %p \n", + Q_FUNC_INFO, eglGetError(), this); + } + return ok; +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowseglcontext.h b/src/plugins/platforms/windows/qwindowseglcontext.h new file mode 100644 index 0000000000..a078f02db2 --- /dev/null +++ b/src/plugins/platforms/windows/qwindowseglcontext.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINDOWSEGLCONTEXT_H +#define QWINDOWSEGLCONTEXT_H + +#include +#include + +QT_BEGIN_NAMESPACE + +class QWindowsEGLStaticContext +{ + Q_DISABLE_COPY(QWindowsEGLStaticContext) +public: + static QWindowsEGLStaticContext *create(); + ~QWindowsEGLStaticContext(); + + EGLDisplay display() const { return m_display; } + +private: + QWindowsEGLStaticContext(EGLDisplay display, int version); + + const EGLDisplay m_display; + const int m_version; //! majorVersion<<8 + minorVersion +}; + +class QWindowsEGLContext : public QEGLPlatformContext +{ +public: + typedef QSharedPointer QWindowsEGLStaticContextPtr; + + QWindowsEGLContext(const QWindowsEGLStaticContextPtr& staticContext, + const QSurfaceFormat &format, + QPlatformOpenGLContext *share); + + ~QWindowsEGLContext(); + + static bool hasThreadedOpenGLCapability(); + + bool makeCurrent(QPlatformSurface *surface); + +protected: + EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface); + +private: + const QWindowsEGLStaticContextPtr m_staticContext; +}; + +QT_END_NAMESPACE + +#endif // QWINDOWSEGLCONTEXT_H diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index e0ab113647..d31b059445 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -43,7 +43,10 @@ #include "qwindowsbackingstore.h" #include "qwindowswindow.h" #include "qwindowscontext.h" -#ifndef QT_NO_OPENGL +#if defined(QT_OPENGL_ES_2) +# include "qwindowseglcontext.h" +# include +#elif !defined(QT_NO_OPENGL) # include "qwindowsglcontext.h" #endif #include "qwindowsscreen.h" @@ -148,9 +151,19 @@ void *QWindowsNativeInterface::nativeResourceForContext(const QByteArray &resour qWarning("%s: '%s' requested for null context or context without handle.", __FUNCTION__, resource.constData()); return 0; } +#ifdef QT_OPENGL_ES_2 + QWindowsEGLContext *windowsEglContext = static_cast(context->handle()); + if (resource == QByteArrayLiteral("eglDisplay")) + return windowsEglContext->eglDisplay(); + if (resource == QByteArrayLiteral("eglContext")) + return windowsEglContext->eglContext(); + if (resource == QByteArrayLiteral("eglConfig")) + return windowsEglContext->eglConfig(); +#else // QT_OPENGL_ES_2 QWindowsGLContext *windowsContext = static_cast(context->handle()); - if (resource == "renderingContext") + if (resource == QByteArrayLiteral("renderingContext")) return windowsContext->renderingContext(); +#endif // !QT_OPENGL_ES_2 qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData()); return 0; @@ -181,7 +194,9 @@ void *QWindowsNativeInterface::createMessageWindow(const QString &classNameTempl struct QWindowsIntegrationPrivate { -#ifndef QT_NO_OPENGL +#if defined(QT_OPENGL_ES_2) + typedef QSharedPointer QEGLStaticContextPtr; +#elif !defined(QT_NO_OPENGL) typedef QSharedPointer QOpenGLStaticContextPtr; #endif @@ -196,7 +211,9 @@ struct QWindowsIntegrationPrivate #endif QWindowsDrag m_drag; QWindowsGuiEventDispatcher *m_eventDispatcher; -#ifndef QT_NO_OPENGL +#if defined(QT_OPENGL_ES_2) + QEGLStaticContextPtr m_staticEGLContext; +#elif !defined(QT_NO_OPENGL) QOpenGLStaticContextPtr m_staticOpenGLContext; #endif QWindowsInputContext m_inputContext; @@ -242,8 +259,12 @@ bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) co case OpenGL: return true; case ThreadedOpenGL: +# ifdef QT_OPENGL_ES_2 + return QWindowsEGLContext::hasThreadedOpenGLCapability(); +# else return true; -#endif +# endif // QT_OPENGL_ES_2 +#endif // !QT_NO_OPENGL default: return QPlatformIntegration::hasCapability(cap); } @@ -293,6 +314,15 @@ QPlatformOpenGLContext { if (QWindowsContext::verboseIntegration) qDebug() << __FUNCTION__ << context->format(); +#ifdef QT_OPENGL_ES_2 + if (d->m_staticEGLContext.isNull()) { + QWindowsEGLStaticContext *staticContext = QWindowsEGLStaticContext::create(); + if (!staticContext) + return 0; + d->m_staticEGLContext = QSharedPointer(staticContext); + } + return new QWindowsEGLContext(d->m_staticEGLContext, context->format(), context->handle()); +#else // QT_OPENGL_ES_2 if (d->m_staticOpenGLContext.isNull()) d->m_staticOpenGLContext = QSharedPointer(QOpenGLStaticContext::create()); @@ -300,6 +330,7 @@ QPlatformOpenGLContext if (result->isValid()) return result.take(); return 0; +#endif // !QT_OPENGL_ES_2 } #endif // !QT_NO_OPENGL diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 74da8c9265..fe38e60697 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -46,6 +46,10 @@ #include "qwindowsscreen.h" #include "qwindowscursor.h" +#ifdef QT_OPENGL_ES_2 +# include "qwindowseglcontext.h" +#endif + #include #include #include @@ -644,6 +648,9 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) : m_cursor(QWindowsScreen::screenOf(aWindow)->windowsCursor()->standardWindowCursor()), m_dropTarget(0), m_savedStyle(0) +#ifdef QT_OPENGL_ES_2 + , m_eglSurface(0) +#endif { if (aWindow->surfaceType() == QWindow::OpenGLSurface) setFlag(OpenGLSurface); @@ -676,6 +683,15 @@ void QWindowsWindow::destroyWindow() if (m_data.hwnd) { // Stop event dispatching before Window is destroyed. unregisterDropSite(); QWindowsContext::instance()->removeWindow(m_data.hwnd); +#ifdef QT_OPENGL_ES_2 + if (m_eglSurface) { + if (QWindowsContext::verboseGL) + qDebug("%s: Freeing EGL surface %p, this = %p", + __FUNCTION__, m_eglSurface, this); + eglDestroySurface(m_staticEglContext->display(), m_eglSurface); + m_eglSurface = 0; + } +#endif if (m_data.hwnd != GetDesktopWindow()) DestroyWindow(m_data.hwnd); m_data.hwnd = 0; @@ -1454,6 +1470,23 @@ void QWindowsWindow::setEnabled(bool enabled) setStyle(newStyle); } +#ifdef QT_OPENGL_ES_2 +EGLSurface QWindowsWindow::ensureEglSurfaceHandle(const QWindowsWindow::QWindowsEGLStaticContextPtr &staticContext, EGLConfig config) +{ + if (!m_eglSurface) { + m_staticEglContext = staticContext; + m_eglSurface = eglCreateWindowSurface(staticContext->display(), config, (EGLNativeWindowType)m_data.hwnd, NULL); + if (m_eglSurface == EGL_NO_SURFACE) + qWarning("%s: Could not create the egl surface (eglCreateWindowSurface failed): error = 0x%x\n", + Q_FUNC_INFO, eglGetError()); + if (QWindowsContext::verboseGL) + qDebug("%s: Created EGL surface %p, this = %p", + __FUNCTION__, m_eglSurface, this); + } + return m_eglSurface; +} +#endif // QT_OPENGL_ES_2 + QByteArray QWindowsWindow::debugWindowFlags(Qt::WindowFlags wf) { const int iwf = int(wf); diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index b558252968..045da7d355 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -50,11 +50,20 @@ #include +#ifdef QT_OPENGL_ES_2 +# include +# include +#endif + QT_BEGIN_NAMESPACE class QWindowsOleDropTarget; class QDebug; +#ifdef QT_OPENGL_ES_2 +class QWindowsEGLStaticContext; +#endif + struct QWindowsGeometryHint { QWindowsGeometryHint() {} @@ -101,6 +110,10 @@ struct QWindowCreationContext class QWindowsWindow : public QPlatformWindow { public: +#ifdef QT_OPENGL_ES_2 + typedef QSharedPointer QWindowsEGLStaticContextPtr; +#endif + enum Flags { WithinWmPaint = 0x1, @@ -160,6 +173,11 @@ public: Qt::WindowState windowState_sys() const; Qt::WindowStates windowStates_sys() const; +#ifdef QT_OPENGL_ES_2 + EGLSurface eglSurfaceHandle() const { return m_eglSurface;} + EGLSurface ensureEglSurfaceHandle(const QWindowsEGLStaticContextPtr &staticContext, EGLConfig config); +#endif + inline unsigned style() const { return GetWindowLongPtr(m_data.hwnd, GWL_STYLE); } void setStyle(unsigned s) const; @@ -236,6 +254,10 @@ private: QWindowsOleDropTarget *m_dropTarget; unsigned m_savedStyle; QRect m_savedFrameGeometry; +#ifdef QT_OPENGL_ES_2 + EGLSurface m_eglSurface; + QSharedPointer m_staticEglContext; +#endif }; // Conveniences for window frames. diff --git a/src/plugins/platforms/windows/windows.pro b/src/plugins/platforms/windows/windows.pro index 0b474ce24e..3f9eddbcbf 100644 --- a/src/plugins/platforms/windows/windows.pro +++ b/src/plugins/platforms/windows/windows.pro @@ -11,7 +11,9 @@ QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms # Note: OpenGL32 must precede Gdi32 as it overwrites some functions. LIBS *= -lole32 !wince*:LIBS *= -lgdi32 -luser32 -lwinspool -limm32 -lwinmm -loleaut32 -contains(QT_CONFIG, opengl):LIBS *= -lopengl32 + +contains(QT_CONFIG, opengl):!contains(QT_CONFIG, opengles2):LIBS *= -lopengl32 + win32-g++*: LIBS *= -luuid # For the dialog helpers: !wince*:LIBS *= -lshlwapi -lshell32 @@ -76,9 +78,14 @@ HEADERS += \ qwindowsservices.h \ qplatformfunctions_wince.h -contains(QT_CONFIG, opengl) { - SOURCES += qwindowsglcontext.cpp - HEADERS += qwindowsglcontext.h +contains(QT_CONFIG, opengles2) { + SOURCES += qwindowseglcontext.cpp + HEADERS += qwindowseglcontext.h +} else { + contains(QT_CONFIG, opengl) { + SOURCES += qwindowsglcontext.cpp + HEADERS += qwindowsglcontext.h + } } !contains( DEFINES, QT_NO_CLIPBOARD ) { diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 3e6613f066..d584f120d4 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -654,6 +654,16 @@ void Configure::parseCmdLine() dictionary[ "DONE" ] = "error"; break; } + // External location of ANGLE library (Open GL ES 2) + } else if (configCmdLine.at(i) == QStringLiteral("-angle")) { + if (++i == argCount) + break; + const QFileInfo fi(configCmdLine.at(i)); + if (!fi.isDir()) { + cout << "Argument passed to -angle option is not a directory." << endl; + dictionary.insert(QStringLiteral("DONE"), QStringLiteral( "error")); + } + dictionary.insert(QStringLiteral("ANGLE_DIR"), fi.absoluteFilePath()); } // OpenVG Support ------------------------------------------- @@ -1608,7 +1618,7 @@ bool Configure::displayHelp() desc("PLUGIN_MANIFESTS", "no", "-no-plugin-manifests", "Do not embed manifests in plugins."); desc("PLUGIN_MANIFESTS", "yes", "-plugin-manifests", "Embed manifests in plugins.\n"); - + desc( "-angle ", "Use ANGLE library from location .\n"); #if !defined(EVAL) desc("BUILD_QMAKE", "no", "-no-qmake", "Do not compile qmake."); desc("BUILD_QMAKE", "yes", "-qmake", "Compile qmake.\n"); @@ -2713,6 +2723,19 @@ void Configure::generateQConfigPri() if (!dictionary["QT_NAMESPACE"].isEmpty()) configStream << "#namespaces" << endl << "QT_NAMESPACE = " << dictionary["QT_NAMESPACE"] << endl; + if (dictionary.value(QStringLiteral("OPENGL_ES_2")) == QStringLiteral("yes")) { + const QString angleDir = dictionary.value(QStringLiteral("ANGLE_DIR")); + if (!angleDir.isEmpty()) { + configStream + << "QMAKE_INCDIR_OPENGL_ES2 = " + << fixSeparators(angleDir + QStringLiteral("/include"), true) << '\n' + << "QMAKE_LIBDIR_OPENGL_ES2_DEBUG = " + << fixSeparators(angleDir + QStringLiteral("/lib/Debug"), true) << '\n' + << "QMAKE_LIBDIR_OPENGL_ES2_RELEASE = " + << fixSeparators(angleDir + QStringLiteral("/lib/Release"), true) + '\n'; + } + } + configStream.flush(); configFile.close(); } @@ -3080,6 +3103,11 @@ void Configure::displayConfig() sout << "SSE2 support................" << dictionary[ "SSE2" ] << endl; sout << "IWMMXT support.............." << dictionary[ "IWMMXT" ] << endl; sout << "OpenGL support.............." << dictionary[ "OPENGL" ] << endl; + if (dictionary.value(QStringLiteral("OPENGL_ES_2")) == QStringLiteral("yes")) { + const QString angleDir = dictionary.value(QStringLiteral("ANGLE_DIR")); + if (!angleDir.isEmpty()) + sout << "ANGLE......................." << QDir::toNativeSeparators(angleDir) << endl; + } sout << "OpenVG support.............." << dictionary[ "OPENVG" ] << endl; sout << "OpenSSL support............." << dictionary[ "OPENSSL" ] << endl; sout << "QtDBus support.............." << dictionary[ "DBUS" ] << endl;