summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>2012-05-23 15:07:06 +0200
committerQt by Nokia <qt-info@nokia.com>2012-05-31 09:13:01 +0200
commite7f1106edb1ac37d92d7851c44cd8d99f68eaaf4 (patch)
treeb4d01b3ca52a0ff8a8ec0aa1803beeac78196508
parentb63e101a90b677dcb192214aef35a107620c5f3c (diff)
Windows: Add ANGLE support.
- 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 <corentinjabot@gmail.com> Task-number: QTBUG-24207 Change-Id: I5f80b1efb6996da7c5d70aa3720f7801c9e4c6af Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com> Reviewed-by: Girish Ramakrishnan <girish.1.ramakrishnan@nokia.com>
-rw-r--r--dist/changes-5.0.02
-rw-r--r--mkspecs/features/win32/opengl.prf17
-rw-r--r--mkspecs/win32-msvc11/qmake.conf1
-rw-r--r--mkspecs/win32-msvc2005/qmake.conf1
-rw-r--r--mkspecs/win32-msvc2008/qmake.conf1
-rw-r--r--mkspecs/win32-msvc2010/qmake.conf1
-rw-r--r--src/opengl/qglshaderprogram.cpp3
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h2
-rw-r--r--src/plugins/platforms/windows/qwindowseglcontext.cpp166
-rw-r--r--src/plugins/platforms/windows/qwindowseglcontext.h90
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp41
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp33
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h22
-rw-r--r--src/plugins/platforms/windows/windows.pro15
-rw-r--r--tools/configure/configureapp.cpp30
15 files changed, 411 insertions, 14 deletions
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 <QtCore/QScopedPointer>
#include <QtCore/QSharedPointer>
+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 <QtCore/QDebug>
+#include <QtGui/QOpenGLContext>
+
+#include <QtPlatformSupport/private/qeglconvenience_p.h>
+
+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 <path>".
+ \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<const QWindowsWindow *>(surface);
+ return window->eglSurfaceHandle();
+}
+
+bool QWindowsEGLContext::makeCurrent(QPlatformSurface *surface)
+{
+ bool ok = false;
+ QWindowsWindow *window = static_cast<QWindowsWindow *>(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 <QtPlatformSupport/private/qeglplatformcontext_p.h>
+#include <QSharedPointer>
+
+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<QWindowsEGLStaticContext> 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 <QtGui/QOpenGLContext>
+#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<QWindowsEGLContext *>(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<QWindowsGLContext *>(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<QWindowsEGLStaticContext> QEGLStaticContextPtr;
+#elif !defined(QT_NO_OPENGL)
typedef QSharedPointer<QOpenGLStaticContext> 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<QWindowsEGLStaticContext>(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>(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 <QtGui/QGuiApplication>
#include <QtGui/QScreen>
#include <QtGui/QWindow>
@@ -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 <qpa/qplatformwindow.h>
+#ifdef QT_OPENGL_ES_2
+# include <QtCore/QSharedPointer>
+# include <EGL/egl.h>
+#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<QWindowsEGLStaticContext> 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<QWindowsEGLStaticContext> 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 <dir>", "Use ANGLE library from location <dir>.\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;