migrate opengl and system from  development/tools

- components under system are moved one directory up like all other HALs

Change-Id: I03b870b870d83b247ac398cadfb155f03c9adfa0
diff --git a/system/egl/Android.mk b/system/egl/Android.mk
new file mode 100644
index 0000000..a979089
--- /dev/null
+++ b/system/egl/Android.mk
@@ -0,0 +1,41 @@
+ifneq (false,$(BUILD_EMULATOR_OPENGL_DRIVER))
+
+LOCAL_PATH := $(call my-dir)
+
+$(call emugl-begin-shared-library,libEGL_emulation)
+$(call emugl-import,libOpenglSystemCommon)
+$(call emugl-set-shared-library-subpath,egl)
+
+LOCAL_CFLAGS += -DLOG_TAG=\"EGL_emulation\" -DEGL_EGLEXT_PROTOTYPES -DWITH_GLES2
+
+LOCAL_SRC_FILES := \
+    eglDisplay.cpp \
+    egl.cpp \
+    ClientAPIExts.cpp
+
+LOCAL_SHARED_LIBRARIES += libdl
+
+# Used to access the Bionic private OpenGL TLS slot
+LOCAL_C_INCLUDES += bionic/libc/private
+
+$(call emugl-end-module)
+
+#### egl.cfg ####
+
+# Ensure that this file is only copied to emulator-specific builds.
+# Other builds are device-specific and will provide their own
+# version of this file to point to the appropriate HW EGL libraries.
+#
+ifneq (,$(filter full full_x86 full_mips sdk sdk_x86 sdk_mips google_sdk google_sdk_x86 google_sdk_mips,$(TARGET_PRODUCT)))
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := egl.cfg
+LOCAL_SRC_FILES := $(LOCAL_MODULE)
+
+LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/egl
+LOCAL_MODULE_CLASS := ETC
+
+include $(BUILD_PREBUILT)
+endif # TARGET_PRODUCT in 'full full_x86 full_mips sdk sdk_x86 sdk_mips google_sdk google_sdk_x86 google_sdk_mips')
+
+endif # BUILD_EMULATOR_OPENGL_DRIVER != false
diff --git a/system/egl/ClientAPIExts.cpp b/system/egl/ClientAPIExts.cpp
new file mode 100644
index 0000000..5e81afe
--- /dev/null
+++ b/system/egl/ClientAPIExts.cpp
@@ -0,0 +1,157 @@
+/*
+* Copyright (C) 2011 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 "ClientAPIExts.h"
+#include "ThreadInfo.h"
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#include "eglContext.h"
+
+namespace ClientAPIExts
+{
+
+//
+// define function pointer type for each extention function
+// typename has the form __egl_{funcname}_t
+//
+#define FUNC_TYPE(fname) __egl_ ## fname ## _t
+#define API_ENTRY(fname,params,args) \
+    typedef void (GL_APIENTRY *FUNC_TYPE(fname)) params;
+
+#define API_ENTRY_RET(rtype,fname,params,args) \
+    typedef rtype (GL_APIENTRY *FUNC_TYPE(fname)) params;
+
+#include "ClientAPIExts.in"
+#undef API_ENTRY
+#undef API_ENTRY_RET
+
+/////
+// Define static table to store the function value for each
+// client API. functions pointers will get initialized through
+// ClientAPIExts::initClientFuncs function after each client API has been
+// loaded.
+/////
+#define API_ENTRY(fname,params,args) \
+    FUNC_TYPE(fname) fname;
+
+#define API_ENTRY_RET(rtype,fname,params,args) \
+    API_ENTRY(fname,params,args)
+
+static struct _ext_table
+{
+#include "ClientAPIExts.in"
+} s_client_extensions[2];
+
+#undef API_ENTRY
+#undef API_ENTRY_RET
+
+//
+// This function initialized each entry in the s_client_extensions
+// struct at the givven index using the givven client interface
+//
+void initClientFuncs(const EGLClient_glesInterface *iface, int idx)
+{
+#define API_ENTRY(fname,params,args) \
+    s_client_extensions[idx].fname = \
+          (FUNC_TYPE(fname))iface->getProcAddress(#fname);
+
+#define API_ENTRY_RET(rtype,fname,params,args) \
+    API_ENTRY(fname,params,args)
+
+    //
+    // reset all func pointers to NULL
+    //
+    memset(&s_client_extensions[idx], 0, sizeof(struct _ext_table));
+
+    //
+    // And now query the GLES library for each proc address
+    //
+#include "ClientAPIExts.in"
+#undef API_ENTRY
+#undef API_ENTRY_RET
+}
+
+//
+// Define implementation for each extension function which checks
+// the current context version and calls to the correct client API
+// function.
+//
+#define API_ENTRY(fname,params,args) \
+    static void _egl_ ## fname params \
+    { \
+        EGLThreadInfo* thread  = getEGLThreadInfo(); \
+        if (!thread->currentContext) { \
+            return; \
+        } \
+        int idx = (int)thread->currentContext->version - 1; \
+        if (!s_client_extensions[idx].fname) { \
+            return; \
+        } \
+        (*s_client_extensions[idx].fname) args; \
+    }
+
+#define API_ENTRY_RET(rtype,fname,params,args) \
+    static rtype _egl_ ## fname params \
+    { \
+        EGLThreadInfo* thread  = getEGLThreadInfo(); \
+        if (!thread->currentContext) { \
+            return (rtype)0; \
+        } \
+        int idx = (int)thread->currentContext->version - 1; \
+        if (!s_client_extensions[idx].fname) { \
+            return (rtype)0; \
+        } \
+        return (*s_client_extensions[idx].fname) args; \
+    }
+
+#include "ClientAPIExts.in"
+#undef API_ENTRY
+#undef API_ENTRY_RET
+
+//
+// Define a table to map function names to the local _egl_ version of
+// the extension function, to be used in eglGetProcAddress.
+//
+#define API_ENTRY(fname,params,args) \
+    { #fname, (void*)_egl_ ## fname},
+#define API_ENTRY_RET(rtype,fname,params,args) \
+    API_ENTRY(fname,params,args)
+
+static const struct _client_ext_funcs {
+    const char *fname;
+    void* proc;
+} s_client_ext_funcs[] = {
+#include "ClientAPIExts.in"
+};
+static const int numExtFuncs = sizeof(s_client_ext_funcs) / 
+                               sizeof(s_client_ext_funcs[0]);
+
+#undef API_ENTRY
+#undef API_ENTRY_RET
+
+//
+// returns the __egl_ version of the givven extension function name.
+//
+void* getProcAddress(const char *fname)
+{
+    for (int i=0; i<numExtFuncs; i++) {
+        if (!strcmp(fname, s_client_ext_funcs[i].fname)) {
+            return s_client_ext_funcs[i].proc;
+        }
+    }
+    return NULL;
+}
+
+} // of namespace ClientAPIExts
diff --git a/system/egl/ClientAPIExts.h b/system/egl/ClientAPIExts.h
new file mode 100644
index 0000000..eee9172
--- /dev/null
+++ b/system/egl/ClientAPIExts.h
@@ -0,0 +1,29 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _CLIENT_APIS_EXTS_H
+#define _CLIENT_APIS_EXTS_H
+
+#include "EGLClientIface.h"
+
+namespace ClientAPIExts
+{
+
+void initClientFuncs(const EGLClient_glesInterface *iface, int idx);
+void* getProcAddress(const char *fname);
+
+} // of namespace ClientAPIExts
+
+#endif
diff --git a/system/egl/ClientAPIExts.in b/system/egl/ClientAPIExts.in
new file mode 100644
index 0000000..5850701
--- /dev/null
+++ b/system/egl/ClientAPIExts.in
@@ -0,0 +1,201 @@
+//
+// Each extension function should have one of the following
+// macro definitions:
+//    API_ENTRY(funcname, paramlist, arglist)
+//  -or- (if the function has a return value)
+//    API_ENTRY_RET(return_type,funcname, paramlist, arglist)
+//
+API_ENTRY(glEGLImageTargetTexture2DOES,
+          (GLenum target, GLeglImageOES image),
+          (target, image))
+
+API_ENTRY(glEGLImageTargetRenderbufferStorageOES,
+          (GLenum target, GLeglImageOES image),
+          (target, image))
+
+API_ENTRY(glBlendEquationSeparateOES,
+          (GLenum modeRGB, GLenum modeAlpha),
+          (modeRGB, modeAlpha))
+
+API_ENTRY(glBlendFuncSeparateOES,
+          (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha),
+          (srcRGB, dstRGB, srcAlpha, dstAlpha))
+
+API_ENTRY(glBlendEquationOES,
+          (GLenum mode),
+          (mode))
+
+API_ENTRY(glCurrentPaletteMatrixOES,
+          (GLuint matrixpaletteindex),
+          (matrixpaletteindex))
+
+API_ENTRY(glLoadPaletteFromModelViewMatrixOES,
+          (void),
+          ())
+
+API_ENTRY(glMatrixIndexPointerOES,
+          (GLint size, GLenum type, GLsizei stride, const GLvoid * pointer),
+          (size, type, stride, pointer))
+
+API_ENTRY(glWeightPointerOES,
+          (GLint size, GLenum type, GLsizei stride, const GLvoid * pointer),
+          (size, type, stride, pointer))
+
+API_ENTRY(glDepthRangefOES,
+          (GLclampf zNear, GLclampf zFar),
+          (zNear, zFar))
+
+API_ENTRY(glFrustumfOES,
+          (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar),
+          (left, right, bottom, top, zNear, zFar))
+
+API_ENTRY(glOrthofOES,
+          (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar),
+          (left, right, bottom, top, zNear, zFar))
+
+API_ENTRY(glClipPlanefOES,
+          (GLenum plane, const GLfloat *equation),
+          (plane, equation))
+
+API_ENTRY(glGetClipPlanefOES,
+          (GLenum pname, GLfloat * eqn),
+          (pname, eqn))
+
+API_ENTRY(glClearDepthfOES,
+          (GLclampf depth),
+          (depth))
+
+API_ENTRY(glPointSizePointerOES,
+          (GLenum type, GLsizei stride, const GLvoid *pointer),
+          (type, stride, pointer))
+
+API_ENTRY(glTexGenfOES,
+          (GLenum coord, GLenum pname, GLfloat param),
+          (coord, pname, param))
+
+API_ENTRY(glTexGenfvOES,
+          (GLenum coord, GLenum pname, const GLfloat *params),
+          (coord, pname, params))
+
+API_ENTRY(glTexGeniOES,
+          (GLenum coord, GLenum pname, GLint param),
+          (coord, pname, param))
+
+API_ENTRY(glTexGenivOES,
+          (GLenum coord, GLenum pname, const GLint *params),
+          (coord, pname, params))
+
+API_ENTRY(glTexGenxOES,
+          (GLenum coord, GLenum pname, GLfixed param),
+          (coord, pname, param))
+
+API_ENTRY(glTexGenxvOES,
+          (GLenum coord, GLenum pname, const GLfixed *params),
+          (coord, pname, params))
+
+API_ENTRY(glGetTexGenfvOES,
+          (GLenum coord, GLenum pname, GLfloat *params),
+          (coord, pname, params))
+
+API_ENTRY(glGetTexGenivOES,
+          (GLenum coord, GLenum pname, GLint *params),
+          (coord, pname, params))
+
+API_ENTRY(glGetTexGenxvOES,
+          (GLenum coord, GLenum pname, GLfixed *params),
+          (coord, pname, params))
+
+API_ENTRY_RET(GLboolean,
+              glIsRenderbufferOES,
+              (GLuint renderbuffer),
+              (renderbuffer))
+
+API_ENTRY(glBindRenderbufferOES,
+          (GLenum target, GLuint renderbuffer),
+          (target, renderbuffer))
+
+API_ENTRY(glDeleteRenderbuffersOES,
+          (GLsizei n, const GLuint* renderbuffers),
+          (n, renderbuffers))
+
+API_ENTRY(glGenRenderbuffersOES,
+          (GLsizei n, GLuint* renderbuffers),
+          (n, renderbuffers))
+
+API_ENTRY(glRenderbufferStorageOES,
+          (GLenum target, GLenum internalformat, GLsizei width, GLsizei height),
+          (target, internalformat, width, height))
+
+API_ENTRY(glGetRenderbufferParameterivOES,
+          (GLenum target, GLenum pname, GLint* params),
+          (target, pname, params))
+
+API_ENTRY_RET(GLboolean,
+              glIsFramebufferOES,
+              (GLuint framebuffer),
+              (framebuffer))
+
+API_ENTRY(glBindFramebufferOES,
+          (GLenum target, GLuint framebuffer),
+          (target, framebuffer))
+
+API_ENTRY(glDeleteFramebuffersOES,
+          (GLsizei n, const GLuint* framebuffers),
+          (n, framebuffers))
+
+API_ENTRY(glGenFramebuffersOES,
+          (GLsizei n, GLuint* framebuffers),
+          (n, framebuffers))
+
+API_ENTRY_RET(GLenum,
+              glCheckFramebufferStatusOES,
+              (GLenum target),
+              (target))
+
+API_ENTRY(glFramebufferTexture2DOES,
+          (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level),
+          (target, attachment, textarget, texture, level))
+
+API_ENTRY(glFramebufferRenderbufferOES,
+          (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer),
+          (target, attachment, renderbuffertarget, renderbuffer))
+
+API_ENTRY(glGetFramebufferAttachmentParameterivOES,
+          (GLenum target, GLenum attachment, GLenum pname, GLint* params),
+          (target, attachment, pname, params))
+
+API_ENTRY(glGenerateMipmapOES,
+          (GLenum target),
+          (target))
+
+API_ENTRY(glDrawTexsOES,
+          (GLshort x, GLshort y, GLshort z, GLshort width, GLshort height),
+          (x, y, z, width, height))
+
+API_ENTRY(glDrawTexiOES,
+          (GLint x, GLint y, GLint z, GLint width, GLint height),
+          (x, y, z, width, height))
+
+API_ENTRY(glDrawTexfOES,
+          (GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height),
+          (x, y, z, width, height))
+
+API_ENTRY(glDrawTexxOES,
+          (GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height),
+          (x, y, z, width, height))
+
+API_ENTRY(glDrawTexsvOES,
+          (const GLshort *coords),
+          (coords))
+
+API_ENTRY(glDrawTexivOES,
+          (const GLint *coords),
+          (coords))
+
+API_ENTRY(glDrawTexfvOES,
+          (const GLfloat *coords),
+          (coords))
+
+API_ENTRY(glDrawTexxvOES,
+          (const GLfixed *coords),
+          (coords))
diff --git a/system/egl/egl.cfg b/system/egl/egl.cfg
new file mode 100644
index 0000000..9d3f2dc
--- /dev/null
+++ b/system/egl/egl.cfg
@@ -0,0 +1 @@
+0 0 emulation
diff --git a/system/egl/egl.cpp b/system/egl/egl.cpp
new file mode 100644
index 0000000..da89c4d
--- /dev/null
+++ b/system/egl/egl.cpp
@@ -0,0 +1,1254 @@
+/*
+* Copyright (C) 2011 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 "HostConnection.h"
+#include "ThreadInfo.h"
+#include "eglDisplay.h"
+#include "egl_ftable.h"
+#include <cutils/log.h>
+#include "gralloc_cb.h"
+#include "GLClientState.h"
+#include "GLSharedGroup.h"
+#include "eglContext.h"
+#include "ClientAPIExts.h"
+
+#include "GLEncoder.h"
+#ifdef WITH_GLES2
+#include "GL2Encoder.h"
+#endif
+
+#include <system/window.h>
+
+template<typename T>
+static T setErrorFunc(GLint error, T returnValue) {
+    getEGLThreadInfo()->eglError = error;
+    return returnValue;
+}
+
+const char *  eglStrError(EGLint err)
+{
+    switch (err){
+        case EGL_SUCCESS:           return "EGL_SUCCESS";
+        case EGL_NOT_INITIALIZED:   return "EGL_NOT_INITIALIZED";
+        case EGL_BAD_ACCESS:        return "EGL_BAD_ACCESS";
+        case EGL_BAD_ALLOC:         return "EGL_BAD_ALLOC";
+        case EGL_BAD_ATTRIBUTE:     return "EGL_BAD_ATTRIBUTE";
+        case EGL_BAD_CONFIG:        return "EGL_BAD_CONFIG";
+        case EGL_BAD_CONTEXT:       return "EGL_BAD_CONTEXT";
+        case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
+        case EGL_BAD_DISPLAY:       return "EGL_BAD_DISPLAY";
+        case EGL_BAD_MATCH:         return "EGL_BAD_MATCH";
+        case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
+        case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
+        case EGL_BAD_PARAMETER:     return "EGL_BAD_PARAMETER";
+        case EGL_BAD_SURFACE:       return "EGL_BAD_SURFACE";
+        case EGL_CONTEXT_LOST:      return "EGL_CONTEXT_LOST";
+        default: return "UNKNOWN";
+    }
+}
+
+#define LOG_EGL_ERRORS 1
+
+#ifdef LOG_EGL_ERRORS
+
+#define setErrorReturn(error, retVal)     \
+    {                                                \
+        ALOGE("tid %d: %s(%d): error 0x%x (%s)", gettid(), __FUNCTION__, __LINE__, error, eglStrError(error));     \
+        return setErrorFunc(error, retVal);            \
+    }
+
+#define RETURN_ERROR(ret,err)           \
+    ALOGE("tid %d: %s(%d): error 0x%x (%s)", gettid(), __FUNCTION__, __LINE__, err, eglStrError(err));    \
+    getEGLThreadInfo()->eglError = err;    \
+    return ret;
+
+#else //!LOG_EGL_ERRORS
+
+#define setErrorReturn(error, retVal) return setErrorFunc(error, retVal);
+
+#define RETURN_ERROR(ret,err)           \
+    getEGLThreadInfo()->eglError = err; \
+    return ret;
+
+#endif //LOG_EGL_ERRORS
+
+#define VALIDATE_CONFIG(cfg,ret) \
+    if(((int)cfg<0)||((int)cfg>s_display.getNumConfigs())) { \
+        RETURN_ERROR(ret,EGL_BAD_CONFIG); \
+    }
+
+#define VALIDATE_DISPLAY(dpy,ret) \
+    if ((dpy) != (EGLDisplay)&s_display) { \
+        RETURN_ERROR(ret, EGL_BAD_DISPLAY);    \
+    }
+
+#define VALIDATE_DISPLAY_INIT(dpy,ret) \
+    VALIDATE_DISPLAY(dpy, ret)    \
+    if (!s_display.initialized()) {        \
+        RETURN_ERROR(ret, EGL_NOT_INITIALIZED);    \
+    }
+
+#define DEFINE_HOST_CONNECTION \
+    HostConnection *hostCon = HostConnection::get(); \
+    renderControl_encoder_context_t *rcEnc = (hostCon ? hostCon->rcEncoder() : NULL)
+
+#define DEFINE_AND_VALIDATE_HOST_CONNECTION(ret) \
+    HostConnection *hostCon = HostConnection::get(); \
+    if (!hostCon) { \
+        ALOGE("egl: Failed to get host connection\n"); \
+        return ret; \
+    } \
+    renderControl_encoder_context_t *rcEnc = hostCon->rcEncoder(); \
+    if (!rcEnc) { \
+        ALOGE("egl: Failed to get renderControl encoder context\n"); \
+        return ret; \
+    }
+
+#define VALIDATE_CONTEXT_RETURN(context,ret)        \
+    if (!context) {                                    \
+        RETURN_ERROR(ret,EGL_BAD_CONTEXT);    \
+    }
+
+#define VALIDATE_SURFACE_RETURN(surface, ret)    \
+    if (surface != EGL_NO_SURFACE) {    \
+        egl_surface_t* s( static_cast<egl_surface_t*>(surface) );    \
+        if (s->dpy != (EGLDisplay)&s_display)    \
+            setErrorReturn(EGL_BAD_DISPLAY, EGL_FALSE);    \
+    }
+
+
+EGLContext_t::EGLContext_t(EGLDisplay dpy, EGLConfig config, EGLContext_t* shareCtx) :
+    dpy(dpy),
+    config(config),
+    read(EGL_NO_SURFACE),
+    draw(EGL_NO_SURFACE),
+    shareCtx(shareCtx),
+    rcContext(0),
+    versionString(NULL),
+    vendorString(NULL),
+    rendererString(NULL),
+    extensionString(NULL)
+{
+    flags = 0;
+    version = 1;
+    clientState = new GLClientState();
+    if (shareCtx)
+        sharedGroup = shareCtx->getSharedGroup();
+    else
+        sharedGroup = GLSharedGroupPtr(new GLSharedGroup());
+};
+
+EGLContext_t::~EGLContext_t()
+{
+    delete clientState;
+    delete [] versionString;
+    delete [] vendorString;
+    delete [] rendererString;
+    delete [] extensionString;
+}
+
+// ----------------------------------------------------------------------------
+//egl_surface_t
+
+//we don't need to handle depth since it's handled when window created on the host
+
+struct egl_surface_t {
+
+    EGLDisplay          dpy;
+    EGLConfig           config;
+
+
+    egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfaceType);
+    virtual     ~egl_surface_t();
+
+    virtual     void        setSwapInterval(int interval) = 0;
+    virtual     EGLBoolean  swapBuffers() = 0;
+
+    EGLint      getSwapBehavior() const;
+    uint32_t    getRcSurface()   { return rcSurface; }
+    EGLint      getSurfaceType() { return surfaceType; }
+
+    EGLint      getWidth(){ return width; }
+    EGLint      getHeight(){ return height; }
+    void        setTextureFormat(EGLint _texFormat) { texFormat = _texFormat; }
+    EGLint      getTextureFormat() { return texFormat; }
+    void        setTextureTarget(EGLint _texTarget) { texTarget = _texTarget; }
+    EGLint      getTextureTarget() { return texTarget; }
+
+private:
+    //
+    //Surface attributes
+    //
+    EGLint      width;
+    EGLint      height;
+    EGLint      texFormat;
+    EGLint      texTarget;
+
+protected:
+    void        setWidth(EGLint w)  { width = w;  }
+    void        setHeight(EGLint h) { height = h; }
+
+    EGLint      surfaceType;
+    uint32_t    rcSurface; //handle to surface created via remote control
+};
+
+egl_surface_t::egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfaceType)
+    : dpy(dpy), config(config), surfaceType(surfaceType), rcSurface(0)
+{
+    width = 0;
+    height = 0;
+    texFormat = EGL_NO_TEXTURE;
+    texTarget = EGL_NO_TEXTURE;
+}
+
+EGLint egl_surface_t::getSwapBehavior() const {
+    return EGL_BUFFER_PRESERVED;
+}
+
+egl_surface_t::~egl_surface_t()
+{
+}
+
+// ----------------------------------------------------------------------------
+// egl_window_surface_t
+
+struct egl_window_surface_t : public egl_surface_t {
+    static egl_window_surface_t* create(
+            EGLDisplay dpy, EGLConfig config, EGLint surfType,
+            ANativeWindow* window);
+
+    virtual ~egl_window_surface_t();
+
+    virtual void       setSwapInterval(int interval);
+    virtual EGLBoolean swapBuffers();
+
+private:
+    egl_window_surface_t(
+            EGLDisplay dpy, EGLConfig config, EGLint surfType,
+            ANativeWindow* window);
+    EGLBoolean init();
+
+    ANativeWindow*              nativeWindow;
+    android_native_buffer_t*    buffer;
+};
+
+egl_window_surface_t::egl_window_surface_t (
+        EGLDisplay dpy, EGLConfig config, EGLint surfType,
+        ANativeWindow* window)
+:   egl_surface_t(dpy, config, surfType),
+    nativeWindow(window),
+    buffer(NULL)
+{
+    // keep a reference on the window
+    nativeWindow->common.incRef(&nativeWindow->common);
+    EGLint w,h;
+    nativeWindow->query(nativeWindow, NATIVE_WINDOW_WIDTH, &w);
+    setWidth(w);
+    nativeWindow->query(nativeWindow, NATIVE_WINDOW_HEIGHT, &h);
+    setHeight(h);
+}
+
+EGLBoolean egl_window_surface_t::init()
+{
+    if (nativeWindow->dequeueBuffer_DEPRECATED(nativeWindow, &buffer) != NO_ERROR) {
+        setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE);
+    }
+
+    DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
+    rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uint32_t)config,
+            getWidth(), getHeight());
+    if (!rcSurface) {
+        ALOGE("rcCreateWindowSurface returned 0");
+        return EGL_FALSE;
+    }
+    rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface,
+            ((cb_handle_t*)(buffer->handle))->hostHandle);
+
+    return EGL_TRUE;
+}
+
+egl_window_surface_t* egl_window_surface_t::create(
+        EGLDisplay dpy, EGLConfig config, EGLint surfType,
+        ANativeWindow* window)
+{
+    egl_window_surface_t* wnd = new egl_window_surface_t(
+            dpy, config, surfType, window);
+    if (wnd && !wnd->init()) {
+        delete wnd;
+        wnd = NULL;
+    }
+    return wnd;
+}
+
+egl_window_surface_t::~egl_window_surface_t() {
+    DEFINE_HOST_CONNECTION;
+    if (rcSurface && rcEnc) {
+        rcEnc->rcDestroyWindowSurface(rcEnc, rcSurface);
+    }
+    if (buffer) {
+        nativeWindow->cancelBuffer_DEPRECATED(nativeWindow, buffer);
+    }
+    nativeWindow->common.decRef(&nativeWindow->common);
+}
+
+void egl_window_surface_t::setSwapInterval(int interval)
+{
+    nativeWindow->setSwapInterval(nativeWindow, interval);
+}
+
+EGLBoolean egl_window_surface_t::swapBuffers()
+{
+    DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
+
+    rcEnc->rcFlushWindowColorBuffer(rcEnc, rcSurface);
+
+    nativeWindow->queueBuffer_DEPRECATED(nativeWindow, buffer);
+    if (nativeWindow->dequeueBuffer_DEPRECATED(nativeWindow, &buffer)) {
+        buffer = NULL;
+        setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE);
+    }
+
+    rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface,
+            ((cb_handle_t *)(buffer->handle))->hostHandle);
+
+    return EGL_TRUE;
+}
+
+// ----------------------------------------------------------------------------
+//egl_pbuffer_surface_t
+
+struct egl_pbuffer_surface_t : public egl_surface_t {
+    static egl_pbuffer_surface_t* create(EGLDisplay dpy, EGLConfig config,
+            EGLint surfType, int32_t w, int32_t h, GLenum pixelFormat);
+
+    virtual ~egl_pbuffer_surface_t();
+
+    virtual void       setSwapInterval(int interval) {}
+    virtual EGLBoolean swapBuffers() { return EGL_TRUE; }
+
+    uint32_t getRcColorBuffer() { return rcColorBuffer; }
+
+private:
+    egl_pbuffer_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfType,
+            int32_t w, int32_t h);
+    EGLBoolean init(GLenum format);
+
+    uint32_t rcColorBuffer;
+};
+
+egl_pbuffer_surface_t::egl_pbuffer_surface_t(EGLDisplay dpy, EGLConfig config,
+        EGLint surfType, int32_t w, int32_t h)
+:   egl_surface_t(dpy, config, surfType),
+    rcColorBuffer(0)
+{
+    setWidth(w);
+    setHeight(h);
+}
+
+egl_pbuffer_surface_t::~egl_pbuffer_surface_t()
+{
+    DEFINE_HOST_CONNECTION;
+    if (rcEnc) {
+        if (rcColorBuffer) rcEnc->rcCloseColorBuffer(rcEnc, rcColorBuffer);
+        if (rcSurface)     rcEnc->rcDestroyWindowSurface(rcEnc, rcSurface);
+    }
+}
+
+EGLBoolean egl_pbuffer_surface_t::init(GLenum pixelFormat)
+{
+    DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
+
+    rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uint32_t)config,
+            getWidth(), getHeight());
+    if (!rcSurface) {
+        ALOGE("rcCreateWindowSurface returned 0");
+        return EGL_FALSE;
+    }
+
+    rcColorBuffer = rcEnc->rcCreateColorBuffer(rcEnc, getWidth(), getHeight(),
+            pixelFormat);
+    if (!rcColorBuffer) {
+        ALOGE("rcCreateColorBuffer returned 0");
+        return EGL_FALSE;
+    }
+
+    rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, rcColorBuffer);
+
+    return EGL_TRUE;
+}
+
+egl_pbuffer_surface_t* egl_pbuffer_surface_t::create(EGLDisplay dpy,
+        EGLConfig config, EGLint surfType, int32_t w, int32_t h,
+        GLenum pixelFormat)
+{
+    egl_pbuffer_surface_t* pb = new egl_pbuffer_surface_t(dpy, config, surfType,
+            w, h);
+    if (pb && !pb->init(pixelFormat)) {
+        delete pb;
+        pb = NULL;
+    }
+    return pb;
+}
+
+static const char *getGLString(int glEnum)
+{
+    EGLThreadInfo *tInfo = getEGLThreadInfo();
+    if (!tInfo || !tInfo->currentContext) {
+        return NULL;
+    }
+
+    const char** strPtr = NULL;
+
+#define GL_VENDOR                         0x1F00
+#define GL_RENDERER                       0x1F01
+#define GL_VERSION                        0x1F02
+#define GL_EXTENSIONS                     0x1F03
+
+    switch(glEnum) {
+        case GL_VERSION:
+            strPtr = &tInfo->currentContext->versionString;
+            break;
+        case GL_VENDOR:
+            strPtr = &tInfo->currentContext->vendorString;
+            break;
+        case GL_RENDERER:
+            strPtr = &tInfo->currentContext->rendererString;
+            break;
+        case GL_EXTENSIONS:
+            strPtr = &tInfo->currentContext->extensionString;
+            break;
+    }
+
+    if (!strPtr) {
+        return NULL;
+    }
+
+    if (*strPtr != NULL) {
+        //
+        // string is already cached
+        //
+        return *strPtr;
+    }
+
+    //
+    // first query of that string - need to query host
+    //
+    DEFINE_AND_VALIDATE_HOST_CONNECTION(NULL);
+    char *hostStr = NULL;
+    int n = rcEnc->rcGetGLString(rcEnc, glEnum, NULL, 0);
+    if (n < 0) {
+        hostStr = new char[-n+1];
+        n = rcEnc->rcGetGLString(rcEnc, glEnum, hostStr, -n);
+        if (n <= 0) {
+            delete [] hostStr;
+            hostStr = NULL;
+        }
+    }
+
+    //
+    // keep the string in the context and return its value
+    //
+    *strPtr = hostStr;
+    return hostStr;
+}
+
+// ----------------------------------------------------------------------------
+
+// The one and only supported display object.
+static eglDisplay s_display;
+
+static EGLClient_eglInterface s_eglIface = {
+    getThreadInfo: getEGLThreadInfo,
+    getGLString: getGLString
+};
+
+#define DBG_FUNC DBG("%s\n", __FUNCTION__)
+EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id)
+{
+    //
+    // we support only EGL_DEFAULT_DISPLAY.
+    //
+    if (display_id != EGL_DEFAULT_DISPLAY) {
+        return EGL_NO_DISPLAY;
+    }
+
+    return (EGLDisplay)&s_display;
+}
+
+EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+    VALIDATE_DISPLAY(dpy,EGL_FALSE);
+
+    if (!s_display.initialize(&s_eglIface)) {
+        return EGL_FALSE;
+    }
+    if (major!=NULL)
+        *major = s_display.getVersionMajor();
+    if (minor!=NULL)
+        *minor = s_display.getVersionMinor();
+    return EGL_TRUE;
+}
+
+EGLBoolean eglTerminate(EGLDisplay dpy)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
+
+    s_display.terminate();
+    return EGL_TRUE;
+}
+
+EGLint eglGetError()
+{
+    EGLint error = getEGLThreadInfo()->eglError;
+    getEGLThreadInfo()->eglError = EGL_SUCCESS;
+    return error;
+}
+
+__eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
+{
+    // search in EGL function table
+    for (int i=0; i<egl_num_funcs; i++) {
+        if (!strcmp(egl_funcs_by_name[i].name, procname)) {
+            return (__eglMustCastToProperFunctionPointerType)egl_funcs_by_name[i].proc;
+        }
+    }
+
+    //
+    // Make sure display is initialized before searching in client APIs
+    //
+    if (!s_display.initialized()) {
+        if (!s_display.initialize(&s_eglIface)) {
+            return NULL;
+        }
+    }
+
+    // look in gles client api's extensions table
+    return (__eglMustCastToProperFunctionPointerType)ClientAPIExts::getProcAddress(procname);
+
+    // Fail - function not found.
+    return NULL;
+}
+
+const char* eglQueryString(EGLDisplay dpy, EGLint name)
+{
+    VALIDATE_DISPLAY_INIT(dpy, NULL);
+
+    return s_display.queryString(name);
+}
+
+EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+    VALIDATE_DISPLAY_INIT(dpy, NULL);
+
+    if(!num_config) {
+        RETURN_ERROR(EGL_FALSE,EGL_BAD_PARAMETER);
+    }
+
+    GLint numConfigs = s_display.getNumConfigs();
+    if (!configs) {
+        *num_config = numConfigs;
+        return EGL_TRUE;
+    }
+
+    int i=0;
+    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)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
+
+    int attribs_size = 0;
+    if (attrib_list) {
+        const EGLint * attrib_p = attrib_list;
+        while (attrib_p[0] != EGL_NONE) {
+            attribs_size += 2;
+            attrib_p += 2;
+        }
+        attribs_size++; //for the terminating EGL_NONE
+    }
+
+    DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
+    *num_config = rcEnc->rcChooseConfig(rcEnc, (EGLint*)attrib_list, attribs_size * sizeof(EGLint), (uint32_t*)configs, config_size);
+
+    return EGL_TRUE;
+}
+
+EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
+{
+    VALIDATE_DISPLAY_INIT(dpy, NULL);
+    VALIDATE_CONFIG(config, EGL_FALSE);
+
+    if (s_display.getConfigAttrib(config, attribute, value))
+    {
+        return EGL_TRUE;
+    }
+    else
+    {
+        RETURN_ERROR(EGL_FALSE, EGL_BAD_ATTRIBUTE);
+    }
+}
+
+EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
+{
+    VALIDATE_DISPLAY_INIT(dpy, NULL);
+    VALIDATE_CONFIG(config, EGL_FALSE);
+    if (win == 0) {
+        setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
+    }
+
+    EGLint surfaceType;
+    if (s_display.getConfigAttrib(config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE)    return EGL_FALSE;
+
+    if (!(surfaceType & EGL_WINDOW_BIT)) {
+        setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
+    }
+
+    if (static_cast<ANativeWindow*>(win)->common.magic != ANDROID_NATIVE_WINDOW_MAGIC) {
+        setErrorReturn(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+    }
+
+    egl_surface_t* surface = egl_window_surface_t::create(
+            &s_display, config, surfaceType, static_cast<ANativeWindow*>(win));
+    if (!surface) {
+        setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+    }
+
+    return surface;
+}
+
+EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
+{
+    VALIDATE_DISPLAY_INIT(dpy, NULL);
+    VALIDATE_CONFIG(config, EGL_FALSE);
+
+    EGLint surfaceType;
+    if (s_display.getConfigAttrib(config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE)    return EGL_FALSE;
+
+    if (!(surfaceType & EGL_PBUFFER_BIT)) {
+        setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
+    }
+
+    int32_t w = 0;
+    int32_t h = 0;
+    EGLint texFormat = EGL_NO_TEXTURE;
+    EGLint texTarget = EGL_NO_TEXTURE;
+    while (attrib_list[0]) {
+        switch (attrib_list[0]) {
+            case EGL_WIDTH:
+                w = attrib_list[1];
+                break;
+            case EGL_HEIGHT:
+                h = attrib_list[1];
+                break;
+            case EGL_TEXTURE_FORMAT:
+                texFormat = attrib_list[1];
+                break;
+            case EGL_TEXTURE_TARGET:
+                texTarget = attrib_list[1];
+                break;
+            default:
+                break;
+        };
+        attrib_list+=2;
+    }
+    if (((texFormat == EGL_NO_TEXTURE)&&(texTarget != EGL_NO_TEXTURE)) ||
+        ((texFormat != EGL_NO_TEXTURE)&&(texTarget == EGL_NO_TEXTURE))) {
+        setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
+    }
+    // TODO: check EGL_TEXTURE_FORMAT - need to support eglBindTexImage
+
+    GLenum pixelFormat;
+    if (s_display.getConfigGLPixelFormat(config, &pixelFormat) == EGL_FALSE)
+        setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE);
+
+    egl_surface_t* surface = egl_pbuffer_surface_t::create(dpy, config,
+            surfaceType, w, h, pixelFormat);
+    if (!surface) {
+        setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+    }
+
+    //setup attributes
+    surface->setTextureFormat(texFormat);
+    surface->setTextureTarget(texTarget);
+
+    return surface;
+}
+
+EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
+{
+    //XXX: Pixmap not supported. The host cannot render to a pixmap resource
+    //     located on host. In order to support Pixmaps we should either punt
+    //     to s/w rendering -or- let the host render to a buffer that will be
+    //     copied back to guest at some sync point. None of those methods not
+    //     implemented and pixmaps are not used with OpenGL anyway ...
+    return EGL_NO_SURFACE;
+}
+
+EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface eglSurface)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
+    VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE);
+
+    egl_surface_t* surface(static_cast<egl_surface_t*>(eglSurface));
+    delete surface;
+
+    return EGL_TRUE;
+}
+
+EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface eglSurface, EGLint attribute, EGLint *value)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
+    VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE);
+
+    egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) );
+    EGLBoolean ret = EGL_TRUE;
+    switch (attribute) {
+        case EGL_CONFIG_ID:
+            ret = s_display.getConfigAttrib(surface->config, EGL_CONFIG_ID, value);
+            break;
+        case EGL_WIDTH:
+            *value = surface->getWidth();
+            break;
+        case EGL_HEIGHT:
+            *value = surface->getHeight();
+            break;
+        case EGL_TEXTURE_FORMAT:
+            *value = surface->getTextureFormat();
+            break;
+        case EGL_TEXTURE_TARGET:
+            *value = surface->getTextureTarget();
+            break;
+        case EGL_SWAP_BEHAVIOR:
+            *value = surface->getSwapBehavior();
+            break;
+        case EGL_LARGEST_PBUFFER:
+            // not modified for a window or pixmap surface
+            // and we ignore it when creating a PBuffer surface (default is EGL_FALSE)
+            if (surface->getSurfaceType() & EGL_PBUFFER_BIT) *value = EGL_FALSE;
+            break;
+        //TODO: complete other attributes
+        default:
+            ALOGE("eglQuerySurface %x  EGL_BAD_ATTRIBUTE", attribute);
+            ret = setErrorFunc(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+            break;
+    }
+
+    return ret;
+}
+
+EGLBoolean eglBindAPI(EGLenum api)
+{
+    if (api != EGL_OPENGL_ES_API)
+        setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
+    return EGL_TRUE;
+}
+
+EGLenum eglQueryAPI()
+{
+    return EGL_OPENGL_ES_API;
+}
+
+EGLBoolean eglWaitClient()
+{
+    return eglWaitGL();
+}
+
+EGLBoolean eglReleaseThread()
+{
+    EGLThreadInfo *tInfo = getEGLThreadInfo();
+    if (tInfo && tInfo->currentContext) {
+        return eglMakeCurrent(&s_display, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
+    }
+    return EGL_TRUE;
+}
+
+EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
+{
+    //TODO
+    ALOGW("%s not implemented", __FUNCTION__);
+    return 0;
+}
+
+EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
+{
+    //TODO
+    ALOGW("%s not implemented", __FUNCTION__);
+    return 0;
+}
+
+EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface eglSurface, EGLint buffer)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
+    VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE);
+    if (eglSurface == EGL_NO_SURFACE) {
+        setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
+    }
+
+    if (buffer != EGL_BACK_BUFFER) {
+        setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
+    }
+
+    egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) );
+
+    if (surface->getTextureFormat() == EGL_NO_TEXTURE) {
+        setErrorReturn(EGL_BAD_MATCH, EGL_FALSE);
+    }
+
+    if (!(surface->getSurfaceType() & EGL_PBUFFER_BIT)) {
+        setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
+    }
+
+    //It's now safe to cast to pbuffer surface
+    egl_pbuffer_surface_t* pbSurface = (egl_pbuffer_surface_t*)surface;
+
+    DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
+    rcEnc->rcBindTexture(rcEnc, pbSurface->getRcColorBuffer());
+
+    return GL_TRUE;
+}
+
+EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+    //TODO
+    ALOGW("%s not implemented", __FUNCTION__);
+    return 0;
+}
+
+EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
+    DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
+
+    EGLContext_t* ctx = getEGLThreadInfo()->currentContext;
+    if (!ctx) {
+        setErrorReturn(EGL_BAD_CONTEXT, EGL_FALSE);
+    }
+    if (!ctx->draw) {
+        setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
+    }
+    egl_surface_t* draw(static_cast<egl_surface_t*>(ctx->draw));
+    draw->setSwapInterval(interval);
+
+    rcEnc->rcFBSetSwapInterval(rcEnc, interval); //TODO: implement on the host
+
+    return EGL_TRUE;
+}
+
+EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_NO_CONTEXT);
+    VALIDATE_CONFIG(config, EGL_NO_CONTEXT);
+
+    EGLint version = 1; //default
+    while (attrib_list && attrib_list[0]) {
+        if (attrib_list[0] == EGL_CONTEXT_CLIENT_VERSION) version = attrib_list[1];
+        attrib_list+=2;
+    }
+
+    uint32_t rcShareCtx = 0;
+    EGLContext_t * shareCtx = NULL;
+    if (share_context) {
+        shareCtx = static_cast<EGLContext_t*>(share_context);
+        rcShareCtx = shareCtx->rcContext;
+        if (shareCtx->dpy != dpy)
+            setErrorReturn(EGL_BAD_MATCH, EGL_NO_CONTEXT);
+    }
+
+    DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_NO_CONTEXT);
+    uint32_t rcContext = rcEnc->rcCreateContext(rcEnc, (uint32_t)config, rcShareCtx, version);
+    if (!rcContext) {
+        ALOGE("rcCreateContext returned 0");
+        setErrorReturn(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
+    }
+
+    EGLContext_t * context = new EGLContext_t(dpy, config, shareCtx);
+    if (!context)
+        setErrorReturn(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
+
+    context->version = version;
+    context->rcContext = rcContext;
+
+
+    return context;
+}
+
+EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
+    VALIDATE_CONTEXT_RETURN(ctx, EGL_FALSE);
+
+    EGLContext_t * context = static_cast<EGLContext_t*>(ctx);
+
+    if (getEGLThreadInfo()->currentContext == context)
+    {
+        eglMakeCurrent(dpy, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
+    }
+
+    if (context->rcContext) {
+        DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
+        rcEnc->rcDestroyContext(rcEnc, context->rcContext);
+        context->rcContext = 0;
+    }
+
+    delete context;
+    return EGL_TRUE;
+}
+
+EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
+    VALIDATE_SURFACE_RETURN(draw, EGL_FALSE);
+    VALIDATE_SURFACE_RETURN(read, EGL_FALSE);
+
+    if ((read == EGL_NO_SURFACE && draw == EGL_NO_SURFACE) && (ctx != EGL_NO_CONTEXT))
+        setErrorReturn(EGL_BAD_MATCH, EGL_FALSE);
+    if ((read != EGL_NO_SURFACE || draw != EGL_NO_SURFACE) && (ctx == EGL_NO_CONTEXT))
+        setErrorReturn(EGL_BAD_MATCH, EGL_FALSE);
+
+    EGLContext_t * context = static_cast<EGLContext_t*>(ctx);
+    uint32_t ctxHandle = (context) ? context->rcContext : 0;
+    egl_surface_t * drawSurf = static_cast<egl_surface_t *>(draw);
+    uint32_t drawHandle = (drawSurf) ? drawSurf->getRcSurface() : 0;
+    egl_surface_t * readSurf = static_cast<egl_surface_t *>(read);
+    uint32_t readHandle = (readSurf) ? readSurf->getRcSurface() : 0;
+
+    //
+    // Nothing to do if no binding change has made
+    //
+    EGLThreadInfo *tInfo = getEGLThreadInfo();
+    if (tInfo->currentContext == context &&
+        (context == NULL ||
+        (context && context->draw == draw && context->read == read))) {
+        return EGL_TRUE;
+    }
+
+    if (context && (context->flags & EGLContext_t::IS_CURRENT) && (context != tInfo->currentContext)) {
+        //context is current to another thread
+        setErrorReturn(EGL_BAD_ACCESS, EGL_FALSE);
+    }
+
+    DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
+    if (rcEnc->rcMakeCurrent(rcEnc, ctxHandle, drawHandle, readHandle) == EGL_FALSE) {
+        ALOGE("rcMakeCurrent returned EGL_FALSE");
+        setErrorReturn(EGL_BAD_CONTEXT, EGL_FALSE);
+    }
+
+    //Now make the local bind
+    if (context) {
+        context->draw = draw;
+        context->read = read;
+        context->flags |= EGLContext_t::IS_CURRENT;
+        //set the client state
+        if (context->version == 2) {
+            hostCon->gl2Encoder()->setClientState(context->getClientState());
+            hostCon->gl2Encoder()->setSharedGroup(context->getSharedGroup());
+        }
+        else {
+            hostCon->glEncoder()->setClientState(context->getClientState());
+            hostCon->glEncoder()->setSharedGroup(context->getSharedGroup());
+        }
+    } 
+    else {
+        //release ClientState & SharedGroup
+        if (tInfo->currentContext->version == 2) {
+            hostCon->gl2Encoder()->setClientState(NULL);
+            hostCon->gl2Encoder()->setSharedGroup(GLSharedGroupPtr(NULL));
+        }
+        else {
+            hostCon->glEncoder()->setClientState(NULL);
+            hostCon->glEncoder()->setSharedGroup(GLSharedGroupPtr(NULL));
+        }
+
+    }
+
+    if (tInfo->currentContext)
+        tInfo->currentContext->flags &= ~EGLContext_t::IS_CURRENT;
+
+    //Now make current
+    tInfo->currentContext = context;
+
+    //Check maybe we need to init the encoder, if it's first eglMakeCurrent
+    if (tInfo->currentContext) {
+        if (tInfo->currentContext->version == 2) {
+            if (!hostCon->gl2Encoder()->isInitialized()) {
+                s_display.gles2_iface()->init();
+                hostCon->gl2Encoder()->setInitialized();
+                ClientAPIExts::initClientFuncs(s_display.gles2_iface(), 1);
+            }
+        }
+        else {
+            if (!hostCon->glEncoder()->isInitialized()) {
+                s_display.gles_iface()->init();
+                hostCon->glEncoder()->setInitialized();
+                ClientAPIExts::initClientFuncs(s_display.gles_iface(), 0);
+            }
+        }
+    }
+
+    return EGL_TRUE;
+}
+
+EGLContext eglGetCurrentContext()
+{
+    return getEGLThreadInfo()->currentContext;
+}
+
+EGLSurface eglGetCurrentSurface(EGLint readdraw)
+{
+    EGLContext_t * context = getEGLThreadInfo()->currentContext;
+    if (!context)
+        return EGL_NO_SURFACE; //not an error
+
+    switch (readdraw) {
+        case EGL_READ:
+            return context->read;
+        case EGL_DRAW:
+            return context->draw;
+        default:
+            setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
+    }
+}
+
+EGLDisplay eglGetCurrentDisplay()
+{
+    EGLContext_t * context = getEGLThreadInfo()->currentContext;
+    if (!context)
+        return EGL_NO_DISPLAY; //not an error
+
+    return context->dpy;
+}
+
+EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
+    VALIDATE_CONTEXT_RETURN(ctx, EGL_FALSE);
+
+    EGLContext_t * context = static_cast<EGLContext_t*>(ctx);
+
+    EGLBoolean ret = EGL_TRUE;
+    switch (attribute) {
+        case EGL_CONFIG_ID:
+            ret = s_display.getConfigAttrib(context->config, EGL_CONFIG_ID, value);
+            break;
+        case EGL_CONTEXT_CLIENT_TYPE:
+            *value = EGL_OPENGL_ES_API;
+            break;
+        case EGL_CONTEXT_CLIENT_VERSION:
+            *value = context->version;
+            break;
+        case EGL_RENDER_BUFFER:
+            if (!context->draw)
+                *value = EGL_NONE;
+            else
+                *value = EGL_BACK_BUFFER; //single buffer not supported
+            break;
+        default:
+            ALOGE("eglQueryContext %x  EGL_BAD_ATTRIBUTE", attribute);
+            setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+            break;
+    }
+
+    return ret;
+}
+
+EGLBoolean eglWaitGL()
+{
+    EGLThreadInfo *tInfo = getEGLThreadInfo();
+    if (!tInfo || !tInfo->currentContext) {
+        return EGL_FALSE;
+    }
+
+    if (tInfo->currentContext->version == 2) {
+        s_display.gles2_iface()->finish();
+    }
+    else {
+        s_display.gles_iface()->finish();
+    }
+
+    return EGL_TRUE;
+}
+
+EGLBoolean eglWaitNative(EGLint engine)
+{
+    return EGL_TRUE;
+}
+
+EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface eglSurface)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
+    if (eglSurface == EGL_NO_SURFACE)
+        setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE);
+
+    DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE);
+
+    egl_surface_t* d = static_cast<egl_surface_t*>(eglSurface);
+    if (d->dpy != dpy)
+        setErrorReturn(EGL_BAD_DISPLAY, EGL_FALSE);
+
+    // post the surface
+    d->swapBuffers();
+
+    hostCon->flush();
+    return EGL_TRUE;
+}
+
+EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
+{
+    //TODO :later
+    return 0;
+}
+
+EGLBoolean eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list)
+{
+    //TODO later
+    return 0;
+}
+
+EGLBoolean eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface)
+{
+    //TODO later
+    return 0;
+}
+
+EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_NO_IMAGE_KHR);
+    if (ctx != EGL_NO_CONTEXT) {
+        setErrorReturn(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
+    }
+    if (target != EGL_NATIVE_BUFFER_ANDROID) {
+        setErrorReturn(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)
+        setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+
+    if (native_buffer->common.version != sizeof(android_native_buffer_t))
+        setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+
+    cb_handle_t *cb = (cb_handle_t *)(native_buffer->handle);
+
+    switch (cb->format) {
+        case HAL_PIXEL_FORMAT_RGBA_8888:
+        case HAL_PIXEL_FORMAT_RGBX_8888:
+        case HAL_PIXEL_FORMAT_RGB_888:
+        case HAL_PIXEL_FORMAT_RGB_565:
+        case HAL_PIXEL_FORMAT_BGRA_8888:
+        case HAL_PIXEL_FORMAT_RGBA_5551:
+        case HAL_PIXEL_FORMAT_RGBA_4444:
+            break;
+        default:
+            setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
+    }
+
+    native_buffer->common.incRef(&native_buffer->common);
+    return (EGLImageKHR)native_buffer;
+}
+
+EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
+{
+    VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE);
+    android_native_buffer_t* native_buffer = (android_native_buffer_t*)img;
+
+    if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
+        setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
+
+    if (native_buffer->common.version != sizeof(android_native_buffer_t))
+        setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
+
+    native_buffer->common.decRef(&native_buffer->common);
+
+    return EGL_TRUE;
+}
+
+#define FENCE_SYNC_HANDLE (EGLSyncKHR)0xFE4CE
+
+EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type,
+        const EGLint *attrib_list)
+{
+    // TODO: This implementation could be faster. We should require the host EGL
+    // to support KHR_fence_sync, or at least pipe the fence command to the host
+    // and wait for it (probably involving a glFinish on the host) in
+    // eglClientWaitSyncKHR.
+
+    VALIDATE_DISPLAY(dpy, EGL_NO_SYNC_KHR);
+
+    if (type != EGL_SYNC_FENCE_KHR ||
+            (attrib_list != NULL && attrib_list[0] != EGL_NONE)) {
+        setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR);
+    }
+
+    EGLThreadInfo *tInfo = getEGLThreadInfo();
+    if (!tInfo || !tInfo->currentContext) {
+        setErrorReturn(EGL_BAD_MATCH, EGL_NO_SYNC_KHR);
+    }
+
+    if (tInfo->currentContext->version == 2) {
+        s_display.gles2_iface()->finish();
+    } else {
+        s_display.gles_iface()->finish();
+    }
+
+    return FENCE_SYNC_HANDLE;
+}
+
+EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
+{
+    if (sync != FENCE_SYNC_HANDLE) {
+        setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
+    }
+
+    return EGL_TRUE;
+}
+
+EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags,
+        EGLTimeKHR timeout)
+{
+    if (sync != FENCE_SYNC_HANDLE) {
+        setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
+    }
+
+    return EGL_CONDITION_SATISFIED_KHR;
+}
+
+EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync,
+        EGLint attribute, EGLint *value)
+{
+    if (sync != FENCE_SYNC_HANDLE) {
+        setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE);
+    }
+
+    switch (attribute) {
+    case EGL_SYNC_TYPE_KHR:
+        *value = EGL_SYNC_FENCE_KHR;
+        return EGL_TRUE;
+    case EGL_SYNC_STATUS_KHR:
+        *value = EGL_SIGNALED_KHR;
+        return EGL_TRUE;
+    case EGL_SYNC_CONDITION_KHR:
+        *value = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR;
+        return EGL_TRUE;
+    default:
+        setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+    }
+}
diff --git a/system/egl/eglContext.h b/system/egl/eglContext.h
new file mode 100644
index 0000000..2ca6d0c
--- /dev/null
+++ b/system/egl/eglContext.h
@@ -0,0 +1,51 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _EGL_CONTEXT_H
+#define _EGL_CONTEXT_H
+
+#include "GLClientState.h"
+#include "GLSharedGroup.h"
+
+struct EGLContext_t {
+
+    enum {
+        IS_CURRENT      =   0x00010000,
+        NEVER_CURRENT   =   0x00020000
+    };
+
+    EGLContext_t(EGLDisplay dpy, EGLConfig config, EGLContext_t* shareCtx);
+    ~EGLContext_t();
+    uint32_t            flags;
+    EGLDisplay          dpy;
+    EGLConfig           config;
+    EGLSurface          read;
+    EGLSurface          draw;
+    EGLContext_t    *   shareCtx;
+    EGLint                version;
+    uint32_t             rcContext;
+    const char*         versionString;
+    const char*         vendorString;
+    const char*         rendererString;
+    const char*         extensionString;
+
+    GLClientState * getClientState(){ return clientState; }
+    GLSharedGroupPtr getSharedGroup(){ return sharedGroup; }
+private:
+    GLClientState    *    clientState;
+    GLSharedGroupPtr      sharedGroup;
+};
+
+#endif
diff --git a/system/egl/eglDisplay.cpp b/system/egl/eglDisplay.cpp
new file mode 100644
index 0000000..bcb0d4b
--- /dev/null
+++ b/system/egl/eglDisplay.cpp
@@ -0,0 +1,497 @@
+/*
+* Copyright (C) 2011 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 "eglDisplay.h"
+#include "HostConnection.h"
+#include <dlfcn.h>
+
+static const int systemEGLVersionMajor = 1;
+static const int systemEGLVersionMinor = 4;
+static const char systemEGLVendor[] = "Google Android emulator";
+
+// list of extensions supported by this EGL implementation
+//  NOTE that each extension name should be suffixed with space
+static const char systemStaticEGLExtensions[] =
+            "EGL_ANDROID_image_native_buffer "
+            "EGL_KHR_fence_sync ";
+
+// list of extensions supported by this EGL implementation only if supported
+// on the host implementation.
+//  NOTE that each extension name should be suffixed with space
+static const char systemDynamicEGLExtensions[] =
+            "EGL_KHR_image_base "
+            "EGL_KHR_gl_texture_2d_image ";
+
+
+static void *s_gles_lib = NULL;
+static void *s_gles2_lib = NULL;
+
+// The following function will be called when we (libEGL)
+// gets unloaded
+// At this point we want to unload the gles libraries we
+// might have loaded during initialization
+static void __attribute__ ((destructor)) do_on_unload(void)
+{
+    if (s_gles_lib) {
+        dlclose(s_gles_lib);
+    }
+
+    if (s_gles2_lib) {
+        dlclose(s_gles2_lib);
+    }
+}
+
+eglDisplay::eglDisplay() :
+    m_initialized(false),
+    m_major(0),
+    m_minor(0),
+    m_hostRendererVersion(0),
+    m_numConfigs(0),
+    m_numConfigAttribs(0),
+    m_attribs(DefaultKeyedVector<EGLint, EGLint>(ATTRIBUTE_NONE)),
+    m_configs(NULL),
+    m_gles_iface(NULL),
+    m_gles2_iface(NULL),
+    m_versionString(NULL),
+    m_vendorString(NULL),
+    m_extensionString(NULL)
+{
+    pthread_mutex_init(&m_lock, NULL);
+}
+
+eglDisplay::~eglDisplay()
+{
+    pthread_mutex_destroy(&m_lock);
+}
+
+bool eglDisplay::initialize(EGLClient_eglInterface *eglIface)
+{
+    pthread_mutex_lock(&m_lock);
+    if (!m_initialized) {
+
+        //
+        // load GLES client API
+        //
+        m_gles_iface = loadGLESClientAPI("/system/lib/egl/libGLESv1_CM_emulation.so",
+                                         eglIface,
+                                         &s_gles_lib);
+        if (!m_gles_iface) {
+            pthread_mutex_unlock(&m_lock);
+            ALOGE("Failed to load gles1 iface");
+            return false;
+        }
+
+#ifdef WITH_GLES2
+        m_gles2_iface = loadGLESClientAPI("/system/lib/egl/libGLESv2_emulation.so",
+                                          eglIface,
+                                          &s_gles2_lib);
+        // Note that if loading gles2 failed, we can still run with no
+        // GLES2 support, having GLES2 is not mandatory.
+#endif
+
+        //
+        // establish connection with the host
+        //
+        HostConnection *hcon = HostConnection::get();
+        if (!hcon) {
+            pthread_mutex_unlock(&m_lock);
+            ALOGE("Failed to establish connection with the host\n");
+            return false;
+        }
+
+        //
+        // get renderControl encoder instance
+        //
+        renderControl_encoder_context_t *rcEnc = hcon->rcEncoder();
+        if (!rcEnc) {
+            pthread_mutex_unlock(&m_lock);
+            ALOGE("Failed to get renderControl encoder instance");
+            return false;
+        }
+
+        //
+        // Query host reneder and EGL version
+        //
+        m_hostRendererVersion = rcEnc->rcGetRendererVersion(rcEnc);
+        EGLint status = rcEnc->rcGetEGLVersion(rcEnc, &m_major, &m_minor);
+        if (status != EGL_TRUE) {
+            // host EGL initialization failed !!
+            pthread_mutex_unlock(&m_lock);
+            return false;
+        }
+
+        //
+        // Take minimum version beween what we support and what the host support
+        //
+        if (m_major > systemEGLVersionMajor) {
+            m_major = systemEGLVersionMajor;
+            m_minor = systemEGLVersionMinor;
+        }
+        else if (m_major == systemEGLVersionMajor &&
+                 m_minor > systemEGLVersionMinor) {
+            m_minor = systemEGLVersionMinor;
+        }
+
+        //
+        // Query the host for the set of configs
+        //
+        m_numConfigs = rcEnc->rcGetNumConfigs(rcEnc, (uint32_t*)&m_numConfigAttribs);
+        if (m_numConfigs <= 0 || m_numConfigAttribs <= 0) {
+            // just sanity check - should never happen
+            pthread_mutex_unlock(&m_lock);
+            return false;
+        }
+
+        uint32_t nInts = m_numConfigAttribs * (m_numConfigs + 1);
+        EGLint tmp_buf[nInts];
+        m_configs = new EGLint[nInts-m_numConfigAttribs];
+        if (!m_configs) {
+            pthread_mutex_unlock(&m_lock);
+            return false;
+        }
+
+        //EGLint n = rcEnc->rcGetConfigs(rcEnc, nInts*sizeof(EGLint), m_configs);
+        EGLint n = rcEnc->rcGetConfigs(rcEnc, nInts*sizeof(EGLint), (GLuint*)tmp_buf);
+        if (n != m_numConfigs) {
+            pthread_mutex_unlock(&m_lock);
+            return false;
+        }
+
+        //Fill the attributes vector.
+        //The first m_numConfigAttribs values of tmp_buf are the actual attributes enums.
+        for (int i=0; i<m_numConfigAttribs; i++) {
+            m_attribs.add(tmp_buf[i], i);
+        }
+
+        //Copy the actual configs data to m_configs
+        memcpy(m_configs, tmp_buf + m_numConfigAttribs, m_numConfigs*m_numConfigAttribs*sizeof(EGLint));
+
+        m_initialized = true;
+    }
+    pthread_mutex_unlock(&m_lock);
+
+    processConfigs();
+
+    return true;
+}
+
+void eglDisplay::processConfigs()
+{
+    for (int i=0; i<m_numConfigs; i++) {
+        EGLConfig config = (EGLConfig)i;
+        //Setup the EGL_NATIVE_VISUAL_ID attribute
+        PixelFormat format;
+        if (getConfigNativePixelFormat(config, &format)) {
+            setConfigAttrib(config, EGL_NATIVE_VISUAL_ID, format);
+        }
+    }
+}
+
+void eglDisplay::terminate()
+{
+    pthread_mutex_lock(&m_lock);
+    if (m_initialized) {
+        m_initialized = false;
+        delete [] m_configs;
+        m_configs = NULL;
+
+        if (m_versionString) {
+            free(m_versionString);
+            m_versionString = NULL;
+        }
+        if (m_vendorString) {
+            free(m_vendorString);
+            m_vendorString = NULL;
+        }
+        if (m_extensionString) {
+            free(m_extensionString);
+            m_extensionString = NULL;
+        }
+    }
+    pthread_mutex_unlock(&m_lock);
+}
+
+EGLClient_glesInterface *eglDisplay::loadGLESClientAPI(const char *libName,
+                                                       EGLClient_eglInterface *eglIface,
+                                                       void **libHandle)
+{
+    void *lib = dlopen(libName, RTLD_NOW);
+    if (!lib) {
+        ALOGE("Failed to dlopen %s", libName);
+        return NULL;
+    }
+
+    init_emul_gles_t init_gles_func = (init_emul_gles_t)dlsym(lib,"init_emul_gles");
+    if (!init_gles_func) {
+        ALOGE("Failed to find init_emul_gles");
+        dlclose((void*)lib);
+        return NULL;
+    }
+
+    *libHandle = lib;
+    return (*init_gles_func)(eglIface);
+}
+
+static char *queryHostEGLString(EGLint name)
+{
+    HostConnection *hcon = HostConnection::get();
+    if (hcon) {
+        renderControl_encoder_context_t *rcEnc = hcon->rcEncoder();
+        if (rcEnc) {
+            int n = rcEnc->rcQueryEGLString(rcEnc, name, NULL, 0);
+            if (n < 0) {
+                // allocate space for the string with additional
+                // space charachter to be suffixed at the end.
+                char *str = (char *)malloc(-n+2);
+                n = rcEnc->rcQueryEGLString(rcEnc, name, str, -n);
+                if (n > 0) {
+                    // add extra space at end of string which will be
+                    // needed later when filtering the extension list.
+                    strcat(str, " ");
+                    return str;
+                }
+
+                free(str);
+            }
+        }
+    }
+
+    return NULL;
+}
+
+static bool findExtInList(const char* token, int tokenlen, const char* list)
+{
+    const char* p = list;
+    while (*p != '\0') {
+        const char* q = strchr(p, ' ');
+        if (q == NULL) {
+            /* should not happen, list must be space-terminated */
+            break;
+        }
+        if (tokenlen == (q - p) && !memcmp(token, p, tokenlen)) {
+            return true;  /* found it */
+        }
+        p = q+1;
+    }
+    return false;  /* not found */
+}
+
+static char *buildExtensionString()
+{
+    //Query host extension string
+    char *hostExt = queryHostEGLString(EGL_EXTENSIONS);
+    if (!hostExt || (hostExt[1] == '\0')) {
+        // no extensions on host - only static extension list supported
+        return strdup(systemStaticEGLExtensions);
+    }
+
+    //
+    // Filter host extension list to include only extensions
+    // we can support (in the systemDynamicEGLExtensions list)
+    //
+    char *ext = (char *)hostExt;
+    char *c = ext;
+    char *insert = ext;
+    while(*c != '\0') {
+        if (*c == ' ') {
+            int len = c - ext;
+            if (findExtInList(ext, len, systemDynamicEGLExtensions)) {
+                if (ext != insert) {
+                    memcpy(insert, ext, len+1); // including space
+                }
+                insert += (len + 1);
+            }
+            ext = c + 1;
+        }
+        c++;
+    }
+    *insert = '\0';
+
+    int n = strlen(hostExt);
+    if (n > 0) {
+        char *str;
+        asprintf(&str,"%s%s", systemStaticEGLExtensions, hostExt);
+        free((char*)hostExt);
+        return str;
+    }
+    else {
+        free((char*)hostExt);
+        return strdup(systemStaticEGLExtensions);
+    }
+}
+
+const char *eglDisplay::queryString(EGLint name)
+{
+    if (name == EGL_CLIENT_APIS) {
+        return "OpenGL_ES";
+    }
+    else if (name == EGL_VERSION) {
+        pthread_mutex_lock(&m_lock);
+        if (m_versionString) {
+            pthread_mutex_unlock(&m_lock);
+            return m_versionString;
+        }
+
+        // build version string
+        asprintf(&m_versionString, "%d.%d", m_major, m_minor);
+        pthread_mutex_unlock(&m_lock);
+
+        return m_versionString;
+    }
+    else if (name == EGL_VENDOR) {
+        pthread_mutex_lock(&m_lock);
+        if (m_vendorString) {
+            pthread_mutex_unlock(&m_lock);
+            return m_vendorString;
+        }
+
+        // build vendor string
+        const char *hostVendor = queryHostEGLString(EGL_VENDOR);
+
+        if (hostVendor) {
+            asprintf(&m_vendorString, "%s Host: %s",
+                                     systemEGLVendor, hostVendor);
+            free((char*)hostVendor);
+        }
+        else {
+            m_vendorString = (char *)systemEGLVendor;
+        }
+        pthread_mutex_unlock(&m_lock);
+
+        return m_vendorString;
+    }
+    else if (name == EGL_EXTENSIONS) {
+        pthread_mutex_lock(&m_lock);
+        if (m_extensionString) {
+            pthread_mutex_unlock(&m_lock);
+            return m_extensionString;
+        }
+
+        // build extension string
+        m_extensionString = buildExtensionString();
+        pthread_mutex_unlock(&m_lock);
+
+        return m_extensionString;
+    }
+    else {
+        ALOGE("[%s] Unknown name %d\n", __FUNCTION__, name);
+        return NULL;
+    }
+}
+
+/* To get the value of attribute <a> of config <c> use the following formula:
+ * value = *(m_configs + (int)c*m_numConfigAttribs + a);
+ */
+EGLBoolean eglDisplay::getAttribValue(EGLConfig config, EGLint attribIdx, EGLint * value)
+{
+    if (attribIdx == ATTRIBUTE_NONE)
+    {
+        ALOGE("[%s] Bad attribute idx\n", __FUNCTION__);
+        return EGL_FALSE;
+    }
+    *value = *(m_configs + (int)config*m_numConfigAttribs + attribIdx);
+    return EGL_TRUE;
+}
+
+EGLBoolean eglDisplay::getConfigAttrib(EGLConfig config, EGLint attrib, EGLint * value)
+{
+    //Though it seems that valueFor() is thread-safe, we don't take chanses
+    pthread_mutex_lock(&m_lock);
+    EGLBoolean ret = getAttribValue(config, m_attribs.valueFor(attrib), value);
+    pthread_mutex_unlock(&m_lock);
+    return ret;
+}
+
+void eglDisplay::dumpConfig(EGLConfig config)
+{
+    EGLint value = 0;
+    DBG("^^^^^^^^^^ dumpConfig %d ^^^^^^^^^^^^^^^^^^", (int)config);
+    for (int i=0; i<m_numConfigAttribs; i++) {
+        getAttribValue(config, i, &value);
+        DBG("{%d}[%d] %d\n", (int)config, i, value);
+    }
+}
+
+/* To set the value of attribute <a> of config <c> use the following formula:
+ * *(m_configs + (int)c*m_numConfigAttribs + a) = value;
+ */
+EGLBoolean eglDisplay::setAttribValue(EGLConfig config, EGLint attribIdx, EGLint value)
+{
+    if (attribIdx == ATTRIBUTE_NONE)
+    {
+        ALOGE("[%s] Bad attribute idx\n", __FUNCTION__);
+        return EGL_FALSE;
+    }
+    *(m_configs + (int)config*m_numConfigAttribs + attribIdx) = value;
+    return EGL_TRUE;
+}
+
+EGLBoolean eglDisplay::setConfigAttrib(EGLConfig config, EGLint attrib, EGLint value)
+{
+    //Though it seems that valueFor() is thread-safe, we don't take chanses
+    pthread_mutex_lock(&m_lock);
+    EGLBoolean ret = setAttribValue(config, m_attribs.valueFor(attrib), value);
+    pthread_mutex_unlock(&m_lock);
+    return ret;
+}
+
+
+EGLBoolean eglDisplay::getConfigNativePixelFormat(EGLConfig config, PixelFormat * format)
+{
+    EGLint redSize, blueSize, greenSize, alphaSize;
+
+    if ( !(getAttribValue(config, m_attribs.valueFor(EGL_RED_SIZE), &redSize) &&
+        getAttribValue(config, m_attribs.valueFor(EGL_BLUE_SIZE), &blueSize) &&
+        getAttribValue(config, m_attribs.valueFor(EGL_GREEN_SIZE), &greenSize) &&
+        getAttribValue(config, m_attribs.valueFor(EGL_ALPHA_SIZE), &alphaSize)) )
+    {
+        ALOGE("Couldn't find value for one of the pixel format attributes");
+        return EGL_FALSE;
+    }
+
+    //calculate the GL internal format
+    if ((redSize==8)&&(greenSize==8)&&(blueSize==8)&&(alphaSize==8)) *format = PIXEL_FORMAT_RGBA_8888; //XXX: BGR?
+    else if ((redSize==8)&&(greenSize==8)&&(blueSize==8)&&(alphaSize==0)) *format = PIXEL_FORMAT_RGBX_8888; //XXX or PIXEL_FORMAT_RGB_888
+    else if ((redSize==5)&&(greenSize==6)&&(blueSize==5)&&(alphaSize==0)) *format = PIXEL_FORMAT_RGB_565;
+    else if ((redSize==5)&&(greenSize==5)&&(blueSize==5)&&(alphaSize==1)) *format = PIXEL_FORMAT_RGBA_5551;
+    else if ((redSize==4)&&(greenSize==4)&&(blueSize==4)&&(alphaSize==4)) *format = PIXEL_FORMAT_RGBA_4444;
+    else {
+        return EGL_FALSE;
+    }
+    return EGL_TRUE;
+}
+EGLBoolean eglDisplay::getConfigGLPixelFormat(EGLConfig config, GLenum * format)
+{
+    EGLint redSize, blueSize, greenSize, alphaSize;
+
+    if ( !(getAttribValue(config, m_attribs.valueFor(EGL_RED_SIZE), &redSize) &&
+        getAttribValue(config, m_attribs.valueFor(EGL_BLUE_SIZE), &blueSize) &&
+        getAttribValue(config, m_attribs.valueFor(EGL_GREEN_SIZE), &greenSize) &&
+        getAttribValue(config, m_attribs.valueFor(EGL_ALPHA_SIZE), &alphaSize)) )
+    {
+        ALOGE("Couldn't find value for one of the pixel format attributes");
+        return EGL_FALSE;
+    }
+
+    //calculate the GL internal format
+    if ((redSize==8)&&(blueSize==8)&&(blueSize==8)&&(alphaSize==8)) *format = GL_RGBA;
+    else if ((redSize==8)&&(greenSize==8)&&(blueSize==8)&&(alphaSize==0)) *format = GL_RGB;
+    else if ((redSize==5)&&(greenSize==6)&&(blueSize==5)&&(alphaSize==0)) *format = GL_RGB565_OES;
+    else if ((redSize==5)&&(greenSize==5)&&(blueSize==5)&&(alphaSize==1)) *format = GL_RGB5_A1_OES;
+    else if ((redSize==4)&&(greenSize==4)&&(blueSize==4)&&(alphaSize==4)) *format = GL_RGBA4_OES;
+    else return EGL_FALSE;
+
+    return EGL_TRUE;
+}
diff --git a/system/egl/eglDisplay.h b/system/egl/eglDisplay.h
new file mode 100644
index 0000000..9d979d9
--- /dev/null
+++ b/system/egl/eglDisplay.h
@@ -0,0 +1,89 @@
+/*
+* Copyright (C) 2011 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.
+*/
+#ifndef _SYSTEM_EGL_DISPLAY_H
+#define _SYSTEM_EGL_DISPLAY_H
+
+#include <pthread.h>
+#include "glUtils.h"
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include "EGLClientIface.h"
+#include <utils/KeyedVector.h>
+
+#include <ui/PixelFormat.h>
+
+#define ATTRIBUTE_NONE -1
+//FIXME: are we in this namespace?
+using namespace android;
+
+class eglDisplay
+{
+public:
+    eglDisplay();
+    ~eglDisplay();
+
+    bool initialize(EGLClient_eglInterface *eglIface);
+    void terminate();
+
+    int getVersionMajor() const { return m_major; }
+    int getVersionMinor() const { return m_minor; }
+    bool initialized() const { return m_initialized; }
+
+    const char *queryString(EGLint name);
+
+    const EGLClient_glesInterface *gles_iface() const { return m_gles_iface; }
+    const EGLClient_glesInterface *gles2_iface() const { return m_gles2_iface; }
+
+    int     getNumConfigs(){ return m_numConfigs; }
+    EGLBoolean  getConfigAttrib(EGLConfig config, EGLint attrib, EGLint * value);
+    EGLBoolean  setConfigAttrib(EGLConfig config, EGLint attrib, EGLint value);
+    EGLBoolean getConfigGLPixelFormat(EGLConfig config, GLenum * format);
+    EGLBoolean getConfigNativePixelFormat(EGLConfig config, PixelFormat * format);
+
+    void     dumpConfig(EGLConfig config);
+private:
+    EGLClient_glesInterface *loadGLESClientAPI(const char *libName,
+                                               EGLClient_eglInterface *eglIface,
+                                               void **libHandle);
+    EGLBoolean getAttribValue(EGLConfig config, EGLint attribIdxi, EGLint * value);
+    EGLBoolean setAttribValue(EGLConfig config, EGLint attribIdxi, EGLint value);
+    void     processConfigs();
+
+private:
+    pthread_mutex_t m_lock;
+    bool m_initialized;
+    int  m_major;
+    int  m_minor;
+    int  m_hostRendererVersion;
+    int  m_numConfigs;
+    int  m_numConfigAttribs;
+
+    /* This is the mapping between an attribute name to it's index in any given config */
+    DefaultKeyedVector<EGLint, EGLint>    m_attribs;
+    /* This is an array of all config's attributes values stored in the following sequencial fasion (read: v[c,a] = the value of attribute <a> of config <c>)
+     * v[0,0],..,v[0,m_numConfigAttribs-1],
+     *...
+     * v[m_numConfigs-1,0],..,v[m_numConfigs-1,m_numConfigAttribs-1]
+     */
+    EGLint *m_configs;
+    EGLClient_glesInterface *m_gles_iface;
+    EGLClient_glesInterface *m_gles2_iface;
+    char *m_versionString;
+    char *m_vendorString;
+    char *m_extensionString;
+};
+
+#endif
diff --git a/system/egl/egl_ftable.h b/system/egl/egl_ftable.h
new file mode 100644
index 0000000..16d130c
--- /dev/null
+++ b/system/egl/egl_ftable.h
@@ -0,0 +1,64 @@
+/*
+* Copyright (C) 2011 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.
+*/
+static const struct _egl_funcs_by_name {
+    const char *name;
+    void *proc;
+} egl_funcs_by_name[] = {
+    {"eglGetError", (void *)eglGetError},
+    {"eglGetDisplay", (void *)eglGetDisplay},
+    {"eglInitialize", (void *)eglInitialize},
+    {"eglTerminate", (void *)eglTerminate},
+    {"eglQueryString", (void *)eglQueryString},
+    {"eglGetConfigs", (void *)eglGetConfigs},
+    {"eglChooseConfig", (void *)eglChooseConfig},
+    {"eglGetConfigAttrib", (void *)eglGetConfigAttrib},
+    {"eglCreateWindowSurface", (void *)eglCreateWindowSurface},
+    {"eglCreatePbufferSurface", (void *)eglCreatePbufferSurface},
+    {"eglCreatePixmapSurface", (void *)eglCreatePixmapSurface},
+    {"eglDestroySurface", (void *)eglDestroySurface},
+    {"eglQuerySurface", (void *)eglQuerySurface},
+    {"eglBindAPI", (void *)eglBindAPI},
+    {"eglQueryAPI", (void *)eglQueryAPI},
+    {"eglWaitClient", (void *)eglWaitClient},
+    {"eglReleaseThread", (void *)eglReleaseThread},
+    {"eglCreatePbufferFromClientBuffer", (void *)eglCreatePbufferFromClientBuffer},
+    {"eglSurfaceAttrib", (void *)eglSurfaceAttrib},
+    {"eglBindTexImage", (void *)eglBindTexImage},
+    {"eglReleaseTexImage", (void *)eglReleaseTexImage},
+    {"eglSwapInterval", (void *)eglSwapInterval},
+    {"eglCreateContext", (void *)eglCreateContext},
+    {"eglDestroyContext", (void *)eglDestroyContext},
+    {"eglMakeCurrent", (void *)eglMakeCurrent},
+    {"eglGetCurrentContext", (void *)eglGetCurrentContext},
+    {"eglGetCurrentSurface", (void *)eglGetCurrentSurface},
+    {"eglGetCurrentDisplay", (void *)eglGetCurrentDisplay},
+    {"eglQueryContext", (void *)eglQueryContext},
+    {"eglWaitGL", (void *)eglWaitGL},
+    {"eglWaitNative", (void *)eglWaitNative},
+    {"eglSwapBuffers", (void *)eglSwapBuffers},
+    {"eglCopyBuffers", (void *)eglCopyBuffers},
+    {"eglGetProcAddress", (void *)eglGetProcAddress},
+    {"eglLockSurfaceKHR", (void *)eglLockSurfaceKHR},
+    {"eglUnlockSurfaceKHR", (void *)eglUnlockSurfaceKHR},
+    {"eglCreateImageKHR", (void *)eglCreateImageKHR},
+    {"eglDestroyImageKHR", (void *)eglDestroyImageKHR},
+    {"eglCreateSyncKHR", (void *)eglCreateSyncKHR},
+    {"eglDestroySyncKHR", (void *)eglDestroySyncKHR},
+    {"eglClientWaitSyncKHR", (void *)eglClientWaitSyncKHR},
+    {"eglGetSyncAttribKHR", (void *)eglGetSyncAttribKHR}
+};
+
+static const int egl_num_funcs = sizeof(egl_funcs_by_name) / sizeof(struct _egl_funcs_by_name);