Merge "Add support for posting Runnables to the Choreographer."
diff --git a/cmds/keystore/keystore.cpp b/cmds/keystore/keystore.cpp
index 05f77e5..2c9cb35 100644
--- a/cmds/keystore/keystore.cpp
+++ b/cmds/keystore/keystore.cpp
@@ -581,7 +581,7 @@
 static ResponseCode insert(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value* val) {
     char filename[NAME_MAX];
     encode_key(filename, uid, keyName);
-    Blob keyBlob(val->value, val->length, 0, NULL);
+    Blob keyBlob(val->value, val->length, NULL, 0);
     return keyStore->put(filename, &keyBlob);
 }
 
diff --git a/include/gui/BufferQueue.h b/include/gui/BufferQueue.h
index 991a181..ae99160 100644
--- a/include/gui/BufferQueue.h
+++ b/include/gui/BufferQueue.h
@@ -60,6 +60,8 @@
     BufferQueue(bool allowSynchronousMode = true);
     virtual ~BufferQueue();
 
+    virtual int query(int what, int* value);
+
     // setBufferCount updates the number of available buffer slots.  After
     // calling this all buffer slots are both unallocated and owned by the
     // BufferQueue object (i.e. they are not owned by the client).
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index 4318f0f..dcab049 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -55,7 +55,7 @@
 
     virtual ~SurfaceTexture();
 
-    virtual int query(int what, int* value);
+
 
     // updateTexImage sets the image contents of the target texture to that of
     // the most recently queued buffer.
diff --git a/include/utils/KeyedVector.h b/include/utils/KeyedVector.h
index 6bcdea4..fcc3bcf 100644
--- a/include/utils/KeyedVector.h
+++ b/include/utils/KeyedVector.h
@@ -66,7 +66,7 @@
             ssize_t         indexOfKey(const KEY& key) const;
 
     /*!
-     * modifing the array
+     * modifying the array
      */
 
             VALUE&          editValueFor(const KEY& key);
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index c7e2c0f..0791de2 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -166,6 +166,37 @@
     return OK;
 }
 
+int BufferQueue::query(int what, int* outValue)
+{
+    Mutex::Autolock lock(mMutex);
+
+    if (mAbandoned) {
+        ST_LOGE("query: SurfaceTexture has been abandoned!");
+        return NO_INIT;
+    }
+
+    int value;
+    switch (what) {
+    case NATIVE_WINDOW_WIDTH:
+        value = mDefaultWidth;
+        break;
+    case NATIVE_WINDOW_HEIGHT:
+        value = mDefaultHeight;
+        break;
+    case NATIVE_WINDOW_FORMAT:
+        value = mPixelFormat;
+        break;
+    case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
+        value = mSynchronousMode ?
+                (MIN_UNDEQUEUED_BUFFERS-1) : MIN_UNDEQUEUED_BUFFERS;
+        break;
+    default:
+        return BAD_VALUE;
+    }
+    outValue[0] = value;
+    return NO_ERROR;
+}
+
 status_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
     ST_LOGV("requestBuffer: slot=%d", slot);
     Mutex::Autolock lock(mMutex);
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index be1bcd1..a7bfc61 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -416,36 +416,7 @@
     return mSynchronousMode;
 }
 
-int SurfaceTexture::query(int what, int* outValue)
-{
-    Mutex::Autolock lock(mMutex);
 
-    if (mAbandoned) {
-        ST_LOGE("query: SurfaceTexture has been abandoned!");
-        return NO_INIT;
-    }
-
-    int value;
-    switch (what) {
-    case NATIVE_WINDOW_WIDTH:
-        value = mDefaultWidth;
-        break;
-    case NATIVE_WINDOW_HEIGHT:
-        value = mDefaultHeight;
-        break;
-    case NATIVE_WINDOW_FORMAT:
-        value = mPixelFormat;
-        break;
-    case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
-        value = mSynchronousMode ?
-                (MIN_UNDEQUEUED_BUFFERS-1) : MIN_UNDEQUEUED_BUFFERS;
-        break;
-    default:
-        return BAD_VALUE;
-    }
-    outValue[0] = value;
-    return NO_ERROR;
-}
 
 void SurfaceTexture::abandon() {
     Mutex::Autolock lock(mMutex);
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 06be2ef..0b1016c 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -118,12 +118,6 @@
 
 // ----------------------------------------------------------------------------
 
-Loader::entry_t::entry_t(int dpy, int impl, const char* tag)
-    : dpy(dpy), impl(impl), tag(tag) {
-}
-
-// ----------------------------------------------------------------------------
-
 Loader::Loader()
 {
     char line[256];
@@ -131,8 +125,9 @@
 
     /* Special case for GLES emulation */
     if (checkGlesEmulationStatus() == 0) {
-        ALOGD("Emulator without GPU support detected. Fallback to software renderer.");
-        gConfig.add( entry_t(0, 0, "android") );
+        ALOGD("Emulator without GPU support detected. "
+              "Fallback to software renderer.");
+        mDriverTag.setTo("android");
         return;
     }
 
@@ -141,14 +136,16 @@
     if (cfg == NULL) {
         // default config
         ALOGD("egl.cfg not found, using default config");
-        gConfig.add( entry_t(0, 0, "android") );
+        mDriverTag.setTo("android");
     } else {
         while (fgets(line, 256, cfg)) {
-            int dpy;
-            int impl;
+            int dpy, impl;
             if (sscanf(line, "%u %u %s", &dpy, &impl, tag) == 3) {
                 //ALOGD(">>> %u %u %s", dpy, impl, tag);
-                gConfig.add( entry_t(dpy, impl, tag) );
+                // We only load the h/w accelerated implementation
+                if (tag != String8("android")) {
+                    mDriverTag = tag;
+                }
             }
         }
         fclose(cfg);
@@ -160,30 +157,12 @@
     GLTrace_stop();
 }
 
-const char* Loader::getTag(int dpy, int impl)
+void* Loader::open(egl_connection_t* cnx)
 {
-    const Vector<entry_t>& cfgs(gConfig);    
-    const size_t c = cfgs.size();
-    for (size_t i=0 ; i<c ; i++) {
-        if (dpy == cfgs[i].dpy)
-            if (impl == cfgs[i].impl)
-                return cfgs[i].tag.string();
-    }
-    return 0;
-}
-
-void* Loader::open(EGLNativeDisplayType display, int impl, egl_connection_t* cnx)
-{
-    /*
-     * TODO: if we don't find display/0, then use 0/0
-     * (0/0 should always work)
-     */
-    
     void* dso;
-    int index = int(display);
     driver_t* hnd = 0;
     
-    char const* tag = getTag(index, impl);
+    char const* tag = mDriverTag.string();
     if (tag) {
         dso = load_driver("GLES", tag, cnx, EGL | GLESv1_CM | GLESv2);
         if (dso) {
@@ -193,16 +172,14 @@
             dso = load_driver("EGL", tag, cnx, EGL);
             if (dso) {
                 hnd = new driver_t(dso);
-
                 // TODO: make this more automated
                 hnd->set( load_driver("GLESv1_CM", tag, cnx, GLESv1_CM), GLESv1_CM );
-
-                hnd->set( load_driver("GLESv2", tag, cnx, GLESv2), GLESv2 );
+                hnd->set( load_driver("GLESv2",    tag, cnx, GLESv2),    GLESv2 );
             }
         }
     }
 
-    LOG_FATAL_IF(!index && !impl && !hnd, 
+    LOG_FATAL_IF(!index && !hnd,
             "couldn't find the default OpenGL ES implementation "
             "for default display");
     
@@ -221,7 +198,7 @@
         __eglMustCastToProperFunctionPointerType* curr, 
         getProcAddressType getProcAddress) 
 {
-    const size_t SIZE = 256;
+    const ssize_t SIZE = 256;
     char scrap[SIZE];
     while (*api) {
         char const * name = *api;
@@ -326,14 +303,14 @@
     if (mask & GLESv1_CM) {
         init_api(dso, gl_names,
             (__eglMustCastToProperFunctionPointerType*)
-                &cnx->hooks[GLESv1_INDEX]->gl,
+                &cnx->hooks[egl_connection_t::GLESv1_INDEX]->gl,
             getProcAddress);
     }
 
     if (mask & GLESv2) {
       init_api(dso, gl_names,
             (__eglMustCastToProperFunctionPointerType*)
-                &cnx->hooks[GLESv2_INDEX]->gl,
+                &cnx->hooks[egl_connection_t::GLESv2_INDEX]->gl,
             getProcAddress);
     }
     
diff --git a/opengl/libs/EGL/Loader.h b/opengl/libs/EGL/Loader.h
index 580d6e4..30773cb 100644
--- a/opengl/libs/EGL/Loader.h
+++ b/opengl/libs/EGL/Loader.h
@@ -24,7 +24,6 @@
 #include <utils/Errors.h>
 #include <utils/Singleton.h>
 #include <utils/String8.h>
-#include <utils/Vector.h>
 
 #include <EGL/egl.h>
 
@@ -53,23 +52,13 @@
         void* dso[3];
     };
     
-    struct entry_t {
-        entry_t() { }
-        entry_t(int dpy, int impl, const char* tag);
-        int dpy;
-        int impl;
-        String8 tag;
-    };
-
-    Vector<entry_t> gConfig;    
+    String8 mDriverTag;
     getProcAddressType getProcAddress;
     
-    const char* getTag(int dpy, int impl);
-
 public:
     ~Loader();
     
-    void* open(EGLNativeDisplayType display, int impl, egl_connection_t* cnx);
+    void* open(egl_connection_t* cnx);
     status_t close(void* driver);
     
 private:
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 83933e5..eec5ce1 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -48,8 +48,8 @@
 namespace android {
 // ----------------------------------------------------------------------------
 
-egl_connection_t gEGLImpl[IMPL_NUM_IMPLEMENTATIONS];
-gl_hooks_t gHooks[2][IMPL_NUM_IMPLEMENTATIONS];
+egl_connection_t gEGLImpl;
+gl_hooks_t gHooks[2];
 gl_hooks_t gHooksNoContext;
 pthread_key_t gGLWrapperKey = -1;
 
@@ -187,16 +187,13 @@
     return dp;
 }
 
-egl_connection_t* validate_display_config(EGLDisplay dpy, EGLConfig config,
+egl_connection_t* validate_display_config(EGLDisplay dpy, EGLConfig,
         egl_display_t const*& dp) {
     dp = validate_display(dpy);
     if (!dp)
         return (egl_connection_t*) NULL;
 
-    if (intptr_t(config) >= dp->numTotalConfigs) {
-        return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL);
-    }
-    egl_connection_t* const cnx = &gEGLImpl[dp->configs[intptr_t(config)].impl];
+    egl_connection_t* const cnx = &gEGLImpl;
     if (cnx->dso == 0) {
         return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL);
     }
@@ -205,34 +202,6 @@
 
 // ----------------------------------------------------------------------------
 
-EGLImageKHR egl_get_image_for_current_context(EGLImageKHR image)
-{
-    EGLContext context = egl_tls_t::getContext();
-    if (context == EGL_NO_CONTEXT || image == EGL_NO_IMAGE_KHR)
-        return EGL_NO_IMAGE_KHR;
-
-    egl_context_t const * const c = get_context(context);
-    if (c == NULL) // this should never happen, by construction
-        return EGL_NO_IMAGE_KHR;
-
-    egl_display_t* display = egl_display_t::get(c->dpy);
-    if (display == NULL) // this should never happen, by construction
-        return EGL_NO_IMAGE_KHR;
-
-    ImageRef _i(display, image);
-    if (!_i.get())
-        return EGL_NO_IMAGE_KHR;
-
-    // here we don't validate the context because if it's been marked for
-    // termination, this call should still succeed since it's internal to
-    // EGL.
-
-    egl_image_t const * const i = get_image(image);
-    return i->images[c->impl];
-}
-
-// ----------------------------------------------------------------------------
-
 const GLubyte * egl_get_string_for_current_context(GLenum name) {
     // NOTE: returning NULL here will fall-back to the default
     // implementation.
@@ -266,34 +235,17 @@
     // get our driver loader
     Loader& loader(Loader::getInstance());
 
-    // dynamically load all our EGL implementations
-    egl_connection_t* cnx;
-
-    cnx = &gEGLImpl[IMPL_SOFTWARE];
+    // dynamically load our EGL implementation
+    egl_connection_t* cnx = &gEGLImpl;
     if (cnx->dso == 0) {
-        cnx->hooks[GLESv1_INDEX] = &gHooks[GLESv1_INDEX][IMPL_SOFTWARE];
-        cnx->hooks[GLESv2_INDEX] = &gHooks[GLESv2_INDEX][IMPL_SOFTWARE];
-        cnx->dso = loader.open(EGL_DEFAULT_DISPLAY, 0, cnx);
+        cnx->hooks[egl_connection_t::GLESv1_INDEX] =
+                &gHooks[egl_connection_t::GLESv1_INDEX];
+        cnx->hooks[egl_connection_t::GLESv2_INDEX] =
+                &gHooks[egl_connection_t::GLESv2_INDEX];
+        cnx->dso = loader.open(cnx);
     }
 
-    cnx = &gEGLImpl[IMPL_HARDWARE];
-    if (cnx->dso == 0) {
-        char value[PROPERTY_VALUE_MAX];
-        property_get("debug.egl.hw", value, "1");
-        if (atoi(value) != 0) {
-            cnx->hooks[GLESv1_INDEX] = &gHooks[GLESv1_INDEX][IMPL_HARDWARE];
-            cnx->hooks[GLESv2_INDEX] = &gHooks[GLESv2_INDEX][IMPL_HARDWARE];
-            cnx->dso = loader.open(EGL_DEFAULT_DISPLAY, 1, cnx);
-        } else {
-            ALOGD("3D hardware acceleration is disabled");
-        }
-    }
-
-    if (!gEGLImpl[IMPL_SOFTWARE].dso && !gEGLImpl[IMPL_HARDWARE].dso) {
-        return EGL_FALSE;
-    }
-
-    return EGL_TRUE;
+    return cnx->dso ? EGL_TRUE : EGL_FALSE;
 }
 
 static pthread_mutex_t sInitDriverMutex = PTHREAD_MUTEX_INITIALIZER;
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 73aab26..a5dc832 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -44,6 +44,7 @@
 #include "egl_impl.h"
 #include "egl_object.h"
 #include "egl_tls.h"
+#include "egldefs.h"
 
 using namespace android;
 
@@ -88,24 +89,6 @@
 
 // ----------------------------------------------------------------------------
 
-template<typename T>
-static __attribute__((noinline))
-int binarySearch(T const sortedArray[], int first, int last, T key) {
-    while (first <= last) {
-        int mid = (first + last) / 2;
-        if (sortedArray[mid] < key) {
-            first = mid + 1;
-        } else if (key < sortedArray[mid]) {
-            last = mid - 1;
-        } else {
-            return mid;
-        }
-    }
-    return -1;
-}
-
-// ----------------------------------------------------------------------------
-
 namespace android {
 extern void setGLHooksThreadSpecific(gl_hooks_t const *value);
 extern EGLBoolean egl_init_drivers();
@@ -183,21 +166,20 @@
     egl_display_t const * const dp = validate_display(dpy);
     if (!dp) return EGL_FALSE;
 
-    GLint numConfigs = dp->numTotalConfigs;
-    if (!configs) {
-        *num_config = numConfigs;
-        return EGL_TRUE;
+    if (num_config==0) {
+        return setError(EGL_BAD_PARAMETER, EGL_FALSE);
     }
 
-    GLint n = 0;
-    for (intptr_t i=0 ; i<dp->numTotalConfigs && config_size ; i++) {
-        *configs++ = EGLConfig(i);
-        config_size--;
-        n++;
+    EGLBoolean res = EGL_FALSE;
+    *num_config = 0;
+
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso) {
+        res = cnx->egl.eglGetConfigs(
+                dp->disp.dpy, configs, config_size, num_config);
     }
-    
-    *num_config = n;
-    return EGL_TRUE;
+
+    return res;
 }
 
 EGLBoolean eglChooseConfig( EGLDisplay dpy, const EGLint *attrib_list,
@@ -213,105 +195,13 @@
         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
     }
 
-    EGLint n;
     EGLBoolean res = EGL_FALSE;
     *num_config = 0;
 
-    
-    // It is unfortunate, but we need to remap the EGL_CONFIG_IDs, 
-    // to do this, we have to go through the attrib_list array once
-    // to figure out both its size and if it contains an EGL_CONFIG_ID
-    // key. If so, the full array is copied and patched.
-    // NOTE: we assume that there can be only one occurrence
-    // of EGL_CONFIG_ID.
-    
-    EGLint patch_index = -1;
-    GLint attr;
-    size_t size = 0;
-    if (attrib_list) {
-        while ((attr=attrib_list[size]) != EGL_NONE) {
-            if (attr == EGL_CONFIG_ID)
-                patch_index = size;
-            size += 2;
-        }
-    }
-    if (patch_index >= 0) {
-        size += 2; // we need copy the sentinel as well
-        EGLint* new_list = (EGLint*)malloc(size*sizeof(EGLint));
-        if (new_list == 0)
-            return setError(EGL_BAD_ALLOC, EGL_FALSE);
-        memcpy(new_list, attrib_list, size*sizeof(EGLint));
-
-        // patch the requested EGL_CONFIG_ID
-        bool found = false;
-        EGLConfig ourConfig(0);
-        EGLint& configId(new_list[patch_index+1]);
-        for (intptr_t i=0 ; i<dp->numTotalConfigs ; i++) {
-            if (dp->configs[i].configId == configId) {
-                ourConfig = EGLConfig(i);
-                configId = dp->configs[i].implConfigId;
-                found = true;
-                break;
-            }
-        }
-
-        egl_connection_t* const cnx = &gEGLImpl[dp->configs[intptr_t(ourConfig)].impl];
-        if (found && cnx->dso) {
-            // and switch to the new list
-            attrib_list = const_cast<const EGLint *>(new_list);
-
-            // At this point, the only configuration that can match is
-            // dp->configs[i][index], however, we don't know if it would be
-            // rejected because of the other attributes, so we do have to call
-            // cnx->egl.eglChooseConfig() -- but we don't have to loop
-            // through all the EGLimpl[].
-            // We also know we can only get a single config back, and we know
-            // which one.
-
-            res = cnx->egl.eglChooseConfig(
-                    dp->disp[ dp->configs[intptr_t(ourConfig)].impl ].dpy,
-                    attrib_list, configs, config_size, &n);
-            if (res && n>0) {
-                // n has to be 0 or 1, by construction, and we already know
-                // which config it will return (since there can be only one).
-                if (configs) {
-                    configs[0] = ourConfig;
-                }
-                *num_config = 1;
-            }
-        }
-
-        free(const_cast<EGLint *>(attrib_list));
-        return res;
-    }
-
-
-    for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
-        egl_connection_t* const cnx = &gEGLImpl[i];
-        if (cnx->dso) {
-            if (cnx->egl.eglChooseConfig(
-                    dp->disp[i].dpy, attrib_list, configs, config_size, &n)) {
-                if (configs) {
-                    // now we need to convert these client EGLConfig to our
-                    // internal EGLConfig format.
-                    // This is done in O(n Log(n)) time.
-                    for (int j=0 ; j<n ; j++) {
-                        egl_config_t key(i, configs[j]);
-                        intptr_t index = binarySearch<egl_config_t>(
-                                dp->configs, 0, dp->numTotalConfigs, key);
-                        if (index >= 0) {
-                            configs[j] = EGLConfig(index);
-                        } else {
-                            return setError(EGL_BAD_CONFIG, EGL_FALSE);
-                        }
-                    }
-                    configs += n;
-                    config_size -= n;
-                }
-                *num_config += n;
-                res = EGL_TRUE;
-            }
-        }
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso) {
+        res = cnx->egl.eglChooseConfig(
+                dp->disp.dpy, attrib_list, configs, config_size, num_config);
     }
     return res;
 }
@@ -325,13 +215,8 @@
     egl_connection_t* cnx = validate_display_config(dpy, config, dp);
     if (!cnx) return EGL_FALSE;
     
-    if (attribute == EGL_CONFIG_ID) {
-        *value = dp->configs[intptr_t(config)].configId;
-        return EGL_TRUE;
-    }
     return cnx->egl.eglGetConfigAttrib(
-            dp->disp[ dp->configs[intptr_t(config)].impl ].dpy,
-            dp->configs[intptr_t(config)].config, attribute, value);
+            dp->disp.dpy, config, attribute, value);
 }
 
 // ----------------------------------------------------------------------------
@@ -347,8 +232,7 @@
     egl_display_t const* dp = 0;
     egl_connection_t* cnx = validate_display_config(dpy, config, dp);
     if (cnx) {
-        EGLDisplay iDpy = dp->disp[ dp->configs[intptr_t(config)].impl ].dpy;
-        EGLConfig iConfig = dp->configs[intptr_t(config)].config;
+        EGLDisplay iDpy = dp->disp.dpy;
         EGLint format;
 
         if (native_window_api_connect(window, NATIVE_WINDOW_API_EGL) != OK) {
@@ -359,7 +243,7 @@
 
         // set the native window's buffers format to match this config
         if (cnx->egl.eglGetConfigAttrib(iDpy,
-                iConfig, EGL_NATIVE_VISUAL_ID, &format)) {
+                config, EGL_NATIVE_VISUAL_ID, &format)) {
             if (format != 0) {
                 int err = native_window_set_buffers_format(window, format);
                 if (err != 0) {
@@ -377,10 +261,9 @@
         anw->setSwapInterval(anw, 1);
 
         EGLSurface surface = cnx->egl.eglCreateWindowSurface(
-                iDpy, iConfig, window, attrib_list);
+                iDpy, config, window, attrib_list);
         if (surface != EGL_NO_SURFACE) {
-            egl_surface_t* s = new egl_surface_t(dpy, config, window, surface,
-                    dp->configs[intptr_t(config)].impl, cnx);
+            egl_surface_t* s = new egl_surface_t(dpy, config, window, surface, cnx);
             return s;
         }
 
@@ -401,11 +284,9 @@
     egl_connection_t* cnx = validate_display_config(dpy, config, dp);
     if (cnx) {
         EGLSurface surface = cnx->egl.eglCreatePixmapSurface(
-                dp->disp[ dp->configs[intptr_t(config)].impl ].dpy,
-                dp->configs[intptr_t(config)].config, pixmap, attrib_list);
+                dp->disp.dpy, config, pixmap, attrib_list);
         if (surface != EGL_NO_SURFACE) {
-            egl_surface_t* s = new egl_surface_t(dpy, config, NULL, surface,
-                    dp->configs[intptr_t(config)].impl, cnx);
+            egl_surface_t* s = new egl_surface_t(dpy, config, NULL, surface, cnx);
             return s;
         }
     }
@@ -421,11 +302,9 @@
     egl_connection_t* cnx = validate_display_config(dpy, config, dp);
     if (cnx) {
         EGLSurface surface = cnx->egl.eglCreatePbufferSurface(
-                dp->disp[ dp->configs[intptr_t(config)].impl ].dpy,
-                dp->configs[intptr_t(config)].config, attrib_list);
+                dp->disp.dpy, config, attrib_list);
         if (surface != EGL_NO_SURFACE) {
-            egl_surface_t* s = new egl_surface_t(dpy, config, NULL, surface,
-                    dp->configs[intptr_t(config)].impl, cnx);
+            egl_surface_t* s = new egl_surface_t(dpy, config, NULL, surface, cnx);
             return s;
         }
     }
@@ -444,8 +323,7 @@
         return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
     egl_surface_t * const s = get_surface(surface);
-    EGLBoolean result = s->cnx->egl.eglDestroySurface(
-            dp->disp[s->impl].dpy, s->surface);
+    EGLBoolean result = s->cnx->egl.eglDestroySurface(dp->disp.dpy, s->surface);
     if (result == EGL_TRUE) {
         _s.terminate();
     }
@@ -465,16 +343,8 @@
         return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
     egl_surface_t const * const s = get_surface(surface);
-    EGLBoolean result(EGL_TRUE);
-    if (attribute == EGL_CONFIG_ID) {
-        // We need to remap EGL_CONFIG_IDs
-        *value = dp->configs[intptr_t(s->config)].configId;
-    } else {
-        result = s->cnx->egl.eglQuerySurface(
-                dp->disp[s->impl].dpy, s->surface, attribute, value);
-    }
-
-    return result;
+    return s->cnx->egl.eglQuerySurface(
+            dp->disp.dpy, s->surface, attribute, value);
 }
 
 void EGLAPI eglBeginFrame(EGLDisplay dpy, EGLSurface surface) {
@@ -514,9 +384,7 @@
             share_list = c->context;
         }
         EGLContext context = cnx->egl.eglCreateContext(
-                dp->disp[ dp->configs[intptr_t(config)].impl ].dpy,
-                dp->configs[intptr_t(config)].config,
-                share_list, attrib_list);
+                dp->disp.dpy, config, share_list, attrib_list);
         if (context != EGL_NO_CONTEXT) {
             // figure out if it's a GLESv1 or GLESv2
             int version = 0;
@@ -526,15 +394,14 @@
                     GLint value = *attrib_list++;
                     if (attr == EGL_CONTEXT_CLIENT_VERSION) {
                         if (value == 1) {
-                            version = GLESv1_INDEX;
+                            version = egl_connection_t::GLESv1_INDEX;
                         } else if (value == 2) {
-                            version = GLESv2_INDEX;
+                            version = egl_connection_t::GLESv2_INDEX;
                         }
                     }
                 };
             }
-            egl_context_t* c = new egl_context_t(dpy, context, config,
-                    dp->configs[intptr_t(config)].impl, cnx, version);
+            egl_context_t* c = new egl_context_t(dpy, context, config, cnx, version);
 #if EGL_TRACE
             if (gEGLDebugLevel > 0)
                 GLTrace_eglCreateContext(version, c);
@@ -558,8 +425,7 @@
         return setError(EGL_BAD_CONTEXT, EGL_FALSE);
     
     egl_context_t * const c = get_context(ctx);
-    EGLBoolean result = c->cnx->egl.eglDestroyContext(
-            dp->disp[c->impl].dpy, c->context);
+    EGLBoolean result = c->cnx->egl.eglDestroyContext(dp->disp.dpy, c->context);
     if (result == EGL_TRUE) {
         _c.terminate();
     }
@@ -625,20 +491,12 @@
     // retrieve the underlying implementation's draw EGLSurface
     if (draw != EGL_NO_SURFACE) {
         d = get_surface(draw);
-        // make sure the EGLContext and EGLSurface passed in are for
-        // the same driver
-        if (c && d->impl != c->impl)
-            return setError(EGL_BAD_MATCH, EGL_FALSE);
         impl_draw = d->surface;
     }
 
     // retrieve the underlying implementation's read EGLSurface
     if (read != EGL_NO_SURFACE) {
         r = get_surface(read);
-        // make sure the EGLContext and EGLSurface passed in are for
-        // the same driver
-        if (c && r->impl != c->impl)
-            return setError(EGL_BAD_MATCH, EGL_FALSE);
         impl_read = r->surface;
     }
 
@@ -682,17 +540,9 @@
     if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
 
     egl_context_t * const c = get_context(ctx);
+    return c->cnx->egl.eglQueryContext(
+            dp->disp.dpy, c->context, attribute, value);
 
-    EGLBoolean result(EGL_TRUE);
-    if (attribute == EGL_CONFIG_ID) {
-        *value = dp->configs[intptr_t(c->config)].configId;
-    } else {
-        // We need to remap EGL_CONFIG_IDs
-        result = c->cnx->egl.eglQueryContext(
-                dp->disp[c->impl].dpy, c->context, attribute, value);
-    }
-
-    return result;
 }
 
 EGLContext eglGetCurrentContext(void)
@@ -744,87 +594,37 @@
 
 EGLBoolean eglWaitGL(void)
 {
-    // could be called before eglInitialize(), but we wouldn't have a context
-    // then, and this function would return GL_TRUE, which isn't wrong.
-
     clearError();
 
-    EGLBoolean res = EGL_TRUE;
-    EGLContext ctx = getContext();
-    if (ctx) {
-        egl_context_t const * const c = get_context(ctx);
-        if (!c) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
-        if (uint32_t(c->impl)>=2)
-            return setError(EGL_BAD_CONTEXT, EGL_FALSE);
-        egl_connection_t* const cnx = &gEGLImpl[c->impl];
-        if (!cnx->dso) 
-            return setError(EGL_BAD_CONTEXT, EGL_FALSE);
-        res = cnx->egl.eglWaitGL();
-    }
-    return res;
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (!cnx->dso)
+        return setError(EGL_BAD_CONTEXT, EGL_FALSE);
+
+    return cnx->egl.eglWaitGL();
 }
 
 EGLBoolean eglWaitNative(EGLint engine)
 {
-    // could be called before eglInitialize(), but we wouldn't have a context
-    // then, and this function would return GL_TRUE, which isn't wrong.
-
     clearError();
 
-    EGLBoolean res = EGL_TRUE;
-    EGLContext ctx = getContext();
-    if (ctx) {
-        egl_context_t const * const c = get_context(ctx);
-        if (!c) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
-        if (uint32_t(c->impl)>=2)
-            return setError(EGL_BAD_CONTEXT, EGL_FALSE);
-        egl_connection_t* const cnx = &gEGLImpl[c->impl];
-        if (!cnx->dso) 
-            return setError(EGL_BAD_CONTEXT, EGL_FALSE);
-        res = cnx->egl.eglWaitNative(engine);
-    }
-    return res;
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (!cnx->dso)
+        return setError(EGL_BAD_CONTEXT, EGL_FALSE);
+
+    return cnx->egl.eglWaitNative(engine);
 }
 
 EGLint eglGetError(void)
 {
-    EGLint result = EGL_SUCCESS;
-    EGLint err;
-    for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
-        err = EGL_SUCCESS;
-        egl_connection_t* const cnx = &gEGLImpl[i];
-        if (cnx->dso)
-            err = cnx->egl.eglGetError();
-        if (err!=EGL_SUCCESS && result==EGL_SUCCESS)
-            result = err;
+    EGLint err = EGL_SUCCESS;
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso) {
+        err = cnx->egl.eglGetError();
     }
-    err = egl_tls_t::getError();
-    if (result == EGL_SUCCESS)
-        result = err;
-    return result;
-}
-
-// Note: Similar implementations of these functions also exist in
-// gl2.cpp and gl.cpp, and are used by applications that call the
-// exported entry points directly.
-typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image);
-typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image);
-
-static PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES_impl = NULL;
-static PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC glEGLImageTargetRenderbufferStorageOES_impl = NULL;
-
-static void glEGLImageTargetTexture2DOES_wrapper(GLenum target, GLeglImageOES image)
-{
-    GLeglImageOES implImage =
-        (GLeglImageOES)egl_get_image_for_current_context((EGLImageKHR)image);
-    glEGLImageTargetTexture2DOES_impl(target, implImage);
-}
-
-static void glEGLImageTargetRenderbufferStorageOES_wrapper(GLenum target, GLeglImageOES image)
-{
-    GLeglImageOES implImage =
-        (GLeglImageOES)egl_get_image_for_current_context((EGLImageKHR)image);
-    glEGLImageTargetRenderbufferStorageOES_impl(target, implImage);
+    if (err == EGL_SUCCESS) {
+        err = egl_tls_t::getError();
+    }
+    return err;
 }
 
 __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname)
@@ -885,32 +685,22 @@
 
         if (!addr && (slot < MAX_NUMBER_OF_GL_EXTENSIONS)) {
             bool found = false;
-            for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
-                egl_connection_t* const cnx = &gEGLImpl[i];
-                if (cnx->dso && cnx->egl.eglGetProcAddress) {
-                    found = true;
-                    // Extensions are independent of the bound context
-                    cnx->hooks[GLESv1_INDEX]->ext.extensions[slot] =
-                    cnx->hooks[GLESv2_INDEX]->ext.extensions[slot] =
+
+            egl_connection_t* const cnx = &gEGLImpl;
+            if (cnx->dso && cnx->egl.eglGetProcAddress) {
+                found = true;
+                // Extensions are independent of the bound context
+                cnx->hooks[egl_connection_t::GLESv1_INDEX]->ext.extensions[slot] =
+                cnx->hooks[egl_connection_t::GLESv2_INDEX]->ext.extensions[slot] =
 #if EGL_TRACE
-                    debugHooks->ext.extensions[slot] =
-                    gHooksTrace.ext.extensions[slot] =
+                debugHooks->ext.extensions[slot] =
+                gHooksTrace.ext.extensions[slot] =
 #endif
-                            cnx->egl.eglGetProcAddress(procname);
-                }
+                        cnx->egl.eglGetProcAddress(procname);
             }
+
             if (found) {
                 addr = gExtensionForwarders[slot];
-
-                if (!strcmp(procname, "glEGLImageTargetTexture2DOES")) {
-                    glEGLImageTargetTexture2DOES_impl = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)addr;
-                    addr = (__eglMustCastToProperFunctionPointerType)glEGLImageTargetTexture2DOES_wrapper;
-                }
-                if (!strcmp(procname, "glEGLImageTargetRenderbufferStorageOES")) {
-                    glEGLImageTargetRenderbufferStorageOES_impl = (PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC)addr;
-                    addr = (__eglMustCastToProperFunctionPointerType)glEGLImageTargetRenderbufferStorageOES_wrapper;
-                }
-
                 sGLExtentionMap.add(name, addr);
                 sGLExtentionSlot++;
             }
@@ -937,7 +727,7 @@
 #endif
 
     egl_surface_t const * const s = get_surface(draw);
-    return s->cnx->egl.eglSwapBuffers(dp->disp[s->impl].dpy, s->surface);
+    return s->cnx->egl.eglSwapBuffers(dp->disp.dpy, s->surface);
 }
 
 EGLBoolean eglCopyBuffers(  EGLDisplay dpy, EGLSurface surface,
@@ -953,8 +743,7 @@
         return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
     egl_surface_t const * const s = get_surface(surface);
-    return s->cnx->egl.eglCopyBuffers(
-            dp->disp[s->impl].dpy, s->surface, target);
+    return s->cnx->egl.eglCopyBuffers(dp->disp.dpy, s->surface, target);
 }
 
 const char* eglQueryString(EGLDisplay dpy, EGLint name)
@@ -973,12 +762,8 @@
             return dp->getExtensionString();
         case EGL_CLIENT_APIS:
             return dp->getClientApiString();
-        case EGL_VERSION_HW_ANDROID: {
-            if (gEGLImpl[IMPL_HARDWARE].dso) {
-                return dp->disp[IMPL_HARDWARE].queryString.version;
-            }
-            return dp->disp[IMPL_SOFTWARE].queryString.version;
-        }
+        case EGL_VERSION_HW_ANDROID:
+            return dp->disp.queryString.version;
     }
     return setError(EGL_BAD_PARAMETER, (const char *)0);
 }
@@ -1003,7 +788,7 @@
     egl_surface_t const * const s = get_surface(surface);
     if (s->cnx->egl.eglSurfaceAttrib) {
         return s->cnx->egl.eglSurfaceAttrib(
-                dp->disp[s->impl].dpy, s->surface, attribute, value);
+                dp->disp.dpy, s->surface, attribute, value);
     }
     return setError(EGL_BAD_SURFACE, EGL_FALSE);
 }
@@ -1023,7 +808,7 @@
     egl_surface_t const * const s = get_surface(surface);
     if (s->cnx->egl.eglBindTexImage) {
         return s->cnx->egl.eglBindTexImage(
-                dp->disp[s->impl].dpy, s->surface, buffer);
+                dp->disp.dpy, s->surface, buffer);
     }
     return setError(EGL_BAD_SURFACE, EGL_FALSE);
 }
@@ -1043,7 +828,7 @@
     egl_surface_t const * const s = get_surface(surface);
     if (s->cnx->egl.eglReleaseTexImage) {
         return s->cnx->egl.eglReleaseTexImage(
-                dp->disp[s->impl].dpy, s->surface, buffer);
+                dp->disp.dpy, s->surface, buffer);
     }
     return setError(EGL_BAD_SURFACE, EGL_FALSE);
 }
@@ -1056,17 +841,11 @@
     if (!dp) return EGL_FALSE;
 
     EGLBoolean res = EGL_TRUE;
-    for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
-        egl_connection_t* const cnx = &gEGLImpl[i];
-        if (cnx->dso) {
-            if (cnx->egl.eglSwapInterval) {
-                if (cnx->egl.eglSwapInterval(
-                        dp->disp[i].dpy, interval) == EGL_FALSE) {
-                    res = EGL_FALSE;
-                }
-            }
-        }
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && cnx->egl.eglSwapInterval) {
+        res = cnx->egl.eglSwapInterval(dp->disp.dpy, interval);
     }
+
     return res;
 }
 
@@ -1079,23 +858,15 @@
 {
     clearError();
 
-    // could be called before eglInitialize(), but we wouldn't have a context
-    // then, and this function would return GL_TRUE, which isn't wrong.
-    EGLBoolean res = EGL_TRUE;
-    EGLContext ctx = getContext();
-    if (ctx) {
-        egl_context_t const * const c = get_context(ctx);
-        if (!c) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
-        if (uint32_t(c->impl)>=2)
-            return setError(EGL_BAD_CONTEXT, EGL_FALSE);
-        egl_connection_t* const cnx = &gEGLImpl[c->impl];
-        if (!cnx->dso) 
-            return setError(EGL_BAD_CONTEXT, EGL_FALSE);
-        if (cnx->egl.eglWaitClient) {
-            res = cnx->egl.eglWaitClient();
-        } else {
-            res = cnx->egl.eglWaitGL();
-        }
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (!cnx->dso)
+        return setError(EGL_BAD_CONTEXT, EGL_FALSE);
+
+    EGLBoolean res;
+    if (cnx->egl.eglWaitClient) {
+        res = cnx->egl.eglWaitClient();
+    } else {
+        res = cnx->egl.eglWaitGL();
     }
     return res;
 }
@@ -1110,15 +881,9 @@
 
     // bind this API on all EGLs
     EGLBoolean res = EGL_TRUE;
-    for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
-        egl_connection_t* const cnx = &gEGLImpl[i];
-        if (cnx->dso) {
-            if (cnx->egl.eglBindAPI) {
-                if (cnx->egl.eglBindAPI(api) == EGL_FALSE) {
-                    res = EGL_FALSE;
-                }
-            }
-        }
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && cnx->egl.eglBindAPI) {
+        res = cnx->egl.eglBindAPI(api);
     }
     return res;
 }
@@ -1131,16 +896,11 @@
         return setError(EGL_BAD_PARAMETER, EGL_FALSE);
     }
 
-    for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
-        egl_connection_t* const cnx = &gEGLImpl[i];
-        if (cnx->dso) {
-            if (cnx->egl.eglQueryAPI) {
-                // the first one we find is okay, because they all
-                // should be the same
-                return cnx->egl.eglQueryAPI();
-            }
-        }
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && cnx->egl.eglQueryAPI) {
+        return cnx->egl.eglQueryAPI();
     }
+
     // or, it can only be OpenGL ES
     return EGL_OPENGL_ES_API;
 }
@@ -1152,14 +912,11 @@
     // If there is context bound to the thread, release it
     egl_display_t::loseCurrent(get_context(getContext()));
 
-    for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
-        egl_connection_t* const cnx = &gEGLImpl[i];
-        if (cnx->dso) {
-            if (cnx->egl.eglReleaseThread) {
-                cnx->egl.eglReleaseThread();
-            }
-        }
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && cnx->egl.eglReleaseThread) {
+        cnx->egl.eglReleaseThread();
     }
+
     egl_tls_t::clearTLS();
 #if EGL_TRACE
     if (gEGLDebugLevel > 0)
@@ -1179,9 +936,7 @@
     if (!cnx) return EGL_FALSE;
     if (cnx->egl.eglCreatePbufferFromClientBuffer) {
         return cnx->egl.eglCreatePbufferFromClientBuffer(
-                dp->disp[ dp->configs[intptr_t(config)].impl ].dpy,
-                buftype, buffer,
-                dp->configs[intptr_t(config)].config, attrib_list);
+                dp->disp.dpy, buftype, buffer, config, attrib_list);
     }
     return setError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
 }
@@ -1205,7 +960,7 @@
     egl_surface_t const * const s = get_surface(surface);
     if (s->cnx->egl.eglLockSurfaceKHR) {
         return s->cnx->egl.eglLockSurfaceKHR(
-                dp->disp[s->impl].dpy, s->surface, attrib_list);
+                dp->disp.dpy, s->surface, attrib_list);
     }
     return setError(EGL_BAD_DISPLAY, EGL_FALSE);
 }
@@ -1223,8 +978,7 @@
 
     egl_surface_t const * const s = get_surface(surface);
     if (s->cnx->egl.eglUnlockSurfaceKHR) {
-        return s->cnx->egl.eglUnlockSurfaceKHR(
-                dp->disp[s->impl].dpy, s->surface);
+        return s->cnx->egl.eglUnlockSurfaceKHR(dp->disp.dpy, s->surface);
     }
     return setError(EGL_BAD_DISPLAY, EGL_FALSE);
 }
@@ -1237,67 +991,18 @@
     egl_display_t const * const dp = validate_display(dpy);
     if (!dp) return EGL_NO_IMAGE_KHR;
 
-    if (ctx != EGL_NO_CONTEXT) {
-        ContextRef _c(dp, ctx);
-        if (!_c.get())
-            return setError(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
-        egl_context_t * const c = get_context(ctx);
-        // since we have an EGLContext, we know which implementation to use
-        EGLImageKHR image = c->cnx->egl.eglCreateImageKHR(
-                dp->disp[c->impl].dpy, c->context, target, buffer, attrib_list);
-        if (image == EGL_NO_IMAGE_KHR)
-            return image;
-            
-        egl_image_t* result = new egl_image_t(dpy, ctx);
-        result->images[c->impl] = image;
-        return (EGLImageKHR)result;
-    } else {
-        // EGL_NO_CONTEXT is a valid parameter
+    ContextRef _c(dp, ctx);
+    egl_context_t * const c = _c.get();
 
-        /* Since we don't have a way to know which implementation to call,
-         * we're calling all of them. If at least one of the implementation
-         * succeeded, this is a success.
-         */
-
-        EGLint currentError = eglGetError();
-
-        EGLImageKHR implImages[IMPL_NUM_IMPLEMENTATIONS];
-        bool success = false;
-        for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
-            egl_connection_t* const cnx = &gEGLImpl[i];
-            implImages[i] = EGL_NO_IMAGE_KHR;
-            if (cnx->dso) {
-                if (cnx->egl.eglCreateImageKHR) {
-                    implImages[i] = cnx->egl.eglCreateImageKHR(
-                            dp->disp[i].dpy, ctx, target, buffer, attrib_list);
-                    if (implImages[i] != EGL_NO_IMAGE_KHR) {
-                        success = true;
-                    }
-                }
-            }
-        }
-
-        if (!success) {
-            // failure, if there was an error when we entered this function,
-            // the error flag must not be updated.
-            // Otherwise, the error is whatever happened in the implementation
-            // that faulted.
-            if (currentError != EGL_SUCCESS) {
-                setError(currentError, EGL_NO_IMAGE_KHR);
-            }
-            return EGL_NO_IMAGE_KHR;
-        } else {
-            // In case of success, we need to clear all error flags
-            // (especially those caused by the implementation that didn't
-            // succeed). TODO: we could avoid this if we knew this was
-            // a "full" success (all implementation succeeded).
-            eglGetError();
-        }
-
-        egl_image_t* result = new egl_image_t(dpy, ctx);
-        memcpy(result->images, implImages, sizeof(implImages));
-        return (EGLImageKHR)result;
+    EGLImageKHR result = EGL_NO_IMAGE_KHR;
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && cnx->egl.eglCreateImageKHR) {
+        result = cnx->egl.eglCreateImageKHR(
+                dp->disp.dpy,
+                c ? c->context : EGL_NO_CONTEXT,
+                target, buffer, attrib_list);
     }
+    return result;
 }
 
 EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
@@ -1307,29 +1012,10 @@
     egl_display_t const * const dp = validate_display(dpy);
     if (!dp) return EGL_FALSE;
 
-    ImageRef _i(dp, img);
-    if (!_i.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE);
-
-    egl_image_t* image = get_image(img);
-    bool success = false;
-    for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
-        egl_connection_t* const cnx = &gEGLImpl[i];
-        if (image->images[i] != EGL_NO_IMAGE_KHR) {
-            if (cnx->dso) {
-                if (cnx->egl.eglDestroyImageKHR) {
-                    if (cnx->egl.eglDestroyImageKHR(
-                            dp->disp[i].dpy, image->images[i])) {
-                        success = true;
-                    }
-                }
-            }
-        }
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && cnx->egl.eglDestroyImageKHR) {
+        cnx->egl.eglDestroyImageKHR(dp->disp.dpy, img);
     }
-    if (!success)
-        return EGL_FALSE;
-
-    _i.terminate();
-
     return EGL_TRUE;
 }
 
@@ -1345,21 +1031,12 @@
     egl_display_t const * const dp = validate_display(dpy);
     if (!dp) return EGL_NO_SYNC_KHR;
 
-    EGLContext ctx = eglGetCurrentContext();
-    ContextRef _c(dp, ctx);
-    if (!_c.get())
-        return setError(EGL_BAD_CONTEXT, EGL_NO_SYNC_KHR);
-
-    egl_context_t * const c = get_context(ctx);
     EGLSyncKHR result = EGL_NO_SYNC_KHR;
-    if (c->cnx->egl.eglCreateSyncKHR) {
-        EGLSyncKHR sync = c->cnx->egl.eglCreateSyncKHR(
-                dp->disp[c->impl].dpy, type, attrib_list);
-        if (sync == EGL_NO_SYNC_KHR)
-            return sync;
-        result = (egl_sync_t*)new egl_sync_t(dpy, ctx, sync);
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && cnx->egl.eglCreateSyncKHR) {
+        result = cnx->egl.eglCreateSyncKHR(dp->disp.dpy, type, attrib_list);
     }
-    return (EGLSyncKHR)result;
+    return result;
 }
 
 EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync)
@@ -1369,75 +1046,46 @@
     egl_display_t const * const dp = validate_display(dpy);
     if (!dp) return EGL_FALSE;
 
-    SyncRef _s(dp, sync);
-    if (!_s.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE);
-    egl_sync_t* syncObject = get_sync(sync);
-
-    EGLContext ctx = syncObject->context;
-    ContextRef _c(dp, ctx);
-    if (!_c.get())
-        return setError(EGL_BAD_CONTEXT, EGL_FALSE);
-
     EGLBoolean result = EGL_FALSE;
-    egl_context_t * const c = get_context(ctx);
-    if (c->cnx->egl.eglDestroySyncKHR) {
-        result = c->cnx->egl.eglDestroySyncKHR(
-                dp->disp[c->impl].dpy, syncObject->sync);
-        if (result)
-            _s.terminate();
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && cnx->egl.eglDestroySyncKHR) {
+        result = cnx->egl.eglDestroySyncKHR(dp->disp.dpy, sync);
     }
     return result;
 }
 
-EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout)
+EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync,
+        EGLint flags, EGLTimeKHR timeout)
 {
     clearError();
 
     egl_display_t const * const dp = validate_display(dpy);
     if (!dp) return EGL_FALSE;
 
-    SyncRef _s(dp, sync);
-    if (!_s.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE);
-    egl_sync_t* syncObject = get_sync(sync);
-
-    EGLContext ctx = syncObject->context;
-    ContextRef _c(dp, ctx);
-    if (!_c.get())
-        return setError(EGL_BAD_CONTEXT, EGL_FALSE);
-
-    egl_context_t * const c = get_context(ctx);
-    if (c->cnx->egl.eglClientWaitSyncKHR) {
-        return c->cnx->egl.eglClientWaitSyncKHR(
-                dp->disp[c->impl].dpy, syncObject->sync, flags, timeout);
+    EGLBoolean result = EGL_FALSE;
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && cnx->egl.eglClientWaitSyncKHR) {
+        result = cnx->egl.eglClientWaitSyncKHR(
+                dp->disp.dpy, sync, flags, timeout);
     }
-
-    return EGL_FALSE;
+    return result;
 }
 
-EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value)
+EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync,
+        EGLint attribute, EGLint *value)
 {
     clearError();
 
     egl_display_t const * const dp = validate_display(dpy);
     if (!dp) return EGL_FALSE;
 
-    SyncRef _s(dp, sync);
-    if (!_s.get())
-        return setError(EGL_BAD_PARAMETER, EGL_FALSE);
-
-    egl_sync_t* syncObject = get_sync(sync);
-    EGLContext ctx = syncObject->context;
-    ContextRef _c(dp, ctx);
-    if (!_c.get())
-        return setError(EGL_BAD_CONTEXT, EGL_FALSE);
-
-    egl_context_t * const c = get_context(ctx);
-    if (c->cnx->egl.eglGetSyncAttribKHR) {
-        return c->cnx->egl.eglGetSyncAttribKHR(
-                dp->disp[c->impl].dpy, syncObject->sync, attribute, value);
+    EGLBoolean result = EGL_FALSE;
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && cnx->egl.eglGetSyncAttribKHR) {
+        result = cnx->egl.eglGetSyncAttribKHR(
+                dp->disp.dpy, sync, attribute, value);
     }
-
-    return EGL_FALSE;
+    return result;
 }
 
 // ----------------------------------------------------------------------------
@@ -1458,12 +1106,10 @@
     }
 
     EGLuint64NV ret = 0;
-    egl_connection_t* const cnx = &gEGLImpl[IMPL_HARDWARE];
+    egl_connection_t* const cnx = &gEGLImpl;
 
-    if (cnx->dso) {
-        if (cnx->egl.eglGetSystemTimeFrequencyNV) {
-            return cnx->egl.eglGetSystemTimeFrequencyNV();
-        }
+    if (cnx->dso && cnx->egl.eglGetSystemTimeFrequencyNV) {
+        return cnx->egl.eglGetSystemTimeFrequencyNV();
     }
 
     return setErrorQuiet(EGL_BAD_DISPLAY, 0);
@@ -1478,12 +1124,10 @@
     }
 
     EGLuint64NV ret = 0;
-    egl_connection_t* const cnx = &gEGLImpl[IMPL_HARDWARE];
+    egl_connection_t* const cnx = &gEGLImpl;
 
-    if (cnx->dso) {
-        if (cnx->egl.eglGetSystemTimeNV) {
-            return cnx->egl.eglGetSystemTimeNV();
-        }
+    if (cnx->dso && cnx->egl.eglGetSystemTimeNV) {
+        return cnx->egl.eglGetSystemTimeNV();
     }
 
     return setErrorQuiet(EGL_BAD_DISPLAY, 0);
diff --git a/opengl/libs/EGL/egl_cache.cpp b/opengl/libs/EGL/egl_cache.cpp
index 7fd6519..c79fb5f 100644
--- a/opengl/libs/EGL/egl_cache.cpp
+++ b/opengl/libs/EGL/egl_cache.cpp
@@ -83,39 +83,39 @@
 
 void egl_cache_t::initialize(egl_display_t *display) {
     Mutex::Autolock lock(mMutex);
-    for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
-        egl_connection_t* const cnx = &gEGLImpl[i];
-        if (cnx->dso && cnx->major >= 0 && cnx->minor >= 0) {
-            const char* exts = display->disp[i].queryString.extensions;
-            size_t bcExtLen = strlen(BC_EXT_STR);
-            size_t extsLen = strlen(exts);
-            bool equal = !strcmp(BC_EXT_STR, exts);
-            bool atStart = !strncmp(BC_EXT_STR " ", exts, bcExtLen+1);
-            bool atEnd = (bcExtLen+1) < extsLen &&
-                    !strcmp(" " BC_EXT_STR, exts + extsLen - (bcExtLen+1));
-            bool inMiddle = strstr(exts, " " BC_EXT_STR " ");
-            if (equal || atStart || atEnd || inMiddle) {
-                PFNEGLSETBLOBCACHEFUNCSANDROIDPROC eglSetBlobCacheFuncsANDROID;
-                eglSetBlobCacheFuncsANDROID =
-                        reinterpret_cast<PFNEGLSETBLOBCACHEFUNCSANDROIDPROC>(
+
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && cnx->major >= 0 && cnx->minor >= 0) {
+        const char* exts = display->disp.queryString.extensions;
+        size_t bcExtLen = strlen(BC_EXT_STR);
+        size_t extsLen = strlen(exts);
+        bool equal = !strcmp(BC_EXT_STR, exts);
+        bool atStart = !strncmp(BC_EXT_STR " ", exts, bcExtLen+1);
+        bool atEnd = (bcExtLen+1) < extsLen &&
+                !strcmp(" " BC_EXT_STR, exts + extsLen - (bcExtLen+1));
+        bool inMiddle = strstr(exts, " " BC_EXT_STR " ");
+        if (equal || atStart || atEnd || inMiddle) {
+            PFNEGLSETBLOBCACHEFUNCSANDROIDPROC eglSetBlobCacheFuncsANDROID;
+            eglSetBlobCacheFuncsANDROID =
+                    reinterpret_cast<PFNEGLSETBLOBCACHEFUNCSANDROIDPROC>(
                             cnx->egl.eglGetProcAddress(
                                     "eglSetBlobCacheFuncsANDROID"));
-                if (eglSetBlobCacheFuncsANDROID == NULL) {
-                    ALOGE("EGL_ANDROID_blob_cache advertised by display %d, "
-                            "but unable to get eglSetBlobCacheFuncsANDROID", i);
-                    continue;
-                }
+            if (eglSetBlobCacheFuncsANDROID == NULL) {
+                ALOGE("EGL_ANDROID_blob_cache advertised, "
+                        "but unable to get eglSetBlobCacheFuncsANDROID");
+                return;
+            }
 
-                eglSetBlobCacheFuncsANDROID(display->disp[i].dpy,
-                        android::setBlob, android::getBlob);
-                EGLint err = cnx->egl.eglGetError();
-                if (err != EGL_SUCCESS) {
-                    ALOGE("eglSetBlobCacheFuncsANDROID resulted in an error: "
-                            "%#x", err);
-                }
+            eglSetBlobCacheFuncsANDROID(display->disp.dpy,
+                    android::setBlob, android::getBlob);
+            EGLint err = cnx->egl.eglGetError();
+            if (err != EGL_SUCCESS) {
+                ALOGE("eglSetBlobCacheFuncsANDROID resulted in an error: "
+                        "%#x", err);
             }
         }
     }
+
     mInitialized = true;
 }
 
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 6b2ae51..c85b4ce 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -60,18 +60,12 @@
 extern void initEglTraceLevel();
 extern void setGLHooksThreadSpecific(gl_hooks_t const *value);
 
-static int cmp_configs(const void* a, const void *b) {
-    const egl_config_t& c0 = *(egl_config_t const *)a;
-    const egl_config_t& c1 = *(egl_config_t const *)b;
-    return c0<c1 ? -1 : (c1<c0 ? 1 : 0);
-}
-
 // ----------------------------------------------------------------------------
 
 egl_display_t egl_display_t::sDisplay[NUM_DISPLAYS];
 
 egl_display_t::egl_display_t() :
-    magic('_dpy'), numTotalConfigs(0), configs(0), refs(0) {
+    magic('_dpy'), refs(0) {
 }
 
 egl_display_t::~egl_display_t() {
@@ -119,15 +113,13 @@
     // get our driver loader
     Loader& loader(Loader::getInstance());
 
-    for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
-        egl_connection_t* const cnx = &gEGLImpl[i];
-        if (cnx->dso && disp[i].dpy == EGL_NO_DISPLAY) {
-            EGLDisplay dpy = cnx->egl.eglGetDisplay(display);
-            disp[i].dpy = dpy;
-            if (dpy == EGL_NO_DISPLAY) {
-                loader.close(cnx->dso);
-                cnx->dso = NULL;
-            }
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && disp.dpy == EGL_NO_DISPLAY) {
+        EGLDisplay dpy = cnx->egl.eglGetDisplay(display);
+        disp.dpy = dpy;
+        if (dpy == EGL_NO_DISPLAY) {
+            loader.close(cnx->dso);
+            cnx->dso = NULL;
         }
     }
 
@@ -160,12 +152,11 @@
     // initialize each EGL and
     // build our own extension string first, based on the extension we know
     // and the extension supported by our client implementation
-    for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
-        egl_connection_t* const cnx = &gEGLImpl[i];
-        cnx->major = -1;
-        cnx->minor = -1;
-        if (!cnx->dso)
-            continue;
+
+    egl_connection_t* const cnx = &gEGLImpl;
+    cnx->major = -1;
+    cnx->minor = -1;
+    if (cnx->dso) {
 
 #if defined(ADRENO130)
 #warning "Adreno-130 eglInitialize() workaround"
@@ -177,31 +168,30 @@
          * eglGetDisplay() before calling eglInitialize();
          */
         if (i == IMPL_HARDWARE) {
-            disp[i].dpy =
-            cnx->egl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
+            disp[i].dpy = cnx->egl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
         }
 #endif
 
-        EGLDisplay idpy = disp[i].dpy;
+        EGLDisplay idpy = disp.dpy;
         if (cnx->egl.eglInitialize(idpy, &cnx->major, &cnx->minor)) {
-            //ALOGD("initialized %d dpy=%p, ver=%d.%d, cnx=%p",
-            //        i, idpy, cnx->major, cnx->minor, cnx);
+            //ALOGD("initialized dpy=%p, ver=%d.%d, cnx=%p",
+            //        idpy, cnx->major, cnx->minor, cnx);
 
             // display is now initialized
-            disp[i].state = egl_display_t::INITIALIZED;
+            disp.state = egl_display_t::INITIALIZED;
 
             // get the query-strings for this display for each implementation
-            disp[i].queryString.vendor = cnx->egl.eglQueryString(idpy,
+            disp.queryString.vendor = cnx->egl.eglQueryString(idpy,
                     EGL_VENDOR);
-            disp[i].queryString.version = cnx->egl.eglQueryString(idpy,
+            disp.queryString.version = cnx->egl.eglQueryString(idpy,
                     EGL_VERSION);
-            disp[i].queryString.extensions = cnx->egl.eglQueryString(idpy,
+            disp.queryString.extensions = cnx->egl.eglQueryString(idpy,
                     EGL_EXTENSIONS);
-            disp[i].queryString.clientApi = cnx->egl.eglQueryString(idpy,
+            disp.queryString.clientApi = cnx->egl.eglQueryString(idpy,
                     EGL_CLIENT_APIS);
 
         } else {
-            ALOGW("%d: eglInitialize(%p) failed (%s)", i, idpy,
+            ALOGW("eglInitialize(%p) failed (%s)", idpy,
                     egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
         }
     }
@@ -211,7 +201,7 @@
     mVersionString.setTo(sVersionString);
     mClientApiString.setTo(sClientApiString);
 
-    // we only add extensions that exist in at least one implementation
+    // we only add extensions that exist in the implementation
     char const* start = sExtensionString;
     char const* end;
     do {
@@ -223,15 +213,13 @@
             if (len) {
                 // NOTE: we could avoid the copy if we had strnstr.
                 const String8 ext(start, len);
-                // now go through all implementations and look for this extension
-                for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
-                    if (disp[i].queryString.extensions) {
-                        // if we find it, add this extension string to our list
-                        // (and don't forget the space)
-                        const char* match = strstr(disp[i].queryString.extensions, ext.string());
-                        if (match && (match[len] == ' ' || match[len] == 0)) {
-                            mExtensionString.append(start, len+1);
-                        }
+                // now look for this extension
+                if (disp.queryString.extensions) {
+                    // if we find it, add this extension string to our list
+                    // (and don't forget the space)
+                    const char* match = strstr(disp.queryString.extensions, ext.string());
+                    if (match && (match[len] == ' ' || match[len] == 0)) {
+                        mExtensionString.append(start, len+1);
                     }
                 }
             }
@@ -242,52 +230,12 @@
 
     egl_cache_t::get()->initialize(this);
 
-    EGLBoolean res = EGL_FALSE;
-    for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
-        egl_connection_t* const cnx = &gEGLImpl[i];
-        if (cnx->dso && cnx->major >= 0 && cnx->minor >= 0) {
-            EGLint n;
-            if (cnx->egl.eglGetConfigs(disp[i].dpy, 0, 0, &n)) {
-                disp[i].config = (EGLConfig*) malloc(sizeof(EGLConfig) * n);
-                if (disp[i].config) {
-                    if (cnx->egl.eglGetConfigs(disp[i].dpy, disp[i].config, n,
-                            &disp[i].numConfigs)) {
-                        numTotalConfigs += n;
-                        res = EGL_TRUE;
-                    }
-                }
-            }
-        }
-    }
-
-    if (res == EGL_TRUE) {
-        configs = new egl_config_t[numTotalConfigs];
-        for (int i = 0, k = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
-            egl_connection_t* const cnx = &gEGLImpl[i];
-            if (cnx->dso && cnx->major >= 0 && cnx->minor >= 0) {
-                for (int j = 0; j < disp[i].numConfigs; j++) {
-                    configs[k].impl = i;
-                    configs[k].config = disp[i].config[j];
-                    configs[k].configId = k + 1; // CONFIG_ID start at 1
-                    // store the implementation's CONFIG_ID
-                    cnx->egl.eglGetConfigAttrib(disp[i].dpy, disp[i].config[j],
-                            EGL_CONFIG_ID, &configs[k].implConfigId);
-                    k++;
-                }
-            }
-        }
-
-        // sort our configurations so we can do binary-searches
-        qsort(configs, numTotalConfigs, sizeof(egl_config_t), cmp_configs);
-
-        refs++;
-        if (major != NULL)
-            *major = VERSION_MAJOR;
-        if (minor != NULL)
-            *minor = VERSION_MINOR;
-        return EGL_TRUE;
-    }
-    return setError(EGL_NOT_INITIALIZED, EGL_FALSE);
+    refs++;
+    if (major != NULL)
+        *major = VERSION_MAJOR;
+    if (minor != NULL)
+        *minor = VERSION_MINOR;
+    return EGL_TRUE;
 }
 
 EGLBoolean egl_display_t::terminate() {
@@ -305,22 +253,15 @@
     }
 
     EGLBoolean res = EGL_FALSE;
-    for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
-        egl_connection_t* const cnx = &gEGLImpl[i];
-        if (cnx->dso && disp[i].state == egl_display_t::INITIALIZED) {
-            if (cnx->egl.eglTerminate(disp[i].dpy) == EGL_FALSE) {
-                ALOGW("%d: eglTerminate(%p) failed (%s)", i, disp[i].dpy,
-                        egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
-            }
-            // REVISIT: it's unclear what to do if eglTerminate() fails
-            free(disp[i].config);
-
-            disp[i].numConfigs = 0;
-            disp[i].config = 0;
-            disp[i].state = egl_display_t::TERMINATED;
-
-            res = EGL_TRUE;
+    egl_connection_t* const cnx = &gEGLImpl;
+    if (cnx->dso && disp.state == egl_display_t::INITIALIZED) {
+        if (cnx->egl.eglTerminate(disp.dpy) == EGL_FALSE) {
+            ALOGW("eglTerminate(%p) failed (%s)", disp.dpy,
+                    egl_tls_t::egl_strerror(cnx->egl.eglGetError()));
         }
+        // REVISIT: it's unclear what to do if eglTerminate() fails
+        disp.state = egl_display_t::TERMINATED;
+        res = EGL_TRUE;
     }
 
     // Mark all objects remaining in the list as terminated, unless
@@ -337,8 +278,6 @@
     objects.clear();
 
     refs--;
-    numTotalConfigs = 0;
-    delete[] configs;
     return res;
 }
 
@@ -390,13 +329,13 @@
         Mutex::Autolock _l(lock);
         if (c) {
             result = c->cnx->egl.eglMakeCurrent(
-                    disp[c->impl].dpy, impl_draw, impl_read, impl_ctx);
+                    disp.dpy, impl_draw, impl_read, impl_ctx);
             if (result == EGL_TRUE) {
                 c->onMakeCurrent(draw, read);
             }
         } else {
             result = cur_c->cnx->egl.eglMakeCurrent(
-                    disp[cur_c->impl].dpy, impl_draw, impl_read, impl_ctx);
+                    disp.dpy, impl_draw, impl_read, impl_ctx);
             if (result == EGL_TRUE) {
                 cur_c->onLooseCurrent();
             }
diff --git a/opengl/libs/EGL/egl_display.h b/opengl/libs/EGL/egl_display.h
index f3c4ddf..6348228 100644
--- a/opengl/libs/EGL/egl_display.h
+++ b/opengl/libs/EGL/egl_display.h
@@ -44,23 +44,6 @@
 
 // ----------------------------------------------------------------------------
 
-struct egl_config_t {
-    egl_config_t() {}
-    egl_config_t(int impl, EGLConfig config)
-        : impl(impl), config(config), configId(0), implConfigId(0) { }
-    int         impl;           // the implementation this config is for
-    EGLConfig   config;         // the implementation's EGLConfig
-    EGLint      configId;       // our CONFIG_ID
-    EGLint      implConfigId;   // the implementation's CONFIG_ID
-    inline bool operator < (const egl_config_t& rhs) const {
-        if (impl < rhs.impl) return true;
-        if (impl > rhs.impl) return false;
-        return config < rhs.config;
-    }
-};
-
-// ----------------------------------------------------------------------------
-
 class EGLAPI egl_display_t { // marked as EGLAPI for testing purposes
     static egl_display_t sDisplay[NUM_DISPLAYS];
     EGLDisplay getDisplay(EGLNativeDisplayType display);
@@ -113,12 +96,9 @@
     };
 
     struct DisplayImpl {
-        DisplayImpl() : dpy(EGL_NO_DISPLAY), config(0),
-                        state(NOT_INITIALIZED), numConfigs(0) { }
+        DisplayImpl() : dpy(EGL_NO_DISPLAY), state(NOT_INITIALIZED) { }
         EGLDisplay  dpy;
-        EGLConfig*  config;
         EGLint      state;
-        EGLint      numConfigs;
         strings_t   queryString;
     };
 
@@ -126,9 +106,7 @@
     uint32_t        magic;
 
 public:
-    DisplayImpl     disp[IMPL_NUM_IMPLEMENTATIONS];
-    EGLint          numTotalConfigs;
-    egl_config_t*   configs;
+    DisplayImpl     disp;
 
 private:
             uint32_t                    refs;
diff --git a/opengl/libs/EGL/egl_object.cpp b/opengl/libs/EGL/egl_object.cpp
index b660c53..d0cbb31 100644
--- a/opengl/libs/EGL/egl_object.cpp
+++ b/opengl/libs/EGL/egl_object.cpp
@@ -64,9 +64,9 @@
 // ----------------------------------------------------------------------------
 
 egl_context_t::egl_context_t(EGLDisplay dpy, EGLContext context, EGLConfig config,
-        int impl, egl_connection_t const* cnx, int version) :
+        egl_connection_t const* cnx, int version) :
     egl_object_t(get_display(dpy)), dpy(dpy), context(context),
-            config(config), read(0), draw(0), impl(impl), cnx(cnx),
+            config(config), read(0), draw(0), cnx(cnx),
             version(version)
 {
 }
@@ -87,7 +87,7 @@
 
     if (gl_extensions.isEmpty()) {
         // call the implementation's glGetString(GL_EXTENSIONS)
-        const char* exts = (const char *)gEGLImpl[impl].hooks[version]->gl.glGetString(GL_EXTENSIONS);
+        const char* exts = (const char *)gEGLImpl.hooks[version]->gl.glGetString(GL_EXTENSIONS);
         gl_extensions.setTo(exts);
         if (gl_extensions.find("GL_EXT_debug_marker") < 0) {
             String8 temp("GL_EXT_debug_marker ");
diff --git a/opengl/libs/EGL/egl_object.h b/opengl/libs/EGL/egl_object.h
index abd4cbb..4d91f54 100644
--- a/opengl/libs/EGL/egl_object.h
+++ b/opengl/libs/EGL/egl_object.h
@@ -125,7 +125,7 @@
 
 // ----------------------------------------------------------------------------
 
-class egl_surface_t: public egl_object_t {
+class egl_surface_t : public egl_object_t {
 protected:
     ~egl_surface_t() {
         ANativeWindow* const window = win.get();
@@ -140,15 +140,14 @@
     typedef egl_object_t::LocalRef<egl_surface_t, EGLSurface> Ref;
 
     egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win,
-            EGLSurface surface, int impl, egl_connection_t const* cnx) :
+            EGLSurface surface, egl_connection_t const* cnx) :
         egl_object_t(get_display(dpy)), dpy(dpy), surface(surface),
-                config(config), win(win), impl(impl), cnx(cnx) {
+                config(config), win(win), cnx(cnx) {
     }
     EGLDisplay dpy;
     EGLSurface surface;
     EGLConfig config;
     sp<ANativeWindow> win;
-    int impl;
     egl_connection_t const* cnx;
 };
 
@@ -159,7 +158,7 @@
     typedef egl_object_t::LocalRef<egl_context_t, EGLContext> Ref;
 
     egl_context_t(EGLDisplay dpy, EGLContext context, EGLConfig config,
-            int impl, egl_connection_t const* cnx, int version);
+            egl_connection_t const* cnx, int version);
 
     void onLooseCurrent();
     void onMakeCurrent(EGLSurface draw, EGLSurface read);
@@ -169,47 +168,15 @@
     EGLConfig config;
     EGLSurface read;
     EGLSurface draw;
-    int impl;
     egl_connection_t const* cnx;
     int version;
     String8 gl_extensions;
 };
 
-class egl_image_t: public egl_object_t {
-protected:
-    ~egl_image_t() {}
-public:
-    typedef egl_object_t::LocalRef<egl_image_t, EGLImageKHR> Ref;
-
-    egl_image_t(EGLDisplay dpy, EGLContext context) :
-        egl_object_t(get_display(dpy)), dpy(dpy), context(context) {
-        memset(images, 0, sizeof(images));
-    }
-    EGLDisplay dpy;
-    EGLContext context;
-    EGLImageKHR images[IMPL_NUM_IMPLEMENTATIONS];
-};
-
-class egl_sync_t: public egl_object_t {
-protected:
-    ~egl_sync_t() {}
-public:
-    typedef egl_object_t::LocalRef<egl_sync_t, EGLSyncKHR> Ref;
-
-    egl_sync_t(EGLDisplay dpy, EGLContext context, EGLSyncKHR sync) :
-        egl_object_t(get_display(dpy)), dpy(dpy), context(context), sync(sync) {
-    }
-    EGLDisplay dpy;
-    EGLContext context;
-    EGLSyncKHR sync;
-};
-
 // ----------------------------------------------------------------------------
 
 typedef egl_surface_t::Ref  SurfaceRef;
 typedef egl_context_t::Ref  ContextRef;
-typedef egl_image_t::Ref    ImageRef;
-typedef egl_sync_t::Ref     SyncRef;
 
 // ----------------------------------------------------------------------------
 
@@ -228,16 +195,6 @@
     return egl_to_native_cast<egl_context_t>(context);
 }
 
-static inline
-egl_image_t* get_image(EGLImageKHR image) {
-    return egl_to_native_cast<egl_image_t>(image);
-}
-
-static inline
-egl_sync_t* get_sync(EGLSyncKHR sync) {
-    return egl_to_native_cast<egl_sync_t>(sync);
-}
-
 // ----------------------------------------------------------------------------
 }; // namespace android
 // ----------------------------------------------------------------------------
diff --git a/opengl/libs/EGL/egldefs.h b/opengl/libs/EGL/egldefs.h
index ff20957..c900c1c 100644
--- a/opengl/libs/EGL/egldefs.h
+++ b/opengl/libs/EGL/egldefs.h
@@ -19,31 +19,24 @@
 
 #include "hooks.h"
 
+#define VERSION_MAJOR 1
+#define VERSION_MINOR 4
+
 // ----------------------------------------------------------------------------
 namespace android {
 // ----------------------------------------------------------------------------
 
-#define VERSION_MAJOR 1
-#define VERSION_MINOR 4
-
 //  EGLDisplay are global, not attached to a given thread
 const unsigned int NUM_DISPLAYS = 1;
 
-enum {
-    IMPL_HARDWARE = 0,
-    IMPL_SOFTWARE,
-    IMPL_NUM_IMPLEMENTATIONS
-};
-
-enum {
-    GLESv1_INDEX = 0,
-    GLESv2_INDEX = 1,
-};
-
 // ----------------------------------------------------------------------------
 
-struct egl_connection_t
-{
+struct egl_connection_t {
+    enum {
+        GLESv1_INDEX = 0,
+        GLESv2_INDEX = 1
+    };
+
     inline egl_connection_t() : dso(0) { }
     void *              dso;
     gl_hooks_t *        hooks[2];
@@ -54,7 +47,7 @@
 
 // ----------------------------------------------------------------------------
 
-extern gl_hooks_t gHooks[2][IMPL_NUM_IMPLEMENTATIONS];
+extern gl_hooks_t gHooks[2];
 extern gl_hooks_t gHooksNoContext;
 extern pthread_key_t gGLWrapperKey;
 extern "C" void gl_unimplemented();
@@ -63,7 +56,7 @@
 extern char const * const gl_names[];
 extern char const * const egl_names[];
 
-extern egl_connection_t gEGLImpl[IMPL_NUM_IMPLEMENTATIONS];
+extern egl_connection_t gEGLImpl;
 
 // ----------------------------------------------------------------------------
 }; // namespace android
diff --git a/opengl/libs/GLES2/gl2.cpp b/opengl/libs/GLES2/gl2.cpp
index 79aa3cd..4345c2b 100644
--- a/opengl/libs/GLES2/gl2.cpp
+++ b/opengl/libs/GLES2/gl2.cpp
@@ -124,27 +124,3 @@
     }
     return ret;
 }
-
-/*
- * These GL calls are special because they need to EGL to retrieve some
- * informations before they can execute.
- */
-
-extern "C" void __glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image);
-extern "C" void __glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image);
-
-
-void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
-{
-    GLeglImageOES implImage = 
-        (GLeglImageOES)egl_get_image_for_current_context((EGLImageKHR)image);
-    __glEGLImageTargetTexture2DOES(target, implImage);
-}
-
-void glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
-{
-    GLeglImageOES implImage = 
-        (GLeglImageOES)egl_get_image_for_current_context((EGLImageKHR)image);
-    __glEGLImageTargetRenderbufferStorageOES(target, implImage);
-}
-
diff --git a/opengl/libs/GLES2/gl2ext_api.in b/opengl/libs/GLES2/gl2ext_api.in
index a8907fd..c381075 100644
--- a/opengl/libs/GLES2/gl2ext_api.in
+++ b/opengl/libs/GLES2/gl2ext_api.in
@@ -1,7 +1,7 @@
-void API_ENTRY(__glEGLImageTargetTexture2DOES)(GLenum target, GLeglImageOES image) {
+void API_ENTRY(glEGLImageTargetTexture2DOES)(GLenum target, GLeglImageOES image) {
     CALL_GL_API(glEGLImageTargetTexture2DOES, target, image);
 }
-void API_ENTRY(__glEGLImageTargetRenderbufferStorageOES)(GLenum target, GLeglImageOES image) {
+void API_ENTRY(glEGLImageTargetRenderbufferStorageOES)(GLenum target, GLeglImageOES image) {
     CALL_GL_API(glEGLImageTargetRenderbufferStorageOES, target, image);
 }
 void API_ENTRY(glGetProgramBinaryOES)(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary) {
diff --git a/opengl/libs/GLES_CM/gl.cpp b/opengl/libs/GLES_CM/gl.cpp
index adeaa5b..adcb60d 100644
--- a/opengl/libs/GLES_CM/gl.cpp
+++ b/opengl/libs/GLES_CM/gl.cpp
@@ -179,27 +179,3 @@
     }
     return ret;
 }
-
-/*
- * These GL calls are special because they need to EGL to retrieve some
- * informations before they can execute.
- */
-
-extern "C" void __glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image);
-extern "C" void __glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image);
-
-
-void glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
-{
-    GLeglImageOES implImage = 
-        (GLeglImageOES)egl_get_image_for_current_context((EGLImageKHR)image);
-    __glEGLImageTargetTexture2DOES(target, implImage);
-}
-
-void glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
-{
-    GLeglImageOES implImage = 
-        (GLeglImageOES)egl_get_image_for_current_context((EGLImageKHR)image);
-    __glEGLImageTargetRenderbufferStorageOES(target, implImage);
-}
-
diff --git a/opengl/libs/GLES_CM/glext_api.in b/opengl/libs/GLES_CM/glext_api.in
index 268a535..7cd6cb5 100644
--- a/opengl/libs/GLES_CM/glext_api.in
+++ b/opengl/libs/GLES_CM/glext_api.in
@@ -31,10 +31,10 @@
 void API_ENTRY(glDrawTexfvOES)(const GLfloat *coords) {
     CALL_GL_API(glDrawTexfvOES, coords);
 }
-void API_ENTRY(__glEGLImageTargetTexture2DOES)(GLenum target, GLeglImageOES image) {
+void API_ENTRY(glEGLImageTargetTexture2DOES)(GLenum target, GLeglImageOES image) {
     CALL_GL_API(glEGLImageTargetTexture2DOES, target, image);
 }
-void API_ENTRY(__glEGLImageTargetRenderbufferStorageOES)(GLenum target, GLeglImageOES image) {
+void API_ENTRY(glEGLImageTargetRenderbufferStorageOES)(GLenum target, GLeglImageOES image) {
     CALL_GL_API(glEGLImageTargetRenderbufferStorageOES, target, image);
 }
 void API_ENTRY(glAlphaFuncxOES)(GLenum func, GLclampx ref) {
diff --git a/opengl/libs/GLES_trace/src/gltrace_fixup.cpp b/opengl/libs/GLES_trace/src/gltrace_fixup.cpp
index 871b5dc..3e185bc 100644
--- a/opengl/libs/GLES_trace/src/gltrace_fixup.cpp
+++ b/opengl/libs/GLES_trace/src/gltrace_fixup.cpp
@@ -15,9 +15,13 @@
  */
 
 #include <cutils/log.h>
+#include <GLES/gl.h>
+#include <GLES/glext.h>
 #include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
 
 #include "gltrace.pb.h"
+#include "gltrace_api.h"
 #include "gltrace_context.h"
 #include "gltrace_fixup.h"
 
@@ -198,6 +202,20 @@
     arg_strpp->add_charvalue(src);
 }
 
+void fixup_glUniformGenericInteger(int argIndex, int nIntegers, GLMessage *glmsg) {
+    /* void glUniform?iv(GLint location, GLsizei count, const GLint *value); */
+    GLMessage_DataType *arg_values = glmsg->mutable_args(argIndex);
+    GLint *src = (GLint*)arg_values->intvalue(0);
+
+    arg_values->set_type(GLMessage::DataType::INT);
+    arg_values->set_isarray(true);
+    arg_values->clear_intvalue();
+
+    for (int i = 0; i < nIntegers; i++) {
+        arg_values->add_intvalue(*src++);
+    }
+}
+
 void fixup_glUniformGeneric(int argIndex, int nFloats, GLMessage *glmsg) {
     GLMessage_DataType *arg_values = glmsg->mutable_args(argIndex);
     GLfloat *src = (GLfloat*)arg_values->intvalue(0);
@@ -223,6 +241,10 @@
     GLMessage_DataType *arg_intarray = glmsg->mutable_args(argIndex);
     GLint *intp = (GLint *)arg_intarray->intvalue(0);
 
+    if (intp == NULL) {
+        return;
+    }
+
     arg_intarray->set_type(GLMessage::DataType::INT);
     arg_intarray->set_isarray(true);
     arg_intarray->clear_intvalue();
@@ -232,6 +254,15 @@
     }
 }
 
+void fixup_GenericEnumArray(int argIndex, int nEnums, GLMessage *glmsg) {
+    // fixup as if they were ints
+    fixup_GenericIntArray(argIndex, nEnums, glmsg);
+
+    // and then set the data type to be enum
+    GLMessage_DataType *arg_enumarray = glmsg->mutable_args(argIndex);
+    arg_enumarray->set_type(GLMessage::DataType::ENUM);
+}
+
 void fixup_glGenGeneric(GLMessage *glmsg) {
     /* void glGen*(GLsizei n, GLuint * buffers); */
     GLMessage_DataType arg_n  = glmsg->args(0);
@@ -270,6 +301,84 @@
     arg_params->add_floatvalue(*src);
 }
 
+void fixup_glLinkProgram(GLMessage *glmsg) {
+    /* void glLinkProgram(GLuint program); */
+    GLuint program = glmsg->args(0).intvalue(0);
+
+    /* We don't have to fixup this call, but as soon as a program is linked,
+       we obtain information about all active attributes and uniforms to
+       pass on to the debugger. Note that in order to pass this info to
+       the debugger, all we need to do is call the trace versions of the
+       necessary calls. */
+
+    GLint n, maxNameLength;
+    GLchar *name;
+    GLint size;
+    GLenum type;
+
+    // obtain info regarding active attributes
+    GLTrace_glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &n);
+    GLTrace_glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxNameLength);
+
+    name = (GLchar *) malloc(maxNameLength);
+    for (int i = 0; i < n; i++) {
+        GLTrace_glGetActiveAttrib(program, i, maxNameLength, NULL, &size, &type, name);
+    }
+    free(name);
+
+    // obtain info regarding active uniforms
+    GLTrace_glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &n);
+    GLTrace_glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength);
+
+    name = (GLchar *) malloc(maxNameLength);
+    for (int i = 0; i < n; i++) {
+        GLTrace_glGetActiveUniform(program, i, maxNameLength, NULL, &size, &type, name);
+    }
+    free(name);
+}
+
+/** Given a glGetActive[Uniform|Attrib] call, obtain the location
+ *  of the variable in the call.
+ */
+int getShaderVariableLocation(GLTraceContext *context, GLMessage *glmsg) {
+    GLMessage_Function func = glmsg->function();
+    if (func != GLMessage::glGetActiveAttrib && func != GLMessage::glGetActiveUniform) {
+        return -1;
+    }
+
+    int program = glmsg->args(0).intvalue(0);
+    GLchar *name = (GLchar*) glmsg->args(6).intvalue(0);
+
+    if (func == GLMessage::glGetActiveAttrib) {
+        return context->hooks->gl.glGetAttribLocation(program, name);
+    } else {
+        return context->hooks->gl.glGetUniformLocation(program, name);
+    }
+}
+
+void fixup_glGetActiveAttribOrUniform(GLMessage *glmsg, int location) {
+    /* void glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize,
+                GLsizei* length, GLint* size, GLenum* type, GLchar* name); */
+    /* void glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize,
+                GLsizei* length, GLint* size, GLenum* type, GLchar* name) */
+
+    fixup_GenericIntArray(3, 1, glmsg);     // length
+    fixup_GenericIntArray(4, 1, glmsg);     // size
+    fixup_GenericEnumArray(5, 1, glmsg);    // type
+    fixup_CStringPtr(6, glmsg);             // name
+
+    // The index argument in the glGetActive[Attrib|Uniform] functions
+    // does not correspond to the actual location index as used in
+    // glUniform*() or glVertexAttrib*() to actually upload the data.
+    // In order to make things simpler for the debugger, we also pass
+    // a hidden location argument that stores the actual location.
+    // append the location value to the end of the argument list
+    GLMessage_DataType *arg_location = glmsg->add_args();
+    arg_location->set_isarray(false);
+    arg_location->set_type(GLMessage::DataType::INT);
+    arg_location->add_intvalue(location);
+}
+
 void fixupGLMessage(GLTraceContext *context, nsecs_t start, nsecs_t end, GLMessage *glmsg) {
     // for all messages, set the current context id
     glmsg->set_context_id(context->getId());
@@ -292,6 +401,19 @@
     case GLMessage::glGenTextures:       /* void glGenTextures(GLsizei n, GLuint *textures); */
         fixup_glGenGeneric(glmsg);
         break;
+    case GLMessage::glLinkProgram:       /* void glLinkProgram(GLuint program); */
+        fixup_glLinkProgram(glmsg);
+        break;
+    case GLMessage::glGetActiveAttrib:
+        fixup_glGetActiveAttribOrUniform(glmsg, getShaderVariableLocation(context, glmsg));
+        break;
+    case GLMessage::glGetActiveUniform:
+        fixup_glGetActiveAttribOrUniform(glmsg, getShaderVariableLocation(context, glmsg));
+        break;
+    case GLMessage::glBindAttribLocation:
+        /* void glBindAttribLocation(GLuint program, GLuint index, const GLchar* name); */
+        fixup_CStringPtr(2, glmsg);
+        break;
     case GLMessage::glGetAttribLocation:  
     case GLMessage::glGetUniformLocation: 
         /* int glGetAttribLocation(GLuint program, const GLchar* name) */
@@ -331,6 +453,38 @@
     case GLMessage::glShaderSource:
         fixup_glShaderSource(glmsg);
         break;
+    case GLMessage::glUniform1iv:
+        /* void glUniform1iv(GLint location, GLsizei count, const GLint *value); */
+        fixup_glUniformGenericInteger(2, 1, glmsg);
+        break;
+    case GLMessage::glUniform2iv:
+        /* void glUniform2iv(GLint location, GLsizei count, const GLint *value); */
+        fixup_glUniformGenericInteger(2, 2, glmsg);
+        break;
+    case GLMessage::glUniform3iv:
+        /* void glUniform3iv(GLint location, GLsizei count, const GLint *value); */
+        fixup_glUniformGenericInteger(2, 3, glmsg);
+        break;
+    case GLMessage::glUniform4iv:
+        /* void glUniform4iv(GLint location, GLsizei count, const GLint *value); */
+        fixup_glUniformGenericInteger(2, 4, glmsg);
+        break;
+    case GLMessage::glUniform1fv:
+        /* void glUniform1fv(GLint location, GLsizei count, const GLfloat *value); */
+        fixup_glUniformGeneric(2, 1, glmsg);
+        break;
+    case GLMessage::glUniform2fv:
+        /* void glUniform2fv(GLint location, GLsizei count, const GLfloat *value); */
+        fixup_glUniformGeneric(2, 2, glmsg);
+        break;
+    case GLMessage::glUniform3fv:
+        /* void glUniform3fv(GLint location, GLsizei count, const GLfloat *value); */
+        fixup_glUniformGeneric(2, 3, glmsg);
+        break;
+    case GLMessage::glUniform4fv:
+        /* void glUniform4fv(GLint location, GLsizei count, const GLfloat *value); */
+        fixup_glUniformGeneric(2, 4, glmsg);
+        break;
     case GLMessage::glUniformMatrix2fv:
         /* void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose,
                                                                     const GLfloat* value) */
diff --git a/opengl/libs/egl_impl.h b/opengl/libs/egl_impl.h
index 8ff51ec..cb0e908 100644
--- a/opengl/libs/egl_impl.h
+++ b/opengl/libs/egl_impl.h
@@ -30,7 +30,6 @@
 // ----------------------------------------------------------------------------
 
 EGLAPI const GLubyte * egl_get_string_for_current_context(GLenum name);
-EGLAPI EGLImageKHR egl_get_image_for_current_context(EGLImageKHR image);
 
 // ----------------------------------------------------------------------------
 }; // namespace android
diff --git a/opengl/libs/tools/glapigen b/opengl/libs/tools/glapigen
index 9be40cf..4d8334f 100755
--- a/opengl/libs/tools/glapigen
+++ b/opengl/libs/tools/glapigen
@@ -37,12 +37,6 @@
   #printf("%s", $line);
   
   my $prefix = "";
-  if ($name eq "glEGLImageTargetTexture2DOES") {
-    $prefix = "__";
-  }
-  if ($name eq "glEGLImageTargetRenderbufferStorageOES") {
-    $prefix = "__";
-  }
   if ($name eq "glGetString") {
     $prefix = "__";
   }