Windows: Add ANGLE support.
authorFriedemann Kleint <Friedemann.Kleint@nokia.com>
Wed, 23 May 2012 13:07:06 +0000 (15:07 +0200)
committerQt by Nokia <qt-info@nokia.com>
Thu, 31 May 2012 07:13:01 +0000 (09:13 +0200)
- 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>
15 files changed:
dist/changes-5.0.0
mkspecs/features/win32/opengl.prf
mkspecs/win32-msvc11/qmake.conf
mkspecs/win32-msvc2005/qmake.conf
mkspecs/win32-msvc2008/qmake.conf
mkspecs/win32-msvc2010/qmake.conf
src/opengl/qglshaderprogram.cpp
src/plugins/platforms/windows/qwindowscontext.h
src/plugins/platforms/windows/qwindowseglcontext.cpp [new file with mode: 0644]
src/plugins/platforms/windows/qwindowseglcontext.h [new file with mode: 0644]
src/plugins/platforms/windows/qwindowsintegration.cpp
src/plugins/platforms/windows/qwindowswindow.cpp
src/plugins/platforms/windows/qwindowswindow.h
src/plugins/platforms/windows/windows.pro
tools/configure/configureapp.cpp

index f227a12..7b13952 100644 (file)
@@ -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
 ---------------
index 3414781..1b1603c 100644 (file)
@@ -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
+    }
 }
index 1180f3f..3c33182 100644 (file)
@@ -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
index 66f1023..2467dbc 100644 (file)
@@ -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
index e360165..72c9a9e 100644 (file)
@@ -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
index 99645a0..c579257 100644 (file)
@@ -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
index e73e63f..1d87f57 100644 (file)
@@ -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);
index 123eb66..4b221bd 100644 (file)
@@ -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 (file)
index 0000000..316c5b3
--- /dev/null
@@ -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 (file)
index 0000000..a078f02
--- /dev/null
@@ -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
index e0ab113..d31b059 100644 (file)
 #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
 
index 74da8c9..fe38e60 100644 (file)
 #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);
index b558252..045da7d 100644 (file)
 
 #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.
index 0b474ce..3f9eddb 100644 (file)
@@ -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 ) {
index 3e6613f..d584f12 100644 (file)
@@ -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;