Fixed missing way of choosing EGL renderable type with QSurfaceFormat.
authorSamuel Rødal <samuel.rodal@nokia.com>
Sat, 23 Jun 2012 15:24:37 +0000 (17:24 +0200)
committerQt by Nokia <qt-info@nokia.com>
Tue, 26 Jun 2012 22:46:35 +0000 (00:46 +0200)
This has been long overdue, since EGL now lets you choose between
desktop and ES based OpenGL. We also add OpenVG for those who want to
use raw OpenVG with a QOpenGLContext. The underlying EGL API for using
OpenGL / OpenVG is the same, with eglMakeCurrent() and eglSwapBuffers().

Change-Id: Ib0146b3fde5fe632069ebf99e7712f496ee7ea4d
Reviewed-by: Gunnar Sletta <gunnar.sletta@nokia.com>
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
src/gui/kernel/qsurfaceformat.cpp
src/gui/kernel/qsurfaceformat.h
src/platformsupport/eglconvenience/qeglconvenience.cpp
src/platformsupport/eglconvenience/qeglconvenience_p.h
src/platformsupport/eglconvenience/qeglplatformcontext.cpp

index cc6b621..ecfeb80 100644 (file)
@@ -68,6 +68,7 @@ public:
         , stencilSize(-1)
         , swapBehavior(QSurfaceFormat::DefaultSwapBehavior)
         , numSamples(-1)
+        , renderableType(QSurfaceFormat::DefaultRenderableType)
         , profile(QSurfaceFormat::NoProfile)
         , major(2)
         , minor(0)
@@ -85,6 +86,7 @@ public:
           stencilSize(other->stencilSize),
           swapBehavior(other->swapBehavior),
           numSamples(other->numSamples),
+          renderableType(other->renderableType),
           profile(other->profile),
           major(other->major),
           minor(other->minor)
@@ -101,6 +103,7 @@ public:
     int stencilSize;
     QSurfaceFormat::SwapBehavior swapBehavior;
     int numSamples;
+    QSurfaceFormat::RenderableType renderableType;
     QSurfaceFormat::OpenGLContextProfile profile;
     int major;
     int minor;
@@ -479,6 +482,29 @@ void QSurfaceFormat::setAlphaBufferSize(int size)
 }
 
 /*!
+    Sets the desired renderable type.
+
+    Chooses between desktop OpenGL, OpenGL ES, and OpenVG.
+*/
+void QSurfaceFormat::setRenderableType(RenderableType type)
+{
+    if (d->renderableType != type) {
+        detach();
+        d->renderableType = type;
+    }
+}
+
+/*!
+    Gets the renderable type.
+
+    Chooses between desktop OpenGL, OpenGL ES, and OpenVG.
+*/
+QSurfaceFormat::RenderableType QSurfaceFormat::renderableType() const
+{
+    return d->renderableType;
+}
+
+/*!
     Sets the desired OpenGL context profile.
 
     This setting is ignored if the requested OpenGL version is
index a4224bb..e8972aa 100644 (file)
@@ -68,6 +68,13 @@ public:
         TripleBuffer
     };
 
+    enum RenderableType {
+        DefaultRenderableType = 0x0,
+        OpenGL                = 0x1,
+        OpenGLES              = 0x2,
+        OpenVG                = 0x4
+    };
+
     enum OpenGLContextProfile {
         NoProfile,
         CoreProfile,
@@ -106,6 +113,9 @@ public:
     void setProfile(OpenGLContextProfile profile);
     OpenGLContextProfile profile() const;
 
+    void setRenderableType(RenderableType type);
+    RenderableType renderableType() const;
+
     void setMajorVersion(int majorVersion);
     int majorVersion() const;
 
index 8cfa8cf..ca7a837 100644 (file)
@@ -218,7 +218,17 @@ EGLConfig q_configFromGLFormat(EGLDisplay display, const QSurfaceFormat &format,
     configureAttributes.append(surfaceType);
 
     configureAttributes.append(EGL_RENDERABLE_TYPE);
-    configureAttributes.append(format.majorVersion() == 1 ? EGL_OPENGL_ES_BIT : EGL_OPENGL_ES2_BIT);
+    if (format.renderableType() == QSurfaceFormat::OpenVG)
+        configureAttributes.append(EGL_OPENVG_BIT);
+#ifdef EGL_VERSION_1_4
+    else if (format.renderableType() == QSurfaceFormat::OpenGL)
+        configureAttributes.append(EGL_OPENGL_BIT);
+#endif
+    else if (format.majorVersion() == 1)
+        configureAttributes.append(EGL_OPENGL_ES_BIT);
+    else
+        configureAttributes.append(EGL_OPENGL_ES2_BIT);
+
     configureAttributes.append(EGL_NONE);
 
     do {
@@ -271,7 +281,7 @@ EGLConfig q_configFromGLFormat(EGLDisplay display, const QSurfaceFormat &format,
     return 0;
 }
 
-QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config)
+QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config, const QSurfaceFormat &referenceFormat)
 {
     QSurfaceFormat format;
     EGLint redSize     = 0;
@@ -281,6 +291,7 @@ QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config)
     EGLint depthSize   = 0;
     EGLint stencilSize = 0;
     EGLint sampleCount = 0;
+    EGLint renderableType = 0;
 
     eglGetConfigAttrib(display, config, EGL_RED_SIZE,     &redSize);
     eglGetConfigAttrib(display, config, EGL_GREEN_SIZE,   &greenSize);
@@ -289,6 +300,16 @@ QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config)
     eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE,   &depthSize);
     eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &stencilSize);
     eglGetConfigAttrib(display, config, EGL_SAMPLES,      &sampleCount);
+    eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &renderableType);
+
+    if (referenceFormat.renderableType() == QSurfaceFormat::OpenVG && (renderableType & EGL_OPENVG_BIT))
+        format.setRenderableType(QSurfaceFormat::OpenVG);
+#ifdef EGL_VERSION_1_4
+    else if (referenceFormat.renderableType() == QSurfaceFormat::OpenGL && (renderableType & EGL_OPENGL_BIT))
+        format.setRenderableType(QSurfaceFormat::OpenGL);
+#endif
+    else
+        format.setRenderableType(QSurfaceFormat::OpenGLES);
 
     format.setRedBufferSize(redSize);
     format.setGreenBufferSize(greenSize);
index 3af228a..01483a5 100644 (file)
@@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE
 QVector<EGLint> q_createConfigAttributesFromFormat(const QSurfaceFormat &format);
 bool q_reduceConfigAttributes(QVector<EGLint> *configAttributes);
 EGLConfig q_configFromGLFormat(EGLDisplay display, const QSurfaceFormat &format, bool highestPixelFormat = false, int surfaceType = EGL_WINDOW_BIT);
-QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config);
+QSurfaceFormat q_glFormatFromConfig(EGLDisplay display, const EGLConfig config, const QSurfaceFormat &referenceFormat = QSurfaceFormat());
 bool q_hasEglExtension(EGLDisplay display,const char* extensionName);
 void q_printEglConfig(EGLDisplay display, EGLConfig config);
 
index 2e7baa0..5e7a3b6 100644 (file)
 
 #include <EGL/egl.h>
 
+static inline void bindApi(const QSurfaceFormat &format)
+{
+    if (format.renderableType() == QSurfaceFormat::OpenVG)
+        eglBindAPI(EGL_OPENVG_API);
+#ifdef EGL_VERSION_1_4
+    else if (format.renderableType() == QSurfaceFormat::OpenGL)
+        eglBindAPI(EGL_OPENGL_API);
+#endif
+    else
+        eglBindAPI(EGL_OPENGL_ES_API);
+}
+
 QEGLPlatformContext::QEGLPlatformContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display,
                                          EGLenum eglApi)
     : m_eglDisplay(display)
@@ -61,7 +73,7 @@ QEGLPlatformContext::QEGLPlatformContext(const QSurfaceFormat &format, QPlatform
     contextAttrs.append(format.majorVersion());
     contextAttrs.append(EGL_NONE);
 
-    eglBindAPI(m_eglApi);
+    bindApi(m_format);
     m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig, m_shareContext, contextAttrs.constData());
     if (m_eglContext == EGL_NO_CONTEXT && m_shareContext != EGL_NO_CONTEXT) {
         m_shareContext = 0;
@@ -76,7 +88,7 @@ bool QEGLPlatformContext::makeCurrent(QPlatformSurface *surface)
 #ifdef QEGL_EXTRA_DEBUG
     qWarning("QEglContext::makeCurrent: %p\n",this);
 #endif
-    eglBindAPI(m_eglApi);
+    bindApi(m_format);
 
     EGLSurface eglSurface = eglSurfaceForPlatformSurface(surface);
 
@@ -121,7 +133,7 @@ void QEGLPlatformContext::doneCurrent()
 #ifdef QEGL_EXTRA_DEBUG
     qWarning("QEglContext::doneCurrent:%p\n",this);
 #endif
-    eglBindAPI(m_eglApi);
+    bindApi(m_format);
     bool ok = eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
     if (!ok)
         qWarning("QEGLPlatformContext::doneCurrent(): eglError: %d, this: %p \n", eglGetError(), this);
@@ -132,7 +144,7 @@ void QEGLPlatformContext::swapBuffers(QPlatformSurface *surface)
 #ifdef QEGL_EXTRA_DEBUG
     qWarning("QEglContext::swapBuffers:%p\n",this);
 #endif
-    eglBindAPI(m_eglApi);
+    bindApi(m_format);
     EGLSurface eglSurface = eglSurfaceForPlatformSurface(surface);
     bool ok = eglSwapBuffers(m_eglDisplay, eglSurface);
     if (!ok)
@@ -144,7 +156,7 @@ void (*QEGLPlatformContext::getProcAddress(const QByteArray &procName)) ()
 #ifdef QEGL_EXTRA_DEBUG
     qWarning("QEglContext::getProcAddress%p\n",this);
 #endif
-    eglBindAPI(m_eglApi);
+    bindApi(m_format);
     return eglGetProcAddress(procName.constData());
 }