/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtGui module 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 <QtGui/qpaintdevice.h>
#include <QtGui/qpixmap.h>
#include <QtGui/qwidget.h>
#include <QtCore/qatomic.h>
#include <QtCore/qdebug.h>

#include "qegl_p.h"
#include "qeglcontext_p.h"


QT_BEGIN_NAMESPACE


/*
    QEglContextTracker is used to track the EGL contexts that we
    create internally in Qt, so that we can call eglTerminate() to
    free additional EGL resources when the last context is destroyed.
*/

class QEglContextTracker
{
public:
    static void ref() { contexts.ref(); }
    static void deref() {
        if (!contexts.deref()) {
            eglTerminate(QEgl::display());
            displayOpen = 0;
        }
    }
    static void setDisplayOpened() { displayOpen = 1; }
    static bool displayOpened() { return displayOpen; }

private:
    static QBasicAtomicInt contexts;
    static QBasicAtomicInt displayOpen;
};

QBasicAtomicInt QEglContextTracker::contexts = Q_BASIC_ATOMIC_INITIALIZER(0);
QBasicAtomicInt QEglContextTracker::displayOpen = Q_BASIC_ATOMIC_INITIALIZER(0);

// Current GL and VG contexts.  These are used to determine if
// we can avoid an eglMakeCurrent() after a call to lazyDoneCurrent().
// If a background thread modifies the value, the worst that will
// happen is a redundant eglMakeCurrent() in the foreground thread.
static QEglContext * volatile currentGLContext = 0;
static QEglContext * volatile currentVGContext = 0;

QEglContext::QEglContext()
    : apiType(QEgl::OpenGL)
    , ctx(EGL_NO_CONTEXT)
    , cfg(QEGL_NO_CONFIG)
    , currentSurface(EGL_NO_SURFACE)
    , current(false)
    , ownsContext(true)
    , sharing(false)
    , apiChanged(false)
{
    QEglContextTracker::ref();
}

QEglContext::~QEglContext()
{
    destroyContext();

    if (currentGLContext == this)
        currentGLContext = 0;
    if (currentVGContext == this)
        currentVGContext = 0;
    QEglContextTracker::deref();
}

bool QEglContext::isValid() const
{
    return (ctx != EGL_NO_CONTEXT);
}

bool QEglContext::isCurrent() const
{
    return current;
}

EGLConfig QEgl::defaultConfig(int devType, API api, ConfigOptions options)
{
    if ( (devType != QInternal::Pixmap) && ((options & Renderable) == 0))
        qWarning("QEgl::defaultConfig() - Only configs for pixmaps make sense to be read-only!");

    EGLConfig* targetConfig = 0;

    static EGLConfig defaultVGConfigs[] = {
        QEGL_NO_CONFIG, // 0    Window  Renderable  Translucent
        QEGL_NO_CONFIG, // 1    Window  Renderable  Opaque
        QEGL_NO_CONFIG, // 2    Pixmap  Renderable  Translucent
        QEGL_NO_CONFIG, // 3    Pixmap  Renderable  Opaque
        QEGL_NO_CONFIG, // 4    Pixmap  ReadOnly    Translucent
        QEGL_NO_CONFIG  // 5    Pixmap  ReadOnly    Opaque
    };
    if (api == OpenVG) {
        if (devType == QInternal::Widget) {
            if (options & Translucent)
                targetConfig = &(defaultVGConfigs[0]);
            else
                targetConfig = &(defaultVGConfigs[1]);
        } else if (devType == QInternal::Pixmap) {
            if (options & Renderable) {
                if (options & Translucent)
                    targetConfig = &(defaultVGConfigs[2]);
                else // Opaque
                    targetConfig = &(defaultVGConfigs[3]);
            } else { // Read-only
                if (options & Translucent)
                    targetConfig = &(defaultVGConfigs[4]);
                else // Opaque
                    targetConfig = &(defaultVGConfigs[5]);
            }
        }
    }


    static EGLConfig defaultGLConfigs[] = {
        QEGL_NO_CONFIG, // 0    Window  Renderable  Translucent
        QEGL_NO_CONFIG, // 1    Window  Renderable  Opaque
        QEGL_NO_CONFIG, // 2    PBuffer Renderable  Translucent
        QEGL_NO_CONFIG, // 3    PBuffer Renderable  Opaque
        QEGL_NO_CONFIG, // 4    Pixmap  Renderable  Translucent
        QEGL_NO_CONFIG, // 5    Pixmap  Renderable  Opaque
        QEGL_NO_CONFIG, // 6    Pixmap  ReadOnly    Translucent
        QEGL_NO_CONFIG  // 7    Pixmap  ReadOnly    Opaque
    };
    if (api == OpenGL) {
        if (devType == QInternal::Widget) {
            if (options & Translucent)
                targetConfig = &(defaultGLConfigs[0]);
            else // Opaque
                targetConfig = &(defaultGLConfigs[1]);
        } else if (devType == QInternal::Pbuffer) {
            if (options & Translucent)
                targetConfig = &(defaultGLConfigs[2]);
            else // Opaque
                targetConfig = &(defaultGLConfigs[3]);
        } else if (devType == QInternal::Pixmap) {
            if (options & Renderable) {
                if (options & Translucent)
                    targetConfig = &(defaultGLConfigs[4]);
                else // Opaque
                    targetConfig = &(defaultGLConfigs[5]);
            } else { // ReadOnly
                if (options & Translucent)
                    targetConfig = &(defaultGLConfigs[6]);
                else // Opaque
                    targetConfig = &(defaultGLConfigs[7]);
            }
        }
    }

    if (!targetConfig) {
        qWarning("QEgl::defaultConfig() - No default config for device/api/options combo");
        return QEGL_NO_CONFIG;
    }
    if (*targetConfig != QEGL_NO_CONFIG)
        return *targetConfig;


    // We haven't found an EGL config for the target config yet, so do it now:


    // Allow overriding from an environment variable:
    QByteArray configId;
    if (api == OpenVG)
        configId = qgetenv("QT_VG_EGL_CONFIG");
    else
        configId = qgetenv("QT_GL_EGL_CONFIG");
    if (!configId.isEmpty()) {
        // Overridden, so get the EGLConfig for the specified config ID:
        EGLint properties[] = {
            EGL_CONFIG_ID, (EGLint)configId.toInt(),
            EGL_NONE
        };
        EGLint configCount = 0;
        eglChooseConfig(display(), properties, targetConfig, 1, &configCount);
        if (configCount > 0)
            return *targetConfig;
        qWarning() << "QEgl::defaultConfig() -" << configId << "appears to be invalid";
    }

    QEglProperties configAttribs;
    configAttribs.setRenderableType(api);

    EGLint surfaceType;
    switch (devType) {
        case QInternal::Widget:
            surfaceType = EGL_WINDOW_BIT;
            break;
        case QInternal::Pixmap:
            surfaceType = EGL_PIXMAP_BIT;
            break;
        case QInternal::Pbuffer:
            surfaceType = EGL_PBUFFER_BIT;
            break;
        default:
            qWarning("QEgl::defaultConfig() - Can't create EGL surface for %d device type", devType);
            return QEGL_NO_CONFIG;
    };
#ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT
    // For OpenVG, we try to create a surface using a pre-multiplied format if
    // the surface needs to have an alpha channel:
    if (api == OpenVG && (options & Translucent))
        surfaceType |= EGL_VG_ALPHA_FORMAT_PRE_BIT;
#endif
    configAttribs.setValue(EGL_SURFACE_TYPE, surfaceType);

#ifdef EGL_BIND_TO_TEXTURE_RGBA
    if (devType == QInternal::Pixmap || devType == QInternal::Pbuffer) {
        if (options & Translucent)
            configAttribs.setValue(EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE);
        else
            configAttribs.setValue(EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE);
    }
#endif

    // Add paint engine requirements
    if (api == OpenVG) {
#if !defined(QVG_SCISSOR_CLIP) && defined(EGL_ALPHA_MASK_SIZE)
        configAttribs.setValue(EGL_ALPHA_MASK_SIZE, 1);
#endif
    } else {
        // Both OpenGL paint engines need to have stencil and sample buffers
        configAttribs.setValue(EGL_STENCIL_SIZE, 1);
        configAttribs.setValue(EGL_SAMPLE_BUFFERS, 1);
#ifndef QT_OPENGL_ES_2
        // Additionally, the GL1 engine likes to have a depth buffer for clipping
        configAttribs.setValue(EGL_DEPTH_SIZE, 1);
#endif
    }

    if (options & Translucent)
        configAttribs.setValue(EGL_ALPHA_SIZE, 1);

    *targetConfig = chooseConfig(&configAttribs, QEgl::BestPixelFormat);
    return *targetConfig;
}


// Choose a configuration that matches "properties".
EGLConfig QEgl::chooseConfig(const QEglProperties* properties, QEgl::PixelFormatMatch match)
{
    QEglProperties props(*properties);
    EGLConfig cfg = QEGL_NO_CONFIG;
    do {
        // Get the number of matching configurations for this set of properties.
        EGLint matching = 0;
        EGLDisplay dpy = QEgl::display();
        if (!eglChooseConfig(dpy, props.properties(), 0, 0, &matching) || !matching)
            continue;

        // If we want the best pixel format, then return the first
        // matching configuration.
        if (match == QEgl::BestPixelFormat) {
            eglChooseConfig(display(), props.properties(), &cfg, 1, &matching);
            if (matching < 1)
                continue;
            return cfg;
        }

        // Fetch all of the matching configurations and find the
        // first that matches the pixel format we wanted.
        EGLint size = matching;
        EGLConfig *configs = new EGLConfig [size];
        eglChooseConfig(display(), props.properties(), configs, size, &matching);
        for (EGLint index = 0; index < size; ++index) {
            EGLint red, green, blue, alpha;
            eglGetConfigAttrib(display(), configs[index], EGL_RED_SIZE, &red);
            eglGetConfigAttrib(display(), configs[index], EGL_GREEN_SIZE, &green);
            eglGetConfigAttrib(display(), configs[index], EGL_BLUE_SIZE, &blue);
            eglGetConfigAttrib(display(), configs[index], EGL_ALPHA_SIZE, &alpha);
            if (red == props.value(EGL_RED_SIZE) &&
                    green == props.value(EGL_GREEN_SIZE) &&
                    blue == props.value(EGL_BLUE_SIZE) &&
                    (props.value(EGL_ALPHA_SIZE) == 0 ||
                     alpha == props.value(EGL_ALPHA_SIZE))) {
                cfg = configs[index];
                delete [] configs;
                return cfg;
            }
        }
        delete [] configs;
    } while (props.reduceConfiguration());

#ifdef EGL_BIND_TO_TEXTURE_RGBA
    // Don't report an error just yet if we failed to get a pbuffer
    // configuration with texture rendering.  Only report failure if
    // we cannot get any pbuffer configurations at all.
    if (props.value(EGL_BIND_TO_TEXTURE_RGBA) == EGL_DONT_CARE &&
        props.value(EGL_BIND_TO_TEXTURE_RGB) == EGL_DONT_CARE)
#endif
    {
        qWarning() << "QEglContext::chooseConfig(): Could not find a suitable EGL configuration";
        qWarning() << "Requested:" << props.toString();
        qWarning() << "Available:";
        QEgl::dumpAllConfigs();
    }
    return QEGL_NO_CONFIG;
}

bool QEglContext::chooseConfig(const QEglProperties& properties, QEgl::PixelFormatMatch match)
{
    cfg = QEgl::chooseConfig(&properties, match);
    return cfg != QEGL_NO_CONFIG;
}

EGLSurface QEglContext::createSurface(QPaintDevice* device, const QEglProperties *properties)
{
    return QEgl::createSurface(device, cfg, properties);
}


// Create the EGLContext.
bool QEglContext::createContext(QEglContext *shareContext, const QEglProperties *properties)
{
    // We need to select the correct API before calling eglCreateContext().
#ifdef QT_OPENGL_ES
#ifdef EGL_OPENGL_ES_API
    if (apiType == QEgl::OpenGL)
        eglBindAPI(EGL_OPENGL_ES_API);
#endif
#else
#ifdef EGL_OPENGL_API
    if (apiType == QEgl::OpenGL)
        eglBindAPI(EGL_OPENGL_API);
#endif
#endif //defined(QT_OPENGL_ES)
#ifdef EGL_OPENVG_API
    if (apiType == QEgl::OpenVG)
        eglBindAPI(EGL_OPENVG_API);
#endif

    // Create a new context for the configuration.
    QEglProperties contextProps;
    if (properties)
        contextProps = *properties;
#ifdef QT_OPENGL_ES_2
    if (apiType == QEgl::OpenGL)
        contextProps.setValue(EGL_CONTEXT_CLIENT_VERSION, 2);
#endif
    sharing = false;
    if (shareContext && shareContext->ctx == EGL_NO_CONTEXT)
        shareContext = 0;
    if (shareContext) {
        ctx = eglCreateContext(QEgl::display(), cfg, shareContext->ctx, contextProps.properties());
        if (ctx == EGL_NO_CONTEXT) {
            qWarning() << "QEglContext::createContext(): Could not share context:" << QEgl::errorString();
            shareContext = 0;
        } else {
            sharing = true;
        }
    }
    if (ctx == EGL_NO_CONTEXT) {
        ctx = eglCreateContext(display(), cfg, 0, contextProps.properties());
        if (ctx == EGL_NO_CONTEXT) {
            qWarning() << "QEglContext::createContext(): Unable to create EGL context:" << QEgl::errorString();
            return false;
        }
    }
    return true;
}

// Destroy an EGL surface object.  If it was current on this context
// then call doneCurrent() for it first.
void QEglContext::destroySurface(EGLSurface surface)
{
    if (surface != EGL_NO_SURFACE) {
        if (surface == currentSurface)
            doneCurrent();
        eglDestroySurface(display(), surface);
    }
}

// Destroy the context.  Note: this does not destroy the surface.
void QEglContext::destroyContext()
{
    if (ctx != EGL_NO_CONTEXT && ownsContext)
        eglDestroyContext(display(), ctx);
    ctx = EGL_NO_CONTEXT;
    cfg = 0;
}

bool QEglContext::makeCurrent(EGLSurface surface)
{
    if (ctx == EGL_NO_CONTEXT) {
        qWarning() << "QEglContext::makeCurrent(): Cannot make invalid context current";
        return false;
    }

    if (surface == EGL_NO_SURFACE) {
        qWarning() << "QEglContext::makeCurrent(): Cannot make invalid surface current";
        return false;
    }

#ifdef Q_OS_SYMBIAN
    apiChanged = false;
    if (currentContext(apiType)
            && currentContext(apiType)->ctx != eglGetCurrentContext()) {
        // some other EGL based API active. Complete its rendering
        eglWaitClient();
        apiChanged = true;
    }
#endif

    // If lazyDoneCurrent() was called on the surface, then we may be able
    // to assume that it is still current within the thread.
    if (surface == currentSurface && currentContext(apiType) == this
            && !apiChanged) {
        current = true;
        return true;
    }

    current = true;
    currentSurface = surface;
    setCurrentContext(apiType, this);

    // Force the right API to be bound before making the context current.
    // The EGL implementation should be able to figure this out from ctx,
    // but some systems require the API to be explicitly set anyway.
#ifdef EGL_OPENGL_ES_API
    if (apiType == QEgl::OpenGL)
        eglBindAPI(EGL_OPENGL_ES_API);
#endif
#ifdef EGL_OPENVG_API
    if (apiType == QEgl::OpenVG)
        eglBindAPI(EGL_OPENVG_API);
#endif

    bool ok = eglMakeCurrent(QEgl::display(), surface, surface, ctx);
    if (!ok)
        qWarning() << "QEglContext::makeCurrent(" << surface << "):" << QEgl::errorString();
    return ok;
}

bool QEglContext::doneCurrent()
{
    // If the context is invalid, we assume that an error was reported
    // when makeCurrent() was called.
    if (ctx == EGL_NO_CONTEXT)
        return false;

    current = false;
    currentSurface = EGL_NO_SURFACE;
    setCurrentContext(apiType, 0);

    // We need to select the correct API before calling eglMakeCurrent()
    // with EGL_NO_CONTEXT because threads can have both OpenGL and OpenVG
    // contexts active at the same time.
#ifdef EGL_OPENGL_ES_API
    if (apiType == QEgl::OpenGL)
        eglBindAPI(EGL_OPENGL_ES_API);
#endif
#ifdef EGL_OPENVG_API
    if (apiType == QEgl::OpenVG)
        eglBindAPI(EGL_OPENVG_API);
#endif

    bool ok = eglMakeCurrent(QEgl::display(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    if (!ok)
        qWarning() << "QEglContext::doneCurrent():" << QEgl::errorString();
    return ok;
}

// Act as though doneCurrent() was called, but keep the context
// and the surface active for the moment.  This allows makeCurrent()
// to skip a call to eglMakeCurrent() if we are using the same
// surface as the last set of painting operations.  We leave the
// currentContext() pointer as-is for now.
bool QEglContext::lazyDoneCurrent()
{
    current = false;
    return true;
}

bool QEglContext::swapBuffers(EGLSurface surface)
{
    if(ctx == EGL_NO_CONTEXT)
        return false;

    bool ok = eglSwapBuffers(QEgl::display(), surface);
    if (!ok)
        qWarning() << "QEglContext::swapBuffers():" << QEgl::errorString();

#ifdef Q_OS_SYMBIAN
    if (apiChanged) {
        eglWaitClient();
        apiChanged = false;
    }
#endif
    return ok;
}

bool QEglContext::swapBuffersRegion2NOK(EGLSurface surface, const QRegion *region) {
    QVector<QRect> qrects = region->rects();
    EGLint *gl_rects;
    uint count;
    uint i;

    count = qrects.size();
    QVarLengthArray <EGLint> arr(4 * count);
    gl_rects = arr.data();
    for (i = 0; i < count; i++) {
      QRect qrect = qrects[i];

      gl_rects[4 * i + 0] = qrect.x();
      gl_rects[4 * i + 1] = qrect.y();
      gl_rects[4 * i + 2] = qrect.width();
      gl_rects[4 * i + 3] = qrect.height();
    }

    bool ok = QEgl::eglSwapBuffersRegion2NOK(QEgl::display(), surface, count, gl_rects);

    if (!ok)
        qWarning() << "QEglContext::swapBuffersRegion2NOK():" << QEgl::errorString();
    return ok;
}

int QEglContext::configAttrib(int name) const
{
    EGLint value;
    EGLBoolean success = eglGetConfigAttrib(QEgl::display(), cfg, name, &value);
    if (success)
        return value;
    else
        return EGL_DONT_CARE;
}

typedef EGLImageKHR (EGLAPIENTRY *_eglCreateImageKHR)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint*);
typedef EGLBoolean (EGLAPIENTRY *_eglDestroyImageKHR)(EGLDisplay, EGLImageKHR);

// Defined in qegl.cpp:
static _eglCreateImageKHR qt_eglCreateImageKHR = 0;
static _eglDestroyImageKHR qt_eglDestroyImageKHR = 0;

typedef EGLBoolean (EGLAPIENTRY *_eglSwapBuffersRegion2NOK)(EGLDisplay, EGLSurface, EGLint, const EGLint*);

static _eglSwapBuffersRegion2NOK qt_eglSwapBuffersRegion2NOK = 0;

EGLDisplay QEgl::display()
{
    static EGLDisplay dpy = EGL_NO_DISPLAY;
    if (!QEglContextTracker::displayOpened()) {
        dpy = eglGetDisplay(nativeDisplay());
        QEglContextTracker::setDisplayOpened();
        if (dpy == EGL_NO_DISPLAY) {
            qWarning("QEgl::display(): Falling back to EGL_DEFAULT_DISPLAY");
            dpy = eglGetDisplay(EGLNativeDisplayType(EGL_DEFAULT_DISPLAY));
        }
        if (dpy == EGL_NO_DISPLAY) {
            qWarning("QEgl::display(): Can't even open the default display");
            return EGL_NO_DISPLAY;
        }

        if (!eglInitialize(dpy, NULL, NULL)) {
            qWarning() << "QEgl::display(): Cannot initialize EGL display:" << QEgl::errorString();
            return EGL_NO_DISPLAY;
        }

        // Resolve the egl extension function pointers:
#if (defined(EGL_KHR_image) || defined(EGL_KHR_image_base)) && !defined(EGL_EGLEXT_PROTOTYPES)
        if (QEgl::hasExtension("EGL_KHR_image") || QEgl::hasExtension("EGL_KHR_image_base")) {
            qt_eglCreateImageKHR = (_eglCreateImageKHR) eglGetProcAddress("eglCreateImageKHR");
            qt_eglDestroyImageKHR = (_eglDestroyImageKHR) eglGetProcAddress("eglDestroyImageKHR");
        }
#endif

        if (QEgl::hasExtension("EGL_NOK_swap_region2")) {
            qt_eglSwapBuffersRegion2NOK = (_eglSwapBuffersRegion2NOK) eglGetProcAddress("eglSwapBuffersRegion2NOK");
        }
    }

    return dpy;
}

EGLImageKHR QEgl::eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
{
    if (qt_eglCreateImageKHR)
        return qt_eglCreateImageKHR(dpy, ctx, target, buffer, attrib_list);

    QEgl::display(); // Initialises function pointers
    if (qt_eglCreateImageKHR)
        return qt_eglCreateImageKHR(dpy, ctx, target, buffer, attrib_list);

    qWarning("QEgl::eglCreateImageKHR() called but EGL_KHR_image(_base) extension not present");
    return 0;
}

EGLBoolean QEgl::eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
{
    if (qt_eglDestroyImageKHR)
        return qt_eglDestroyImageKHR(dpy, img);

    QEgl::display(); // Initialises function pointers
    if (qt_eglDestroyImageKHR)
        return qt_eglDestroyImageKHR(dpy, img);

    qWarning("QEgl::eglDestroyImageKHR() called but EGL_KHR_image(_base) extension not present");
    return 0;
}

EGLBoolean QEgl::eglSwapBuffersRegion2NOK(EGLDisplay dpy, EGLSurface surface, EGLint count, const EGLint *rects)
{
    if (qt_eglSwapBuffersRegion2NOK)
        return qt_eglSwapBuffersRegion2NOK(dpy, surface, count, rects);

    QEgl::display(); // Initialises function pointers
    if (qt_eglSwapBuffersRegion2NOK)
        return qt_eglSwapBuffersRegion2NOK(dpy, surface, count, rects);

    qWarning("QEgl::eglSwapBuffersRegion2NOK() called but EGL_NOK_swap_region2 extension not present");
    return 0;
}

#ifndef Q_WS_X11
EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig cfg, const QEglProperties *properties)
{
    // Create the native drawable for the paint device.
    int devType = device->devType();
    EGLNativePixmapType pixmapDrawable = 0;
    EGLNativeWindowType windowDrawable = 0;
    bool ok;
    if (devType == QInternal::Pixmap) {
        pixmapDrawable = nativePixmap(static_cast<QPixmap *>(device));
        ok = (pixmapDrawable != 0);
    } else if (devType == QInternal::Widget) {
        windowDrawable = nativeWindow(static_cast<QWidget *>(device));
        ok = (windowDrawable != 0);
    } else {
        ok = false;
    }
    if (!ok) {
        qWarning("QEglContext::createSurface(): Cannot create the native EGL drawable");
        return EGL_NO_SURFACE;
    }

    // Create the EGL surface to draw into, based on the native drawable.
    const int *props;
    if (properties)
        props = properties->properties();
    else
        props = 0;
    EGLSurface surf;
    if (devType == QInternal::Widget)
        surf = eglCreateWindowSurface(QEgl::display(), cfg, windowDrawable, props);
    else
        surf = eglCreatePixmapSurface(QEgl::display(), cfg, pixmapDrawable, props);
    if (surf == EGL_NO_SURFACE) {
        qWarning("QEglContext::createSurface(): Unable to create EGL surface, error = 0x%x", eglGetError());
    }
    return surf;
}
#endif


// Return the error string associated with a specific code.
QString QEgl::errorString(EGLint code)
{
    static const char * const errors[] = {
        "Success (0x3000)",                 // No tr
        "Not initialized (0x3001)",         // No tr
        "Bad access (0x3002)",              // No tr
        "Bad alloc (0x3003)",               // No tr
        "Bad attribute (0x3004)",           // No tr
        "Bad config (0x3005)",              // No tr
        "Bad context (0x3006)",             // No tr
        "Bad current surface (0x3007)",     // No tr
        "Bad display (0x3008)",             // No tr
        "Bad match (0x3009)",               // No tr
        "Bad native pixmap (0x300A)",       // No tr
        "Bad native window (0x300B)",       // No tr
        "Bad parameter (0x300C)",           // No tr
        "Bad surface (0x300D)",             // No tr
        "Context lost (0x300E)"             // No tr
    };
    if (code >= 0x3000 && code <= 0x300E) {
        return QString::fromLatin1(errors[code - 0x3000]);
    } else {
        return QLatin1String("0x") + QString::number(int(code), 16);
    }
}

// Dump all of the EGL configurations supported by the system.
void QEgl::dumpAllConfigs()
{
    QEglProperties props;
    EGLint count = 0;
    if (!eglGetConfigs(display(), 0, 0, &count) || count < 1)
        return;
    EGLConfig *configs = new EGLConfig [count];
    eglGetConfigs(display(), configs, count, &count);
    for (EGLint index = 0; index < count; ++index) {
        props = QEglProperties(configs[index]);
        qWarning() << props.toString();
    }
    delete [] configs;
}

QString QEgl::extensions()
{
    const char* exts = eglQueryString(QEgl::display(), EGL_EXTENSIONS);
    return QString(QLatin1String(exts));
}

bool QEgl::hasExtension(const char* extensionName)
{
    QList<QByteArray> extensions =
        QByteArray(reinterpret_cast<const char *>
            (eglQueryString(QEgl::display(), EGL_EXTENSIONS))).split(' ');
    return extensions.contains(extensionName);
}

QEglContext *QEglContext::currentContext(QEgl::API api)
{
    if (api == QEgl::OpenGL)
        return currentGLContext;
    else
        return currentVGContext;
}

void QEglContext::setCurrentContext(QEgl::API api, QEglContext *context)
{
    if (api == QEgl::OpenGL)
        currentGLContext = context;
    else
        currentVGContext = context;
}

QT_END_NAMESPACE
