/*
**
** Copyright 2007 The Android Open Source Project
**
** Licensed under the Apache License Version 2.0(the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing software
** distributed under the License is distributed on an "AS IS" BASIS
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/mman.h>

#include <cutils/log.h>
#include <cutils/atomic.h>

#include <utils/threads.h>

#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <EGL/android_natives.h>
#include <GLES/gl.h>
#include <GLES/glext.h>

#include <pixelflinger/format.h>
#include <pixelflinger/pixelflinger.h>

#include "context.h"
#include "state.h"
#include "texture.h"
#include "matrix.h"

#ifdef LIBAGL_USE_GRALLOC_COPYBITS
#include "gralloc_priv.h"
#endif // LIBAGL_USE_GRALLOC_COPYBITS

#undef NELEM
#define NELEM(x) (sizeof(x)/sizeof(*(x)))

// ----------------------------------------------------------------------------
namespace android {
// ----------------------------------------------------------------------------

const unsigned int NUM_DISPLAYS = 1;

static pthread_mutex_t gInitMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t gErrorKeyMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_key_t gEGLErrorKey = -1;
#ifndef HAVE_ANDROID_OS
namespace gl {
pthread_key_t gGLKey = -1;
}; // namespace gl
#endif

template<typename T>
static T setError(GLint error, T returnValue) {
    if (ggl_unlikely(gEGLErrorKey == -1)) {
        pthread_mutex_lock(&gErrorKeyMutex);
        if (gEGLErrorKey == -1)
            pthread_key_create(&gEGLErrorKey, NULL);
        pthread_mutex_unlock(&gErrorKeyMutex);
    }
    pthread_setspecific(gEGLErrorKey, (void*)error);
    return returnValue;
}

static GLint getError() {
    if (ggl_unlikely(gEGLErrorKey == -1))
        return EGL_SUCCESS;
    GLint error = (GLint)pthread_getspecific(gEGLErrorKey);
    pthread_setspecific(gEGLErrorKey, (void*)EGL_SUCCESS);
    return error;
}

// ----------------------------------------------------------------------------

struct egl_display_t
{
    egl_display_t() : type(0), initialized(0) { }

    static egl_display_t& get_display(EGLDisplay dpy);

    static EGLBoolean is_valid(EGLDisplay dpy) {
        return ((uintptr_t(dpy)-1U) >= NUM_DISPLAYS) ? EGL_FALSE : EGL_TRUE;
    }

    NativeDisplayType   type;
    volatile int32_t    initialized;
};

static egl_display_t gDisplays[NUM_DISPLAYS];

egl_display_t& egl_display_t::get_display(EGLDisplay dpy) {
    return gDisplays[uintptr_t(dpy)-1U];
}

struct egl_context_t {
    enum {
        IS_CURRENT      =   0x00010000,
        NEVER_CURRENT   =   0x00020000
    };
    uint32_t            flags;
    EGLDisplay          dpy;
    EGLConfig           config;
    EGLSurface          read;
    EGLSurface          draw;

    static inline egl_context_t* context(EGLContext ctx) {
        ogles_context_t* const gl = static_cast<ogles_context_t*>(ctx);
        return static_cast<egl_context_t*>(gl->rasterizer.base);
    }
};

// ----------------------------------------------------------------------------

struct egl_surface_t
{
    enum {
        PAGE_FLIP = 0x00000001,
        MAGIC     = 0x31415265
    };

    uint32_t            magic;
    EGLDisplay          dpy;
    EGLConfig           config;
    EGLContext          ctx;

                egl_surface_t(EGLDisplay dpy, EGLConfig config, int32_t depthFormat);
    virtual     ~egl_surface_t();
    virtual     bool    isValid() const = 0;

    virtual     EGLBoolean  bindDrawSurface(ogles_context_t* gl) = 0;
    virtual     EGLBoolean  bindReadSurface(ogles_context_t* gl) = 0;
    virtual     EGLint      getWidth() const = 0;
    virtual     EGLint      getHeight() const = 0;
    virtual     void*       getBits() const = 0;

    virtual     EGLint      getHorizontalResolution() const;
    virtual     EGLint      getVerticalResolution() const;
    virtual     EGLint      getRefreshRate() const;
    virtual     EGLint      getSwapBehavior() const;
    virtual     EGLBoolean  swapBuffers();
protected:
    GGLSurface              depth;
};

egl_surface_t::egl_surface_t(EGLDisplay dpy,
        EGLConfig config,
        int32_t depthFormat)
    : magic(MAGIC), dpy(dpy), config(config), ctx(0)
{
    depth.version = sizeof(GGLSurface);
    depth.data = 0;
    depth.format = depthFormat;
}
egl_surface_t::~egl_surface_t()
{
    magic = 0;
    free(depth.data);
}
EGLBoolean egl_surface_t::swapBuffers() {
    return EGL_FALSE;
}
EGLint egl_surface_t::getHorizontalResolution() const {
    return (0 * EGL_DISPLAY_SCALING) * (1.0f / 25.4f);
}
EGLint egl_surface_t::getVerticalResolution() const {
    return (0 * EGL_DISPLAY_SCALING) * (1.0f / 25.4f);
}
EGLint egl_surface_t::getRefreshRate() const {
    return (60 * EGL_DISPLAY_SCALING);
}
EGLint egl_surface_t::getSwapBehavior() const {
    return EGL_BUFFER_PRESERVED;
}

// ----------------------------------------------------------------------------

struct egl_window_surface_v2_t : public egl_surface_t
{
    egl_window_surface_v2_t(
            EGLDisplay dpy, EGLConfig config,
            int32_t depthFormat,
            android_native_window_t* window);

     ~egl_window_surface_v2_t();

    virtual     bool        isValid() const { return nativeWindow->common.magic == ANDROID_NATIVE_WINDOW_MAGIC; }
    virtual     EGLBoolean  swapBuffers();
    virtual     EGLBoolean  bindDrawSurface(ogles_context_t* gl);
    virtual     EGLBoolean  bindReadSurface(ogles_context_t* gl);
    virtual     EGLint      getWidth() const    { return buffer->width;  }
    virtual     EGLint      getHeight() const   { return buffer->height; }
    virtual     void*       getBits() const;
    virtual     EGLint      getHorizontalResolution() const;
    virtual     EGLint      getVerticalResolution() const;
    virtual     EGLint      getRefreshRate() const;
    virtual     EGLint      getSwapBehavior() const;
private:
    android_native_window_t*   nativeWindow;
    android_native_buffer_t*   buffer;
    int width;
    int height;
};

egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy,
        EGLConfig config,
        int32_t depthFormat,
        android_native_window_t* window)
    : egl_surface_t(dpy, config, depthFormat), nativeWindow(window), buffer(0)
{
    nativeWindow->common.incRef(&nativeWindow->common);

    nativeWindow->dequeueBuffer(nativeWindow, &buffer);
    
    width = buffer->width;
    height = buffer->height;
    if (depthFormat) {
        depth.width   = width;
        depth.height  = height;
        depth.stride  = depth.width; // use the width here
        depth.data    = (GGLubyte*)malloc(depth.stride*depth.height*2);
        if (depth.data == 0) {
            setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
            return;
        }
    }

    // TODO: lockBuffer should rather be executed when the very first
    // direct rendering occurs.    
    buffer->common.incRef(&buffer->common);
    nativeWindow->lockBuffer(nativeWindow, buffer);

    // FIXME: we need to gralloc lock the buffer
    // FIXME: we need to handle the copy-back if needed, but
    // for now we're a "non preserving" implementation.
}

egl_window_surface_v2_t::~egl_window_surface_v2_t() {
    if (buffer) {
        buffer->common.decRef(&buffer->common);
    }
    nativeWindow->common.decRef(&nativeWindow->common);
}

EGLBoolean egl_window_surface_v2_t::swapBuffers()
{
    // TODO: this is roughly the code needed for preserving the back buffer
    // efficiently. dirty is the area that has been modified.
    //Region newDirty(dirty);
    //newDirty.andSelf(Rect(nativeWindow->width, nativeWindow->height));
    //mDirty = newDirty;
    //const Region copyback(mDirty.subtract(newDirty));
    //mDisplaySurface->copyFrontToBack(copyback);

    
    nativeWindow->queueBuffer(nativeWindow, buffer);
    buffer->common.decRef(&buffer->common); buffer = 0;

    nativeWindow->dequeueBuffer(nativeWindow, &buffer);
    buffer->common.incRef(&buffer->common);

    // TODO: lockBuffer should rather be executed when the very first
    // direct rendering occurs.
    nativeWindow->lockBuffer(nativeWindow, buffer);

    
    if ((width != buffer->width) || (height != buffer->height)) {
        // TODO: we probably should reset the swap rect here
        // if the window size has changed
        width = buffer->width;
        height = buffer->height;
        if (depth.data) {
            free(depth.data);
            depth.width   = width;
            depth.height  = height;
            depth.stride  = buffer->stride;
            depth.data    = (GGLubyte*)malloc(depth.stride*depth.height*2);
            if (depth.data == 0) {
                setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
                return EGL_FALSE;
            }
        }
    }
    return EGL_TRUE;
}

#ifdef LIBAGL_USE_GRALLOC_COPYBITS

static bool supportedCopybitsDestinationFormat(int format) {
    // Hardware supported and no destination alpha
    switch (format) {
    case HAL_PIXEL_FORMAT_RGB_565:
    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
        return true;
    default:
        return false;
    }
}
#endif

EGLBoolean egl_window_surface_v2_t::bindDrawSurface(ogles_context_t* gl)
{
    GGLSurface buffer;
    buffer.version = sizeof(GGLSurface);
    buffer.width   = this->buffer->width;
    buffer.height  = this->buffer->height;
    buffer.stride  = this->buffer->stride;
    buffer.data    = (GGLubyte*)this->buffer->bits;
    buffer.format  = this->buffer->format;
    gl->rasterizer.procs.colorBuffer(gl, &buffer);
    if (depth.data != gl->rasterizer.state.buffers.depth.data)
        gl->rasterizer.procs.depthBuffer(gl, &depth);
#ifdef LIBAGL_USE_GRALLOC_COPYBITS
    gl->copybits.drawSurfaceFd = -1;
    if (supportedCopybitsDestinationFormat(buffer.format)) {
        buffer_handle_t handle;
        this->buffer->getHandle(this->buffer, &handle);
        if (handle != NULL) {
            private_handle_t* hand = private_handle_t::dynamicCast(handle);
            if (hand != NULL) {
                if (hand->usesPhysicallyContiguousMemory()) {
                    gl->copybits.drawSurfaceFd = hand->fd;
                }
            }
        }
    }
#endif // LIBAGL_USE_GRALLOC_COPYBITS
    return EGL_TRUE;
}
EGLBoolean egl_window_surface_v2_t::bindReadSurface(ogles_context_t* gl)
{
    GGLSurface buffer;
    buffer.version = sizeof(GGLSurface);
    buffer.width   = this->buffer->width;
    buffer.height  = this->buffer->height;
    buffer.stride  = this->buffer->stride;
    buffer.data    = (GGLubyte*)this->buffer->bits;
    buffer.format  = this->buffer->format;
    gl->rasterizer.procs.readBuffer(gl, &buffer);
    return EGL_TRUE;
}
void* egl_window_surface_v2_t::getBits() const {
    return (GGLubyte*)buffer->bits;
}
EGLint egl_window_surface_v2_t::getHorizontalResolution() const {
    return (nativeWindow->xdpi * EGL_DISPLAY_SCALING) * (1.0f / 25.4f);
}
EGLint egl_window_surface_v2_t::getVerticalResolution() const {
    return (nativeWindow->ydpi * EGL_DISPLAY_SCALING) * (1.0f / 25.4f);
}
EGLint egl_window_surface_v2_t::getRefreshRate() const {
    return (60 * EGL_DISPLAY_SCALING); // FIXME
}
EGLint egl_window_surface_v2_t::getSwapBehavior() const {
    //uint32_t flags = nativeWindow->flags;
    //if (flags & SURFACE_FLAG_PRESERVE_CONTENT)
    //    return EGL_BUFFER_PRESERVED;
    // This is now a feature of EGL, currently we don't preserve
    // the content of the buffers.
    return EGL_BUFFER_DESTROYED;
}

// ----------------------------------------------------------------------------

struct egl_pixmap_surface_t : public egl_surface_t
{
    egl_pixmap_surface_t(
            EGLDisplay dpy, EGLConfig config,
            int32_t depthFormat,
            egl_native_pixmap_t const * pixmap);

    virtual ~egl_pixmap_surface_t() { }

    virtual     bool        isValid() const { return nativePixmap.version == sizeof(egl_native_pixmap_t); }
    virtual     EGLBoolean  bindDrawSurface(ogles_context_t* gl);
    virtual     EGLBoolean  bindReadSurface(ogles_context_t* gl);
    virtual     EGLint      getWidth() const    { return nativePixmap.width;  }
    virtual     EGLint      getHeight() const   { return nativePixmap.height; }
    virtual     void*       getBits() const     { return nativePixmap.data; }
private:
    egl_native_pixmap_t     nativePixmap;
};

egl_pixmap_surface_t::egl_pixmap_surface_t(EGLDisplay dpy,
        EGLConfig config,
        int32_t depthFormat,
        egl_native_pixmap_t const * pixmap)
    : egl_surface_t(dpy, config, depthFormat), nativePixmap(*pixmap)
{
    if (depthFormat) {
        depth.width   = pixmap->width;
        depth.height  = pixmap->height;
        depth.stride  = depth.width; // use the width here
        depth.data    = (GGLubyte*)malloc(depth.stride*depth.height*2);
        if (depth.data == 0) {
            setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
            return;
        }
    }
}
EGLBoolean egl_pixmap_surface_t::bindDrawSurface(ogles_context_t* gl)
{
    GGLSurface buffer;
    buffer.version = sizeof(GGLSurface);
    buffer.width   = nativePixmap.width;
    buffer.height  = nativePixmap.height;
    buffer.stride  = nativePixmap.stride;
    buffer.data    = nativePixmap.data;
    buffer.format  = nativePixmap.format;

    gl->rasterizer.procs.colorBuffer(gl, &buffer);
    if (depth.data != gl->rasterizer.state.buffers.depth.data)
        gl->rasterizer.procs.depthBuffer(gl, &depth);
    return EGL_TRUE;
}
EGLBoolean egl_pixmap_surface_t::bindReadSurface(ogles_context_t* gl)
{
    GGLSurface buffer;
    buffer.version = sizeof(GGLSurface);
    buffer.width   = nativePixmap.width;
    buffer.height  = nativePixmap.height;
    buffer.stride  = nativePixmap.stride;
    buffer.data    = nativePixmap.data;
    buffer.format  = nativePixmap.format;
    gl->rasterizer.procs.readBuffer(gl, &buffer);
    return EGL_TRUE;
}

// ----------------------------------------------------------------------------

struct egl_pbuffer_surface_t : public egl_surface_t
{
    egl_pbuffer_surface_t(
            EGLDisplay dpy, EGLConfig config, int32_t depthFormat,
            int32_t w, int32_t h, int32_t f);

    virtual ~egl_pbuffer_surface_t();

    virtual     bool        isValid() const { return pbuffer.data != 0; }
    virtual     EGLBoolean  bindDrawSurface(ogles_context_t* gl);
    virtual     EGLBoolean  bindReadSurface(ogles_context_t* gl);
    virtual     EGLint      getWidth() const    { return pbuffer.width;  }
    virtual     EGLint      getHeight() const   { return pbuffer.height; }
    virtual     void*       getBits() const     { return pbuffer.data; }
private:
    GGLSurface  pbuffer;
};

egl_pbuffer_surface_t::egl_pbuffer_surface_t(EGLDisplay dpy,
        EGLConfig config, int32_t depthFormat,
        int32_t w, int32_t h, int32_t f)
    : egl_surface_t(dpy, config, depthFormat)
{
    size_t size = w*h;
    switch (f) {
        case GGL_PIXEL_FORMAT_A_8:          size *= 1; break;
        case GGL_PIXEL_FORMAT_RGB_565:      size *= 2; break;
        case GGL_PIXEL_FORMAT_RGBA_8888:    size *= 4; break;
        default:
            LOGE("incompatible pixel format for pbuffer (format=%d)", f);
            pbuffer.data = 0;
            break;
    }
    pbuffer.version = sizeof(GGLSurface);
    pbuffer.width   = w;
    pbuffer.height  = h;
    pbuffer.stride  = w;
    pbuffer.data    = (GGLubyte*)malloc(size);
    pbuffer.format  = f;

    if (depthFormat) {
        depth.width   = pbuffer.width;
        depth.height  = pbuffer.height;
        depth.stride  = depth.width; // use the width here
        depth.data    = (GGLubyte*)malloc(depth.stride*depth.height*2);
        if (depth.data == 0) {
            setError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
            return;
        }
    }
}
egl_pbuffer_surface_t::~egl_pbuffer_surface_t() {
    free(pbuffer.data);
}
EGLBoolean egl_pbuffer_surface_t::bindDrawSurface(ogles_context_t* gl)
{
    gl->rasterizer.procs.colorBuffer(gl, &pbuffer);
    if (depth.data != gl->rasterizer.state.buffers.depth.data)
        gl->rasterizer.procs.depthBuffer(gl, &depth);
    return EGL_TRUE;
}
EGLBoolean egl_pbuffer_surface_t::bindReadSurface(ogles_context_t* gl)
{
    gl->rasterizer.procs.readBuffer(gl, &pbuffer);
    return EGL_TRUE;
}

// ----------------------------------------------------------------------------

struct config_pair_t {
    GLint key;
    GLint value;
};

struct configs_t {
    const config_pair_t* array;
    int                  size;
};

struct config_management_t {
    GLint key;
    bool (*match)(GLint reqValue, GLint confValue);
    static bool atLeast(GLint reqValue, GLint confValue) {
        return (reqValue == EGL_DONT_CARE) || (confValue >= reqValue);
    }
    static bool exact(GLint reqValue, GLint confValue) {
        return (reqValue == EGL_DONT_CARE) || (confValue == reqValue);
    }
    static bool mask(GLint reqValue, GLint confValue) {
        return (confValue & reqValue) == reqValue;
    }
};

// ----------------------------------------------------------------------------

#define VERSION_MAJOR 1
#define VERSION_MINOR 2
static char const * const gVendorString     = "Google Inc.";
static char const * const gVersionString    = "1.2 Android Driver";
static char const * const gClientApiString  = "OpenGL ES";
static char const * const gExtensionsString =
        "KHR_image_base "
        // "KHR_image_pixmap "
        "EGL_ANDROID_image_native_buffer "
        ;

// ----------------------------------------------------------------------------

struct extention_map_t {
    const char * const name;
    __eglMustCastToProperFunctionPointerType address;
};

static const extention_map_t gExtentionMap[] = {
    { "glDrawTexsOES",
            (__eglMustCastToProperFunctionPointerType)&glDrawTexsOES },
    { "glDrawTexiOES",
            (__eglMustCastToProperFunctionPointerType)&glDrawTexiOES },
    { "glDrawTexfOES",
            (__eglMustCastToProperFunctionPointerType)&glDrawTexfOES },
    { "glDrawTexxOES",
            (__eglMustCastToProperFunctionPointerType)&glDrawTexxOES },
    { "glDrawTexsvOES",
            (__eglMustCastToProperFunctionPointerType)&glDrawTexsvOES },
    { "glDrawTexivOES",
            (__eglMustCastToProperFunctionPointerType)&glDrawTexivOES },
    { "glDrawTexfvOES",
            (__eglMustCastToProperFunctionPointerType)&glDrawTexfvOES },
    { "glDrawTexxvOES",
            (__eglMustCastToProperFunctionPointerType)&glDrawTexxvOES },
    { "glQueryMatrixxOES",
            (__eglMustCastToProperFunctionPointerType)&glQueryMatrixxOES },
    { "glEGLImageTargetTexture2DOES",
            (__eglMustCastToProperFunctionPointerType)&glEGLImageTargetTexture2DOES },
    { "glEGLImageTargetRenderbufferStorageOES",
            (__eglMustCastToProperFunctionPointerType)&glEGLImageTargetRenderbufferStorageOES },
    { "glClipPlanef",
            (__eglMustCastToProperFunctionPointerType)&glClipPlanef },
    { "glClipPlanex",
            (__eglMustCastToProperFunctionPointerType)&glClipPlanex },
    { "glBindBuffer",
            (__eglMustCastToProperFunctionPointerType)&glBindBuffer },
    { "glBufferData",
            (__eglMustCastToProperFunctionPointerType)&glBufferData },
    { "glBufferSubData",
            (__eglMustCastToProperFunctionPointerType)&glBufferSubData },
    { "glDeleteBuffers",
            (__eglMustCastToProperFunctionPointerType)&glDeleteBuffers },
    { "glGenBuffers",
            (__eglMustCastToProperFunctionPointerType)&glGenBuffers },
};

/*
 * In the lists below, attributes names MUST be sorted.
 * Additionally, all configs must be sorted according to
 * the EGL specification.
 */

static config_pair_t const config_base_attribute_list[] = {
        { EGL_STENCIL_SIZE,               0                                 },
        { EGL_CONFIG_CAVEAT,              EGL_SLOW_CONFIG                   },
        { EGL_LEVEL,                      0                                 },
        { EGL_MAX_PBUFFER_HEIGHT,         GGL_MAX_VIEWPORT_DIMS             },
        { EGL_MAX_PBUFFER_PIXELS,
                GGL_MAX_VIEWPORT_DIMS*GGL_MAX_VIEWPORT_DIMS                 },
        { EGL_MAX_PBUFFER_WIDTH,          GGL_MAX_VIEWPORT_DIMS             },
        { EGL_NATIVE_RENDERABLE,          EGL_TRUE                          },
        { EGL_NATIVE_VISUAL_ID,           0                                 },
        { EGL_NATIVE_VISUAL_TYPE,         GGL_PIXEL_FORMAT_RGB_565          },
        { EGL_SAMPLES,                    0                                 },
        { EGL_SAMPLE_BUFFERS,             0                                 },
        { EGL_TRANSPARENT_TYPE,           EGL_NONE                          },
        { EGL_TRANSPARENT_BLUE_VALUE,     0                                 },
        { EGL_TRANSPARENT_GREEN_VALUE,    0                                 },
        { EGL_TRANSPARENT_RED_VALUE,      0                                 },
        { EGL_BIND_TO_TEXTURE_RGBA,       EGL_FALSE                         },
        { EGL_BIND_TO_TEXTURE_RGB,        EGL_FALSE                         },
        { EGL_MIN_SWAP_INTERVAL,          1                                 },
        { EGL_MAX_SWAP_INTERVAL,          4                                 },
};

// These configs can override the base attribute list
// NOTE: when adding a config here, don't forget to update eglCreate*Surface()

static config_pair_t const config_0_attribute_list[] = {
        { EGL_BUFFER_SIZE,     16 },
        { EGL_ALPHA_SIZE,       0 },
        { EGL_BLUE_SIZE,        5 },
        { EGL_GREEN_SIZE,       6 },
        { EGL_RED_SIZE,         5 },
        { EGL_DEPTH_SIZE,       0 },
        { EGL_CONFIG_ID,        0 },
        { EGL_SURFACE_TYPE,     EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
};

static config_pair_t const config_1_attribute_list[] = {
        { EGL_BUFFER_SIZE,     16 },
        { EGL_ALPHA_SIZE,       0 },
        { EGL_BLUE_SIZE,        5 },
        { EGL_GREEN_SIZE,       6 },
        { EGL_RED_SIZE,         5 },
        { EGL_DEPTH_SIZE,      16 },
        { EGL_CONFIG_ID,        1 },
        { EGL_SURFACE_TYPE,     EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
};

static config_pair_t const config_2_attribute_list[] = {
        { EGL_BUFFER_SIZE,     32 },
        { EGL_ALPHA_SIZE,       8 },
        { EGL_BLUE_SIZE,        8 },
        { EGL_GREEN_SIZE,       8 },
        { EGL_RED_SIZE,         8 },
        { EGL_DEPTH_SIZE,       0 },
        { EGL_CONFIG_ID,        2 },
        { EGL_SURFACE_TYPE,     EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
};

static config_pair_t const config_3_attribute_list[] = {
        { EGL_BUFFER_SIZE,     32 },
        { EGL_ALPHA_SIZE,       8 },
        { EGL_BLUE_SIZE,        8 },
        { EGL_GREEN_SIZE,       8 },
        { EGL_RED_SIZE,         8 },
        { EGL_DEPTH_SIZE,      16 },
        { EGL_CONFIG_ID,        3 },
        { EGL_SURFACE_TYPE,     EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
};

static config_pair_t const config_4_attribute_list[] = {
        { EGL_BUFFER_SIZE,      8 },
        { EGL_ALPHA_SIZE,       8 },
        { EGL_BLUE_SIZE,        0 },
        { EGL_GREEN_SIZE,       0 },
        { EGL_RED_SIZE,         0 },
        { EGL_DEPTH_SIZE,       0 },
        { EGL_CONFIG_ID,        4 },
        { EGL_SURFACE_TYPE,     EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
};

static config_pair_t const config_5_attribute_list[] = {
        { EGL_BUFFER_SIZE,      8 },
        { EGL_ALPHA_SIZE,       8 },
        { EGL_BLUE_SIZE,        0 },
        { EGL_GREEN_SIZE,       0 },
        { EGL_RED_SIZE,         0 },
        { EGL_DEPTH_SIZE,      16 },
        { EGL_CONFIG_ID,        5 },
        { EGL_SURFACE_TYPE,     EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
};

static configs_t const gConfigs[] = {
        { config_0_attribute_list, NELEM(config_0_attribute_list) },
        { config_1_attribute_list, NELEM(config_1_attribute_list) },
        { config_2_attribute_list, NELEM(config_2_attribute_list) },
        { config_3_attribute_list, NELEM(config_3_attribute_list) },
        { config_4_attribute_list, NELEM(config_4_attribute_list) },
        { config_5_attribute_list, NELEM(config_5_attribute_list) },
};

static config_management_t const gConfigManagement[] = {
        { EGL_BUFFER_SIZE,                config_management_t::atLeast },
        { EGL_ALPHA_SIZE,                 config_management_t::atLeast },
        { EGL_BLUE_SIZE,                  config_management_t::atLeast },
        { EGL_GREEN_SIZE,                 config_management_t::atLeast },
        { EGL_RED_SIZE,                   config_management_t::atLeast },
        { EGL_DEPTH_SIZE,                 config_management_t::atLeast },
        { EGL_STENCIL_SIZE,               config_management_t::atLeast },
        { EGL_CONFIG_CAVEAT,              config_management_t::exact   },
        { EGL_CONFIG_ID,                  config_management_t::exact   },
        { EGL_LEVEL,                      config_management_t::exact   },
        { EGL_MAX_PBUFFER_HEIGHT,         config_management_t::exact   },
        { EGL_MAX_PBUFFER_PIXELS,         config_management_t::exact   },
        { EGL_MAX_PBUFFER_WIDTH,          config_management_t::exact   },
        { EGL_NATIVE_RENDERABLE,          config_management_t::exact   },
        { EGL_NATIVE_VISUAL_ID,           config_management_t::exact   },
        { EGL_NATIVE_VISUAL_TYPE,         config_management_t::exact   },
        { EGL_SAMPLES,                    config_management_t::exact   },
        { EGL_SAMPLE_BUFFERS,             config_management_t::exact   },
        { EGL_SURFACE_TYPE,               config_management_t::mask    },
        { EGL_TRANSPARENT_TYPE,           config_management_t::exact   },
        { EGL_TRANSPARENT_BLUE_VALUE,     config_management_t::exact   },
        { EGL_TRANSPARENT_GREEN_VALUE,    config_management_t::exact   },
        { EGL_TRANSPARENT_RED_VALUE,      config_management_t::exact   },
        { EGL_BIND_TO_TEXTURE_RGBA,       config_management_t::exact   },
        { EGL_BIND_TO_TEXTURE_RGB,        config_management_t::exact   },
        { EGL_MIN_SWAP_INTERVAL,          config_management_t::exact   },
        { EGL_MAX_SWAP_INTERVAL,          config_management_t::exact   },
};

static config_pair_t const config_defaults[] = {
        { EGL_SURFACE_TYPE,        EGL_WINDOW_BIT },
};

// ----------------------------------------------------------------------------

template<typename T>
static int binarySearch(T const sortedArray[], int first, int last, EGLint key)
{
   while (first <= last) {
       int mid = (first + last) / 2;
       if (key > sortedArray[mid].key) {
           first = mid + 1;
       } else if (key < sortedArray[mid].key) {
           last = mid - 1;
       } else {
           return mid;
       }
   }
   return -1;
}

static int isAttributeMatching(int i, EGLint attr, EGLint val)
{
    // look for the attribute in all of our configs
    config_pair_t const* configFound = gConfigs[i].array;
    int index = binarySearch<config_pair_t>(
            gConfigs[i].array,
            0, gConfigs[i].size-1,
            attr);
    if (index < 0) {
        configFound = config_base_attribute_list;
        index = binarySearch<config_pair_t>(
                config_base_attribute_list,
                0, NELEM(config_base_attribute_list)-1,
                attr);
    }
    if (index >= 0) {
        // attribute found, check if this config could match
        int cfgMgtIndex = binarySearch<config_management_t>(
                gConfigManagement,
                0, NELEM(gConfigManagement)-1,
                attr);
        if (index >= 0) {
            bool match = gConfigManagement[cfgMgtIndex].match(
                    val, configFound[index].value);
            if (match) {
                // this config matches
                return 1;
            }
        } else {
            // attribute not found. this should NEVER happen.
        }
    } else {
        // error, this attribute doesn't exist
    }
    return 0;
}

static int makeCurrent(ogles_context_t* gl)
{
    ogles_context_t* current = (ogles_context_t*)getGlThreadSpecific();
    if (gl) {
        egl_context_t* c = egl_context_t::context(gl);
        if (c->flags & egl_context_t::IS_CURRENT) {
            if (current != gl) {
                // it is an error to set a context current, if it's already
                // current to another thread
                return -1;
            }
        } else {
            if (current) {
                // mark the current context as not current, and flush
                glFlush();
                egl_context_t::context(current)->flags &= ~egl_context_t::IS_CURRENT;
            }
        }
        if (!(c->flags & egl_context_t::IS_CURRENT)) {
            // The context is not current, make it current!
            setGlThreadSpecific(gl);
            c->flags |= egl_context_t::IS_CURRENT;
        }
    } else {
        if (current) {
            // mark the current context as not current, and flush
            glFlush();
            egl_context_t::context(current)->flags &= ~egl_context_t::IS_CURRENT;
        }
        // this thread has no context attached to it
        setGlThreadSpecific(0);
    }
    return 0;
}

static EGLBoolean getConfigAttrib(EGLDisplay dpy, EGLConfig config,
        EGLint attribute, EGLint *value)
{
    size_t numConfigs =  NELEM(gConfigs);
    int index = (int)config;
    if (uint32_t(index) >= numConfigs)
        return setError(EGL_BAD_CONFIG, EGL_FALSE);

    int attrIndex;
    attrIndex = binarySearch<config_pair_t>(
            gConfigs[index].array,
            0, gConfigs[index].size-1,
            attribute);
    if (attrIndex>=0) {
        *value = gConfigs[index].array[attrIndex].value;
        return EGL_TRUE;
    }

    attrIndex = binarySearch<config_pair_t>(
            config_base_attribute_list,
            0, NELEM(config_base_attribute_list)-1,
            attribute);
    if (attrIndex>=0) {
        *value = config_base_attribute_list[attrIndex].value;
        return EGL_TRUE;
    }
    return setError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
}

static EGLSurface createWindowSurface(EGLDisplay dpy, EGLConfig config,
        NativeWindowType window, const EGLint *attrib_list)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
        return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
    if (window == 0)
        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);

    EGLint surfaceType;
    if (getConfigAttrib(dpy, config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE)
        return EGL_FALSE;

    if (!(surfaceType & EGL_WINDOW_BIT))
        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);

    EGLint configID;
    if (getConfigAttrib(dpy, config, EGL_CONFIG_ID, &configID) == EGL_FALSE)
        return EGL_FALSE;

    int32_t depthFormat;
    int32_t pixelFormat;
    switch(configID) {
    case 0:
        pixelFormat = GGL_PIXEL_FORMAT_RGB_565;
        depthFormat = 0;
        break;
    case 1:
        pixelFormat = GGL_PIXEL_FORMAT_RGB_565;
        depthFormat = GGL_PIXEL_FORMAT_Z_16;
        break;
    case 2:
        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888;
        depthFormat = 0;
        break;
    case 3:
        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888;
        depthFormat = GGL_PIXEL_FORMAT_Z_16;
        break;
    case 4:
        pixelFormat = GGL_PIXEL_FORMAT_A_8;
        depthFormat = 0;
        break;
    case 5:
        pixelFormat = GGL_PIXEL_FORMAT_A_8;
        depthFormat = GGL_PIXEL_FORMAT_Z_16;
        break;
    default:
        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
    }

    // FIXME: we don't have access to the pixelFormat here just yet.
    // (it's possible that the surface is not fully initialized)
    // maybe this should be done after the page-flip
    //if (EGLint(info.format) != pixelFormat)
    //    return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);

    egl_surface_t* surface;
    surface = new egl_window_surface_v2_t(dpy, config, depthFormat,
            static_cast<android_native_window_t*>(window));

    if (!surface->isValid()) {
        // there was a problem in the ctor, the error
        // flag has been set.
        delete surface;
        surface = 0;
    }
    return surface;
}

static EGLSurface createPixmapSurface(EGLDisplay dpy, EGLConfig config,
        NativePixmapType pixmap, const EGLint *attrib_list)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
        return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
    if (pixmap == 0)
        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);

    EGLint surfaceType;
    if (getConfigAttrib(dpy, config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE)
        return EGL_FALSE;

    if (!(surfaceType & EGL_PIXMAP_BIT))
        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);

    EGLint configID;
    if (getConfigAttrib(dpy, config, EGL_CONFIG_ID, &configID) == EGL_FALSE)
        return EGL_FALSE;

    int32_t depthFormat;
    int32_t pixelFormat;
    switch(configID) {
    case 0:
        pixelFormat = GGL_PIXEL_FORMAT_RGB_565;
        depthFormat = 0;
        break;
    case 1:
        pixelFormat = GGL_PIXEL_FORMAT_RGB_565;
        depthFormat = GGL_PIXEL_FORMAT_Z_16;
        break;
    case 2:
        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888;
        depthFormat = 0;
        break;
    case 3:
        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888;
        depthFormat = GGL_PIXEL_FORMAT_Z_16;
        break;
    case 4:
        pixelFormat = GGL_PIXEL_FORMAT_A_8;
        depthFormat = 0;
        break;
    case 5:
        pixelFormat = GGL_PIXEL_FORMAT_A_8;
        depthFormat = GGL_PIXEL_FORMAT_Z_16;
        break;
    default:
        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
    }

    if (pixmap->format != pixelFormat)
        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);

    egl_surface_t* surface =
        new egl_pixmap_surface_t(dpy, config, depthFormat,
                static_cast<egl_native_pixmap_t*>(pixmap));

    if (!surface->isValid()) {
        // there was a problem in the ctor, the error
        // flag has been set.
        delete surface;
        surface = 0;
    }
    return surface;
}

static EGLSurface createPbufferSurface(EGLDisplay dpy, EGLConfig config,
        const EGLint *attrib_list)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
        return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);

    EGLint surfaceType;
    if (getConfigAttrib(dpy, config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE)
        return EGL_FALSE;

    if (!(surfaceType & EGL_PBUFFER_BIT))
        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);

    EGLint configID;
    if (getConfigAttrib(dpy, config, EGL_CONFIG_ID, &configID) == EGL_FALSE)
        return EGL_FALSE;

    int32_t depthFormat;
    int32_t pixelFormat;
    switch(configID) {
    case 0:
        pixelFormat = GGL_PIXEL_FORMAT_RGB_565;
        depthFormat = 0;
        break;
    case 1:
        pixelFormat = GGL_PIXEL_FORMAT_RGB_565;
        depthFormat = GGL_PIXEL_FORMAT_Z_16;
        break;
    case 2:
        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888;
        depthFormat = 0;
        break;
    case 3:
        pixelFormat = GGL_PIXEL_FORMAT_RGBA_8888;
        depthFormat = GGL_PIXEL_FORMAT_Z_16;
        break;
    case 4:
        pixelFormat = GGL_PIXEL_FORMAT_A_8;
        depthFormat = 0;
        break;
    case 5:
        pixelFormat = GGL_PIXEL_FORMAT_A_8;
        depthFormat = GGL_PIXEL_FORMAT_Z_16;
        break;
    default:
        return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
    }

    int32_t w = 0;
    int32_t h = 0;
    while (attrib_list[0]) {
        if (attrib_list[0] == EGL_WIDTH)  w = attrib_list[1];
        if (attrib_list[0] == EGL_HEIGHT) h = attrib_list[1];
        attrib_list+=2;
    }

    egl_surface_t* surface =
        new egl_pbuffer_surface_t(dpy, config, depthFormat, w, h, pixelFormat);

    if (!surface->isValid()) {
        // there was a problem in the ctor, the error
        // flag has been set.
        delete surface;
        surface = 0;
    }
    return surface;
}

// ----------------------------------------------------------------------------
}; // namespace android
// ----------------------------------------------------------------------------

using namespace android;

// ----------------------------------------------------------------------------
// Initialization
// ----------------------------------------------------------------------------

EGLDisplay eglGetDisplay(NativeDisplayType display)
{
#ifndef HAVE_ANDROID_OS
    // this just needs to be done once
    if (gGLKey == -1) {
        pthread_mutex_lock(&gInitMutex);
        if (gGLKey == -1)
            pthread_key_create(&gGLKey, NULL);
        pthread_mutex_unlock(&gInitMutex);
    }
#endif
    if (display == EGL_DEFAULT_DISPLAY) {
        EGLDisplay dpy = (EGLDisplay)1;
        egl_display_t& d = egl_display_t::get_display(dpy);
        d.type = display;
        return dpy;
    }
    return EGL_NO_DISPLAY;
}

EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
        return setError(EGL_BAD_DISPLAY, EGL_FALSE);

    EGLBoolean res = EGL_TRUE;
    egl_display_t& d = egl_display_t::get_display(dpy);

    if (android_atomic_inc(&d.initialized) == 0) {
        // initialize stuff here if needed
        //pthread_mutex_lock(&gInitMutex);
        //pthread_mutex_unlock(&gInitMutex);
    }

    if (res == EGL_TRUE) {
        if (major != NULL) *major = VERSION_MAJOR;
        if (minor != NULL) *minor = VERSION_MINOR;
    }
    return res;
}

EGLBoolean eglTerminate(EGLDisplay dpy)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
        return setError(EGL_BAD_DISPLAY, EGL_FALSE);

    EGLBoolean res = EGL_TRUE;
    egl_display_t& d = egl_display_t::get_display(dpy);
    if (android_atomic_dec(&d.initialized) == 1) {
        // TODO: destroy all resources (surfaces, contexts, etc...)
        //pthread_mutex_lock(&gInitMutex);
        //pthread_mutex_unlock(&gInitMutex);
    }
    return res;
}

// ----------------------------------------------------------------------------
// configuration
// ----------------------------------------------------------------------------

EGLBoolean eglGetConfigs(   EGLDisplay dpy,
                            EGLConfig *configs,
                            EGLint config_size, EGLint *num_config)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
        return setError(EGL_BAD_DISPLAY, EGL_FALSE);

    GLint numConfigs = NELEM(gConfigs);
    if (!configs) {
        *num_config = numConfigs;
        return EGL_TRUE;
    }
    GLint i;
    for (i=0 ; i<numConfigs && i<config_size ; i++) {
        *configs++ = (EGLConfig)i;
    }
    *num_config = i;
    return EGL_TRUE;
}

EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list,
                            EGLConfig *configs, EGLint config_size,
                            EGLint *num_config)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
    
    if (ggl_unlikely(num_config==0)) {
        return setError(EGL_BAD_PARAMETER, EGL_FALSE);
    }

    if (ggl_unlikely(attrib_list==0)) {
        *num_config = 0;
        return EGL_TRUE;
    }

    int numAttributes = 0;
    int numConfigs =  NELEM(gConfigs);
    uint32_t possibleMatch = (1<<numConfigs)-1;
    while(possibleMatch && *attrib_list != EGL_NONE) {
        numAttributes++;
        EGLint attr = *attrib_list++;
        EGLint val  = *attrib_list++;
        for (int i=0 ; i<numConfigs ; i++) {
            if (!(possibleMatch & (1<<i)))
                continue;
            if (isAttributeMatching(i, attr, val) == 0) {
                possibleMatch &= ~(1<<i);
            }
        }
    }

    // now, handle the attributes which have a useful default value
    for (size_t j=0 ; j<NELEM(config_defaults) ; j++) {
        // see if this attribute was specified, if not apply its
        // default value
        if (binarySearch<config_pair_t>(
                (config_pair_t const*)attrib_list,
                0, numAttributes,
                config_defaults[j].key) < 0)
        {
            for (int i=0 ; i<numConfigs ; i++) {
                if (!(possibleMatch & (1<<i)))
                    continue;
                if (isAttributeMatching(i,
                        config_defaults[j].key,
                        config_defaults[j].value) == 0)
                {
                    possibleMatch &= ~(1<<i);
                }
            }
        }
    }

    // return the configurations found
    int n=0;
    if (possibleMatch) {
        if (configs) {
            for (int i=0 ; config_size && i<numConfigs ; i++) {
                if (possibleMatch & (1<<i)) {
                    *configs++ = (EGLConfig)i;
                    config_size--;
                    n++;
                }
            }
        } else {
            for (int i=0 ; i<numConfigs ; i++) {
                if (possibleMatch & (1<<i)) {
                    n++;
                }
            }
        }
    }
    *num_config = n;
     return EGL_TRUE;
}

EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
        EGLint attribute, EGLint *value)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
        return setError(EGL_BAD_DISPLAY, EGL_FALSE);

    return getConfigAttrib(dpy, config, attribute, value);
}

// ----------------------------------------------------------------------------
// surfaces
// ----------------------------------------------------------------------------

EGLSurface eglCreateWindowSurface(  EGLDisplay dpy, EGLConfig config,
                                    NativeWindowType window,
                                    const EGLint *attrib_list)
{
    return createWindowSurface(dpy, config, window, attrib_list);
}

EGLSurface eglCreatePixmapSurface(  EGLDisplay dpy, EGLConfig config,
                                    NativePixmapType pixmap,
                                    const EGLint *attrib_list)
{
    return createPixmapSurface(dpy, config, pixmap, attrib_list);
}

EGLSurface eglCreatePbufferSurface( EGLDisplay dpy, EGLConfig config,
                                    const EGLint *attrib_list)
{
    return createPbufferSurface(dpy, config, attrib_list);
}

EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface eglSurface)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
    if (eglSurface != EGL_NO_SURFACE) {
        egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) );
        if (surface->magic != egl_surface_t::MAGIC)
            return setError(EGL_BAD_SURFACE, EGL_FALSE);
        if (surface->dpy != dpy)
            return setError(EGL_BAD_DISPLAY, EGL_FALSE);
        delete surface;
    }
    return EGL_TRUE;
}

EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface eglSurface,
                            EGLint attribute, EGLint *value)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
    egl_surface_t* surface = static_cast<egl_surface_t*>(eglSurface);
    if (surface->dpy != dpy)
        return setError(EGL_BAD_DISPLAY, EGL_FALSE);

    EGLBoolean ret = EGL_TRUE;
    switch (attribute) {
        case EGL_CONFIG_ID:
            ret = getConfigAttrib(dpy, surface->config, EGL_CONFIG_ID, value);
            break;
        case EGL_WIDTH:
            *value = surface->getWidth();
            break;
        case EGL_HEIGHT:
            *value = surface->getHeight();
            break;
        case EGL_LARGEST_PBUFFER:
            // not modified for a window or pixmap surface
            break;
        case EGL_TEXTURE_FORMAT:
            *value = EGL_NO_TEXTURE;
            break;
        case EGL_TEXTURE_TARGET:
            *value = EGL_NO_TEXTURE;
            break;
        case EGL_MIPMAP_TEXTURE:
            *value = EGL_FALSE;
            break;
        case EGL_MIPMAP_LEVEL:
            *value = 0;
            break;
        case EGL_RENDER_BUFFER:
            // TODO: return the real RENDER_BUFFER here
            *value = EGL_BACK_BUFFER;
            break;
        case EGL_HORIZONTAL_RESOLUTION:
            // pixel/mm * EGL_DISPLAY_SCALING
            *value = surface->getHorizontalResolution();
            break;
        case EGL_VERTICAL_RESOLUTION:
            // pixel/mm * EGL_DISPLAY_SCALING
            *value = surface->getVerticalResolution();
            break;
        case EGL_PIXEL_ASPECT_RATIO: {
            // w/h * EGL_DISPLAY_SCALING
            int wr = surface->getHorizontalResolution();
            int hr = surface->getVerticalResolution();
            *value = (wr * EGL_DISPLAY_SCALING) / hr;
        } break;
        case EGL_SWAP_BEHAVIOR:
            *value = surface->getSwapBehavior();
            break;
        default:
            ret = setError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
    }
    return ret;
}

EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
                            EGLContext share_list, const EGLint *attrib_list)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
        return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);

    ogles_context_t* gl = ogles_init(sizeof(egl_context_t));
    if (!gl) return setError(EGL_BAD_ALLOC, EGL_NO_CONTEXT);

    egl_context_t* c = static_cast<egl_context_t*>(gl->rasterizer.base);
    c->flags = egl_context_t::NEVER_CURRENT;
    c->dpy = dpy;
    c->config = config;
    c->read = 0;
    c->draw = 0;
    return (EGLContext)gl;
}

EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
    egl_context_t* c = egl_context_t::context(ctx);
    if (c->flags & egl_context_t::IS_CURRENT)
        setGlThreadSpecific(0);
    ogles_uninit((ogles_context_t*)ctx);
    return EGL_TRUE;
}

EGLBoolean eglMakeCurrent(  EGLDisplay dpy, EGLSurface draw,
                            EGLSurface read, EGLContext ctx)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
    if (draw) {
        egl_surface_t* s = (egl_surface_t*)draw;
        if (s->dpy != dpy)
            return setError(EGL_BAD_DISPLAY, EGL_FALSE);
        // TODO: check that draw and read are compatible with the context
    }

    EGLContext current_ctx = EGL_NO_CONTEXT;

    if ((read == EGL_NO_SURFACE && draw == EGL_NO_SURFACE) && (ctx != EGL_NO_CONTEXT))
        return setError(EGL_BAD_MATCH, EGL_FALSE);

    if ((read != EGL_NO_SURFACE || draw != EGL_NO_SURFACE) && (ctx == EGL_NO_CONTEXT))
        return setError(EGL_BAD_MATCH, EGL_FALSE);

    if (ctx == EGL_NO_CONTEXT) {
        // if we're detaching, we need the current context
        current_ctx = (EGLContext)getGlThreadSpecific();
    } else {
        egl_context_t* c = egl_context_t::context(ctx);
        egl_surface_t* d = (egl_surface_t*)draw;
        egl_surface_t* r = (egl_surface_t*)read;
        if ((d && d->ctx && d->ctx != ctx) ||
            (r && r->ctx && r->ctx != ctx)) {
            // once of the surface is bound to a context in another thread
            return setError(EGL_BAD_ACCESS, EGL_FALSE);
        }
    }

    // TODO: call connect / disconnect on the surface

    ogles_context_t* gl = (ogles_context_t*)ctx;
    if (makeCurrent(gl) == 0) {
        if (ctx) {
            egl_context_t* c = egl_context_t::context(ctx);
            egl_surface_t* d = (egl_surface_t*)draw;
            egl_surface_t* r = (egl_surface_t*)read;
            c->read = read;
            c->draw = draw;
            if (c->flags & egl_context_t::NEVER_CURRENT) {
                c->flags &= ~egl_context_t::NEVER_CURRENT;
                GLint w = 0;
                GLint h = 0;
                if (draw) {
                    w = d->getWidth();
                    h = d->getHeight();
                }
                ogles_surfaceport(gl, 0, 0);
                ogles_viewport(gl, 0, 0, w, h);
                ogles_scissor(gl, 0, 0, w, h);
            }
            if (d) {
                d->ctx = ctx;
                d->bindDrawSurface(gl);
            }
            if (r) {
                r->ctx = ctx;
                r->bindReadSurface(gl);
            }
        } else {
            // if surfaces were bound to the context bound to this thread
            // mark then as unbound.
            if (current_ctx) {
                egl_context_t* c = egl_context_t::context(current_ctx);
                egl_surface_t* d = (egl_surface_t*)c->draw;
                egl_surface_t* r = (egl_surface_t*)c->read;
                if (d) d->ctx = EGL_NO_CONTEXT;
                if (r) r->ctx = EGL_NO_CONTEXT;
            }
        }
        return EGL_TRUE;
    }
    return setError(EGL_BAD_ACCESS, EGL_FALSE);
}

EGLContext eglGetCurrentContext(void)
{
    // eglGetCurrentContext returns the current EGL rendering context,
    // as specified by eglMakeCurrent. If no context is current,
    // EGL_NO_CONTEXT is returned.
    return (EGLContext)getGlThreadSpecific();
}

EGLSurface eglGetCurrentSurface(EGLint readdraw)
{
    // eglGetCurrentSurface returns the read or draw surface attached
    // to the current EGL rendering context, as specified by eglMakeCurrent.
    // If no context is current, EGL_NO_SURFACE is returned.
    EGLContext ctx = (EGLContext)getGlThreadSpecific();
    if (ctx == EGL_NO_CONTEXT) return EGL_NO_SURFACE;
    egl_context_t* c = egl_context_t::context(ctx);
    if (readdraw == EGL_READ) {
        return c->read;
    } else if (readdraw == EGL_DRAW) {
        return c->draw;
    }
    return setError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
}

EGLDisplay eglGetCurrentDisplay(void)
{
    // eglGetCurrentDisplay returns the current EGL display connection
    // for the current EGL rendering context, as specified by eglMakeCurrent.
    // If no context is current, EGL_NO_DISPLAY is returned.
    EGLContext ctx = (EGLContext)getGlThreadSpecific();
    if (ctx == EGL_NO_CONTEXT) return EGL_NO_DISPLAY;
    egl_context_t* c = egl_context_t::context(ctx);
    return c->dpy;
}

EGLBoolean eglQueryContext( EGLDisplay dpy, EGLContext ctx,
                            EGLint attribute, EGLint *value)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
    egl_context_t* c = egl_context_t::context(ctx);
    switch (attribute) {
        case EGL_CONFIG_ID:
            // Returns the ID of the EGL frame buffer configuration with
            // respect to which the context was created
            return getConfigAttrib(dpy, c->config, EGL_CONFIG_ID, value);
    }
    return setError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
}

EGLBoolean eglWaitGL(void)
{
    return EGL_TRUE;
}

EGLBoolean eglWaitNative(EGLint engine)
{
    return EGL_TRUE;
}

EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
        return setError(EGL_BAD_DISPLAY, EGL_FALSE);

    egl_surface_t* d = static_cast<egl_surface_t*>(draw);
    if (d->dpy != dpy)
        return setError(EGL_BAD_DISPLAY, EGL_FALSE);

    // post the surface
    d->swapBuffers();

    // if it's bound to a context, update the buffer
    if (d->ctx != EGL_NO_CONTEXT) {
        d->bindDrawSurface((ogles_context_t*)d->ctx);
        // if this surface is also the read surface of the context
        // it is bound to, make sure to update the read buffer as well.
        // The EGL spec is a little unclear about this.
        egl_context_t* c = egl_context_t::context(d->ctx);
        if (c->read == draw) {
            d->bindReadSurface((ogles_context_t*)d->ctx);
        }
    }

    return EGL_TRUE;
}

EGLBoolean eglCopyBuffers(  EGLDisplay dpy, EGLSurface surface,
                            NativePixmapType target)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
    // TODO: eglCopyBuffers()
    return EGL_FALSE;
}

EGLint eglGetError(void)
{
    return getError();
}

const char* eglQueryString(EGLDisplay dpy, EGLint name)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
        return setError(EGL_BAD_DISPLAY, (const char*)0);

    switch (name) {
        case EGL_VENDOR:
            return gVendorString;
        case EGL_VERSION:
            return gVersionString;
        case EGL_EXTENSIONS:
            return gExtensionsString;
        case EGL_CLIENT_APIS:
            return gClientApiString;
    }
    return setError(EGL_BAD_PARAMETER, (const char *)0);
}

// ----------------------------------------------------------------------------
// EGL 1.1
// ----------------------------------------------------------------------------

EGLBoolean eglSurfaceAttrib(
        EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
    // TODO: eglSurfaceAttrib()
    return setError(EGL_BAD_PARAMETER, EGL_FALSE);
}

EGLBoolean eglBindTexImage(
        EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
    // TODO: eglBindTexImage()
    return setError(EGL_BAD_PARAMETER, EGL_FALSE);
}

EGLBoolean eglReleaseTexImage(
        EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
    // TODO: eglReleaseTexImage()
    return setError(EGL_BAD_PARAMETER, EGL_FALSE);
}

EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
    // TODO: eglSwapInterval()
    return setError(EGL_BAD_PARAMETER, EGL_FALSE);
}

// ----------------------------------------------------------------------------
// EGL 1.2
// ----------------------------------------------------------------------------

EGLBoolean eglBindAPI(EGLenum api)
{
    if (api != EGL_OPENGL_ES_API)
        return setError(EGL_BAD_PARAMETER, EGL_FALSE);
    return EGL_TRUE;
}

EGLenum eglQueryAPI(void)
{
    return EGL_OPENGL_ES_API;
}

EGLBoolean eglWaitClient(void)
{
    glFinish();
    return EGL_TRUE;
}

EGLBoolean eglReleaseThread(void)
{
    // TODO: eglReleaseThread()
    return EGL_TRUE;
}

EGLSurface eglCreatePbufferFromClientBuffer(
          EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
          EGLConfig config, const EGLint *attrib_list)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
        return setError(EGL_BAD_DISPLAY, EGL_NO_SURFACE);
    // TODO: eglCreatePbufferFromClientBuffer()
    return setError(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
}

// ----------------------------------------------------------------------------
// EGL_EGLEXT_VERSION 3
// ----------------------------------------------------------------------------

void (*eglGetProcAddress (const char *procname))()
{
    extention_map_t const * const map = gExtentionMap;
    for (uint32_t i=0 ; i<NELEM(gExtentionMap) ; i++) {
        if (!strcmp(procname, map[i].name)) {
            return map[i].address;
        }
    }
    return NULL;
}

EGLBoolean eglLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface,
        const EGLint *attrib_list)
{
    EGLBoolean result = EGL_FALSE;
    return result;
}

EGLBoolean eglUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface)
{
    EGLBoolean result = EGL_FALSE;
    return result;
}

EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target,
        EGLClientBuffer buffer, const EGLint *attrib_list)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE) {
        return setError(EGL_BAD_DISPLAY, EGL_NO_IMAGE_KHR);
    }
    if (ctx != EGL_NO_CONTEXT) {
        return setError(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
    }
    if (target != EGL_NATIVE_BUFFER_ANDROID) {
        return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
    }

    android_native_buffer_t* native_buffer = (android_native_buffer_t*)buffer;

    if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
        return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);

    if (native_buffer->common.version != sizeof(android_native_buffer_t))
        return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);

    hw_module_t const* pModule;
    if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule))
        return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
    buffer_handle_t bufferHandle;
    gralloc_module_t const* module =
        reinterpret_cast<gralloc_module_t const*>(pModule);
    if (native_buffer->getHandle(native_buffer, &bufferHandle) < 0)
        return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
    if (module->map(module, bufferHandle, &native_buffer->bits) < 0)
        return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);

    native_buffer->common.incRef(&native_buffer->common);
    return (EGLImageKHR)native_buffer;
}

EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
{
    if (egl_display_t::is_valid(dpy) == EGL_FALSE) {
        return setError(EGL_BAD_DISPLAY, EGL_FALSE);
    }

    android_native_buffer_t* native_buffer = (android_native_buffer_t*)img;

    if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
        return setError(EGL_BAD_PARAMETER, EGL_FALSE);

    if (native_buffer->common.version != sizeof(android_native_buffer_t))
        return setError(EGL_BAD_PARAMETER, EGL_FALSE);

    hw_module_t const* pModule;
    if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &pModule) == 0) {
        buffer_handle_t bufferHandle;
        gralloc_module_t const* module =
            reinterpret_cast<gralloc_module_t const*>(pModule);
        if (native_buffer->getHandle(native_buffer, &bufferHandle) == 0) {
            module->unmap(module, bufferHandle);
        }
    }

    native_buffer->common.decRef(&native_buffer->common);

    return EGL_TRUE;
}
