From 4c4537d63a62d5ba0a2d8ddbc04026f81399268f Mon Sep 17 00:00:00 2001
From: Tom Cooksey <thomas.cooksey@nokia.com>
Date: Fri, 5 Mar 2010 16:57:46 +0100
Subject: Make QEgl::ConfigOptions use QFlags

Reviewed-By: Trustme
---
 src/gui/egl/qegl_p.h | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/gui/egl/qegl_p.h b/src/gui/egl/qegl_p.h
index ffb45aa..f500bd4 100644
--- a/src/gui/egl/qegl_p.h
+++ b/src/gui/egl/qegl_p.h
@@ -97,10 +97,14 @@ QT_END_INCLUDE_NAMESPACE
 
 #include <QtGui/qpaintdevice.h>
 
+#include <QFlags>
+
 QT_BEGIN_NAMESPACE
 
 #define QEGL_NO_CONFIG ((EGLConfig)-1)
 
+
+
 class QEglProperties;
 
 namespace QEgl {
@@ -116,12 +120,14 @@ namespace QEgl {
         BestPixelFormat
     };
 
-    enum ConfigOptions
+    enum ConfigOption
     {
         NoOptions   = 0,
         Translucent = 0x01,
         Renderable  = 0x02  // Config will be compatable with the paint engines (VG or GL)
     };
+    Q_DECLARE_FLAGS(ConfigOptions, ConfigOption);
+
 
     // Most of the time we use the same config for things like widgets & pixmaps, so rather than
     // go through the eglChooseConfig loop every time, we use defaultConfig, which will return
@@ -153,6 +159,7 @@ namespace QEgl {
 #endif
 };
 
+Q_DECLARE_OPERATORS_FOR_FLAGS(QEgl::ConfigOptions);
 
 QT_END_NAMESPACE
 
-- 
cgit v0.12


From ee07fff45d49e69d9a4f4474861a219af8d557f2 Mon Sep 17 00:00:00 2001
From: Tom Cooksey <thomas.cooksey@nokia.com>
Date: Fri, 5 Mar 2010 16:59:06 +0100
Subject: Make QEgl::createSurface store the surface in the pixmapdata too

This means the same surface can then later be used to bind the
pixmap as a texture using eglBindTexImage2D.

Reviewed-By: TrustMe
---
 src/gui/egl/qegl_x11.cpp | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/gui/egl/qegl_x11.cpp b/src/gui/egl/qegl_x11.cpp
index 483c01d..8608523 100644
--- a/src/gui/egl/qegl_x11.cpp
+++ b/src/gui/egl/qegl_x11.cpp
@@ -404,9 +404,11 @@ EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig config, const QEg
         else
             surfaceAttribs.setValue(EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB);
 
-        return eglCreatePixmapSurface(QEgl::display(), config,
-                                      (EGLNativePixmapType) x11PixmapData->handle(),
-                                      surfaceAttribs.properties());
+        EGLSurface surf = eglCreatePixmapSurface(QEgl::display(), config,
+                                                 (EGLNativePixmapType) x11PixmapData->handle(),
+                                                 surfaceAttribs.properties());
+        x11PixmapData->gl_surface = (Qt::HANDLE)surf;
+        return surf;
     }
 
     return EGL_NO_SURFACE;
-- 
cgit v0.12


From 7d587efef35b3adbb3433a4baec1c5ee7105cf0b Mon Sep 17 00:00:00 2001
From: Tom Cooksey <thomas.cooksey@nokia.com>
Date: Fri, 5 Mar 2010 17:29:53 +0100
Subject: Port QX11GLPixmapData & QX11GLWindowSurface to new QEgl API

It's still just as buggy, but at least it allows us to remove a lot
of crud from qgl_x11egl.cpp.

Reviewed-By: TrustMe
---
 src/opengl/qgl_egl.cpp               |  15 ++--
 src/opengl/qgl_x11egl.cpp            | 107 ---------------------------
 src/opengl/qgraphicssystem_gl.cpp    |   1 -
 src/opengl/qpixmapdata_x11gl_egl.cpp | 138 ++++++++++++++---------------------
 src/opengl/qpixmapdata_x11gl_p.h     |   9 +++
 5 files changed, 74 insertions(+), 196 deletions(-)

diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp
index 7bfcf27..91b271b 100644
--- a/src/opengl/qgl_egl.cpp
+++ b/src/opengl/qgl_egl.cpp
@@ -210,23 +210,26 @@ void QGLContextPrivate::destroyEglSurfaceForDevice()
 
 EGLSurface QGLContextPrivate::eglSurfaceForDevice() const
 {
-    if (paintDevice->devType() == QInternal::Widget)
+    // If a QPixmapData had to create the QGLContext, we don't have a paintDevice
+    if (!paintDevice)
         return eglSurface;
-    if (paintDevice->devType() == QInternal::Pixmap) {
+
 #ifdef Q_WS_X11
+    if (paintDevice->devType() == QInternal::Pixmap) {
         QPixmapData *pmd = static_cast<QPixmap*>(paintDevice)->data_ptr().data();
         if (pmd->classId() == QPixmapData::X11Class) {
             QX11PixmapData* x11PixmapData = static_cast<QX11PixmapData*>(pmd);
             return (EGLSurface)x11PixmapData->gl_surface;
-        } else
-#endif
-            return eglSurface;
+        }
     }
+#endif
+
     if (paintDevice->devType() == QInternal::Pbuffer) {
         QGLPixelBuffer* pbuf = static_cast<QGLPixelBuffer*>(paintDevice);
         return pbuf->d_func()->pbuf;
     }
-    return EGL_NO_SURFACE;
+
+    return eglSurface;
 }
 
 void QGLWidget::setMouseTracking(bool enable)
diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp
index 123bbdd..5ffecc5 100644
--- a/src/opengl/qgl_x11egl.cpp
+++ b/src/opengl/qgl_x11egl.cpp
@@ -358,113 +358,6 @@ void QGLWidgetPrivate::recreateEglSurface(bool force)
     }
 }
 
-// Selects which configs should be used
-EGLConfig Q_OPENGL_EXPORT qt_chooseEGLConfigForPixmap(bool hasAlpha, bool readOnly)
-{
-    // Cache the configs we select as they wont change:
-    static EGLConfig roPixmapRGBConfig = 0;
-    static EGLConfig roPixmapRGBAConfig = 0;
-    static EGLConfig rwPixmapRGBConfig = 0;
-    static EGLConfig rwPixmapRGBAConfig = 0;
-
-    EGLConfig* targetConfig;
-
-    if (hasAlpha) {
-        if (readOnly)
-            targetConfig = &roPixmapRGBAConfig;
-        else
-            targetConfig = &rwPixmapRGBAConfig;
-    }
-    else {
-        if (readOnly)
-            targetConfig = &roPixmapRGBConfig;
-        else
-            targetConfig = &rwPixmapRGBConfig;
-    }
-
-    if (*targetConfig == 0) {
-        QEglProperties configAttribs;
-        configAttribs.setValue(EGL_SURFACE_TYPE, EGL_PIXMAP_BIT);
-        configAttribs.setRenderableType(QEgl::OpenGL);
-        if (hasAlpha)
-            configAttribs.setValue(EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE);
-        else
-            configAttribs.setValue(EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE);
-
-        // If this is going to be a render target, it needs to have a depth, stencil & sample buffer
-        if (!readOnly) {
-            configAttribs.setValue(EGL_DEPTH_SIZE, 1);
-            configAttribs.setValue(EGL_STENCIL_SIZE, 1);
-            configAttribs.setValue(EGL_SAMPLE_BUFFERS, 1);
-        }
-
-        EGLint configCount = 0;
-        do {
-            eglChooseConfig(QEgl::display(), configAttribs.properties(), targetConfig, 1, &configCount);
-            if (configCount > 0) {
-                // Got one
-                qDebug() << "Found an" << (hasAlpha ? "ARGB" : "RGB") << (readOnly ? "readonly" : "target" )
-                         << "config to create a pixmap surface:";
-
-//                QEglProperties configProps(*targetConfig);
-//                qDebug() << configProps.toString();
-                break;
-            }
-            qWarning("choosePixmapConfig() - No suitible config found, reducing requirements");
-        } while (configAttribs.reduceConfiguration());
-    }
-
-    if (*targetConfig == 0)
-        qWarning("choosePixmapConfig() - Couldn't find a suitable config");
-
-    return *targetConfig;
-}
-
-bool Q_OPENGL_EXPORT qt_createEGLSurfaceForPixmap(QPixmapData* pmd, bool readOnly)
-{
-    Q_ASSERT(pmd->classId() == QPixmapData::X11Class);
-    QX11PixmapData* pixmapData = static_cast<QX11PixmapData*>(pmd);
-
-    bool hasAlpha = pixmapData->hasAlphaChannel();
-
-    EGLConfig pixmapConfig = qt_chooseEGLConfigForPixmap(hasAlpha, readOnly);
-
-    QEglProperties pixmapAttribs;
-
-    // If the pixmap can't be bound to a texture, it's pretty useless
-    pixmapAttribs.setValue(EGL_TEXTURE_TARGET, EGL_TEXTURE_2D);
-    if (hasAlpha)
-        pixmapAttribs.setValue(EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA);
-    else
-        pixmapAttribs.setValue(EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB);
-
-    EGLSurface pixmapSurface;
-    pixmapSurface = eglCreatePixmapSurface(QEgl::display(),
-                                           pixmapConfig,
-                                           (EGLNativePixmapType) pixmapData->handle(),
-                                           pixmapAttribs.properties());
-//    qDebug("qt_createEGLSurfaceForPixmap() created surface 0x%x for pixmap 0x%x",
-//           pixmapSurface, pixmapData->handle());
-    if (pixmapSurface == EGL_NO_SURFACE) {
-        qWarning() << "Failed to create a pixmap surface:" << QEgl::errorString();
-        return false;
-    }
-
-    static bool doneOnce = false;
-    if (!doneOnce) {
-        // Make sure QGLTextureCache is instanciated so it can install cleanup hooks
-        // which cleanup the EGL surface.
-        QGLTextureCache::instance();
-        doneOnce = true;
-    }
-
-    Q_ASSERT(sizeof(Qt::HANDLE) >= sizeof(EGLSurface)); // Just to make totally sure!
-    pixmapData->gl_surface = (Qt::HANDLE)pixmapSurface;
-    QImagePixmapCleanupHooks::enableCleanupHooks(pixmapData); // Make sure the cleanup hook gets called
-
-    return true;
-}
-
 
 QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmapData* pd, const qint64 key,
                                                            QGLContext::BindOptions options)
diff --git a/src/opengl/qgraphicssystem_gl.cpp b/src/opengl/qgraphicssystem_gl.cpp
index 3a399ae..a282e4c 100644
--- a/src/opengl/qgraphicssystem_gl.cpp
+++ b/src/opengl/qgraphicssystem_gl.cpp
@@ -62,7 +62,6 @@ QPixmapData *QGLGraphicsSystem::createPixmapData(QPixmapData::PixelType type) co
     if (type == QPixmapData::PixmapType && QX11GLPixmapData::hasX11GLPixmaps())
         return new QX11GLPixmapData();
 #endif
-
     return new QGLPixmapData(type);
 }
 
diff --git a/src/opengl/qpixmapdata_x11gl_egl.cpp b/src/opengl/qpixmapdata_x11gl_egl.cpp
index 811e554..34915f5 100644
--- a/src/opengl/qpixmapdata_x11gl_egl.cpp
+++ b/src/opengl/qpixmapdata_x11gl_egl.cpp
@@ -58,13 +58,12 @@
 
 QT_BEGIN_NAMESPACE
 
-extern EGLConfig qt_chooseEGLConfigForPixmap(bool hasAlpha, bool readOnly); // in qgl_x11egl.cpp
-extern bool qt_createEGLSurfaceForPixmap(QPixmapData* pmd, bool readOnly); // in qgl_x11egl.cpp
 
 // On 16bpp systems, RGB & ARGB pixmaps are different bit-depths and therefore need
 // different contexts:
-static EGLContext qPixmapARGBSharedEglContext = EGL_NO_CONTEXT;
-static EGLContext qPixmapRGBSharedEglContext = EGL_NO_CONTEXT;
+QEglContext* QX11GLPixmapData::rgbContext = 0;
+QEglContext* QX11GLPixmapData::argbContext = 0;
+
 
 bool QX11GLPixmapData::hasX11GLPixmaps()
 {
@@ -76,68 +75,64 @@ bool QX11GLPixmapData::hasX11GLPixmaps()
 
     checkedForX11Pixmaps = true;
 
-    QX11PixmapData *argbPixmapData = 0;
-    QX11PixmapData *rgbPixmapData = 0;
     do {
         if (qgetenv("QT_USE_X11GL_PIXMAPS").isEmpty())
             break;
 
-        // Check we actually have EGL configs which support pixmaps
-        EGLConfig argbConfig = qt_chooseEGLConfigForPixmap(true, false);
-        EGLConfig rgbConfig = qt_chooseEGLConfigForPixmap(false, false);
+        EGLConfig rgbConfig = QEgl::defaultConfig(QInternal::Pixmap, QEgl::OpenGL, QEgl::Renderable);
+        EGLConfig argbConfig = QEgl::defaultConfig(QInternal::Pixmap, QEgl::OpenGL,
+                                                   QEgl::Renderable | QEgl::Translucent);
+
+        if (!rgbContext) {
+            rgbContext = new QEglContext;
+            rgbContext->setConfig(rgbConfig);
+            rgbContext->createContext();
+        }
 
-        if (argbConfig == 0 || rgbConfig == 0)
+        if (!rgbContext->isValid())
             break;
 
-        // Create the shared contexts:
-        eglBindAPI(EGL_OPENGL_ES_API);
-        EGLint contextAttribs[] = {
-#if defined(QT_OPENGL_ES_2)
-            EGL_CONTEXT_CLIENT_VERSION, 2,
-#endif
-            EGL_NONE
-        };
-        qPixmapARGBSharedEglContext = eglCreateContext(QEgl::display(),
-                                                       argbConfig, 0, contextAttribs);
-
-        if (argbConfig == rgbConfig) {
-            // If the configs are the same, we can re-use the same context.
-            qPixmapRGBSharedEglContext = qPixmapARGBSharedEglContext;
-        } else {
-            qPixmapRGBSharedEglContext = eglCreateContext(QEgl::display(),
-                                                           rgbConfig, 0, contextAttribs);
-        }
+        // If the configs are the same, use the same egl contexts:
+        if (rgbConfig == argbConfig)
+            argbContext = rgbContext;
 
-        argbPixmapData = new QX11PixmapData(QPixmapData::PixmapType);
-        argbPixmapData->resize(100, 100);
-        argbPixmapData->fill(Qt::transparent); // Force ARGB
+        if (!argbContext) {
+            argbContext = new QEglContext;
+            argbContext->setConfig(argbConfig);
+            argbContext->createContext();
+        }
 
-        if (!qt_createEGLSurfaceForPixmap(argbPixmapData, false))
+        if (!argbContext->isValid())
             break;
 
-        haveX11Pixmaps = eglMakeCurrent(QEgl::display(),
-                                        (EGLSurface)argbPixmapData->gl_surface,
-                                        (EGLSurface)argbPixmapData->gl_surface,
-                                        qPixmapARGBSharedEglContext);
+        {
+            QX11PixmapData *argbPixmapData = new QX11PixmapData(QPixmapData::PixmapType);
+            argbPixmapData->resize(100, 100);
+            argbPixmapData->fill(Qt::transparent); // Force ARGB
+            QPixmap argbPixmap(argbPixmapData);
+            EGLSurface argbPixmapSurface = QEgl::createSurface(&argbPixmap, argbConfig);
+            haveX11Pixmaps = argbContext->makeCurrent(argbPixmapSurface);
+            argbContext->doneCurrent();
+            eglDestroySurface(QEgl::display(), argbPixmapSurface);
+        }
+
         if (!haveX11Pixmaps) {
-            qWarning() << "Unable to make pixmap config current:" << QEgl::errorString();
+            qWarning() << "Unable to make pixmap surface current:" << QEgl::errorString();
             break;
         }
 
-        // If the ARGB & RGB configs are the same, we don't need to check RGB too
-        if (haveX11Pixmaps && (argbConfig != rgbConfig)) {
-            rgbPixmapData = new QX11PixmapData(QPixmapData::PixmapType);
+        // If the ARGB & RGB configs are different, check RGB too:
+        if (argbConfig != rgbConfig) {
+            QX11PixmapData *rgbPixmapData = new QX11PixmapData(QPixmapData::PixmapType);
             rgbPixmapData->resize(100, 100);
             rgbPixmapData->fill(Qt::red);
 
-            // Try to actually create an EGL pixmap surface
-            if (!qt_createEGLSurfaceForPixmap(rgbPixmapData, false))
-                break;
+            QPixmap rgbPixmap(rgbPixmapData);
+            EGLSurface rgbPixmapSurface = QEgl::createSurface(&rgbPixmap, rgbConfig);
+            haveX11Pixmaps = rgbContext->makeCurrent(rgbPixmapSurface);
+            rgbContext->doneCurrent();
+            eglDestroySurface(QEgl::display(), rgbPixmapSurface);
 
-            haveX11Pixmaps = eglMakeCurrent(QEgl::display(),
-                                            (EGLSurface)rgbPixmapData->gl_surface,
-                                            (EGLSurface)rgbPixmapData->gl_surface,
-                                            qPixmapRGBSharedEglContext);
             if (!haveX11Pixmaps) {
                 qWarning() << "Unable to make pixmap config current:" << QEgl::errorString();
                 break;
@@ -145,36 +140,15 @@ bool QX11GLPixmapData::hasX11GLPixmaps()
         }
     } while (0);
 
-    if (qPixmapARGBSharedEglContext || qPixmapRGBSharedEglContext) {
-        eglMakeCurrent(QEgl::display(),
-                       EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-    }
-
-    if (argbPixmapData) {
-        if (argbPixmapData->gl_surface)
-            QGLContextPrivate::destroyGlSurfaceForPixmap(argbPixmapData);
-        delete argbPixmapData;
-        argbPixmapData = 0;
-    }
-    if (rgbPixmapData) {
-        if (rgbPixmapData->gl_surface)
-            QGLContextPrivate::destroyGlSurfaceForPixmap(rgbPixmapData);
-        delete rgbPixmapData;
-        rgbPixmapData = 0;
-    }
-
     if (!haveX11Pixmaps) {
-        // Clean up the context(s) if we can't use X11GL pixmaps
-        if (qPixmapARGBSharedEglContext != EGL_NO_CONTEXT)
-            eglDestroyContext(QEgl::display(), qPixmapARGBSharedEglContext);
-
-        if (qPixmapRGBSharedEglContext != qPixmapARGBSharedEglContext &&
-            qPixmapRGBSharedEglContext != EGL_NO_CONTEXT)
-        {
-            eglDestroyContext(QEgl::display(), qPixmapRGBSharedEglContext);
+        if (argbContext && (argbContext != rgbContext)) {
+            delete argbContext;
+            argbContext = 0;
+        }
+        if (rgbContext) {
+            delete rgbContext;
+            rgbContext = 0;
         }
-        qPixmapRGBSharedEglContext = EGL_NO_CONTEXT;
-        qPixmapARGBSharedEglContext = EGL_NO_CONTEXT;
     }
 
     if (haveX11Pixmaps)
@@ -209,11 +183,8 @@ QPaintEngine* QX11GLPixmapData::paintEngine() const
     // We need to create the context before beginPaint - do it here:
     if (!ctx) {
         ctx = new QGLContext(glFormat());
-        if (ctx->d_func()->eglContext == 0)
-            ctx->d_func()->eglContext = new QEglContext();
-        ctx->d_func()->eglContext->setApi(QEgl::OpenGL);
-        ctx->d_func()->eglContext->setContext(hasAlphaChannel() ? qPixmapARGBSharedEglContext
-                                                                : qPixmapRGBSharedEglContext);
+        Q_ASSERT(ctx->d_func()->eglContext == 0);
+        ctx->d_func()->eglContext = hasAlphaChannel() ? argbContext : rgbContext;
     }
 
     QPaintEngine* engine;
@@ -256,10 +227,13 @@ QPaintEngine* QX11GLPixmapData::paintEngine() const
 void QX11GLPixmapData::beginPaint()
 {
 //    qDebug("QX11GLPixmapData::beginPaint()");
+    // TODO: Check to see if the surface is renderable
     if ((EGLSurface)gl_surface == EGL_NO_SURFACE) {
-        qt_createEGLSurfaceForPixmap(this, false);
+        QPixmap tmpPixmap(this);
+        EGLConfig cfg = ctx->d_func()->eglContext->config();
+        gl_surface = (Qt::HANDLE)QEgl::createSurface(&tmpPixmap, cfg);
         ctx->d_func()->eglSurface = (EGLSurface)gl_surface;
-        ctx->d_func()->valid = true; // ;-)
+        ctx->d_func()->valid = true;
     }
     QGLPaintDevice::beginPaint();
 }
diff --git a/src/opengl/qpixmapdata_x11gl_p.h b/src/opengl/qpixmapdata_x11gl_p.h
index c9f4f56..83cd780 100644
--- a/src/opengl/qpixmapdata_x11gl_p.h
+++ b/src/opengl/qpixmapdata_x11gl_p.h
@@ -59,6 +59,10 @@
 
 #include <qgl.h>
 
+#ifndef QT_NO_EGL
+#include <QtGui/private/qeglcontext_p.h>
+#endif
+
 QT_BEGIN_NAMESPACE
 
 class QX11GLPixmapData : public QX11PixmapData, public QGLPaintDevice
@@ -76,6 +80,11 @@ public:
 
     static bool hasX11GLPixmaps();
     static QGLFormat glFormat();
+
+#ifndef QT_NO_EGL
+    static QEglContext* rgbContext;
+    static QEglContext* argbContext;
+#endif
 private:
     mutable QGLContext* ctx;
 };
-- 
cgit v0.12