Code drop from //branches/cupcake/...@124589
diff --git a/opengl/libGLES_CM/gl_wrapper.cpp b/opengl/libGLES_CM/gl_wrapper.cpp
index 5da4f9a..3b7f45e 100644
--- a/opengl/libGLES_CM/gl_wrapper.cpp
+++ b/opengl/libGLES_CM/gl_wrapper.cpp
@@ -373,6 +373,7 @@
 
 static sp<GPURevokeRequester> gRevokerCallback;
 
+
 static request_gpu_t* gpu_acquire(void* user)
 {
     sp<ISurfaceComposer> server( getSurfaceFlinger() );
@@ -383,7 +384,10 @@
     }
     
     ISurfaceComposer::gpu_info_t info;
-    gRevokerCallback = new GPURevokeRequester();
+    
+    if (gRevokerCallback == 0)
+        gRevokerCallback = new GPURevokeRequester();
+
     status_t err = server->requestGPU(gRevokerCallback, &info);
     if (err != NO_ERROR) {
         LOGD("requestGPU returned %d", err);
@@ -549,6 +553,21 @@
     return -1;
 }
 
+static EGLint configToUniqueId(egl_display_t const* dp, int i, int index) 
+{
+    // NOTE: this mapping works only if we have no more than two EGLimpl
+    return (i>0 ? dp->numConfigs[0] : 0) + index;
+}
+
+static void uniqueIdToConfig(egl_display_t const* dp, EGLint configId,
+        int& i, int& index) 
+{
+    // NOTE: this mapping works only if we have no more than two EGLimpl
+    size_t numConfigs = dp->numConfigs[0];
+    i = configId / numConfigs;
+    index = configId % numConfigs;
+}
+
 static int cmp_configs(const void* a, const void *b)
 {
     EGLConfig c0 = *(EGLConfig const *)a;
@@ -557,7 +576,7 @@
 }
 
 static char const * const gVendorString     = "Android";
-static char const * const gVersionString    = "1.2 Android META-EGL";
+static char const * const gVersionString    = "1.3 Android META-EGL";
 static char const * const gClientApiString  = "OpenGL ES";
 
 struct extention_map_t {
@@ -834,7 +853,13 @@
         property_get("debug.egl.hw", value, "1");
         if (atoi(value) != 0) {
             cnx->hooks = &gHooks[IMPL_HARDWARE];
-            cnx->dso = load_driver("libhgl.so", cnx->hooks);
+            property_get("debug.egl.profiler", value, "0");
+            if (atoi(value) == 0) {
+                cnx->dso = load_driver("libhgl.so", cnx->hooks);
+            } else {
+                LOGW("Using instrumented h/w OpenGL ES library");
+                cnx->dso = load_driver("libhgld.so", cnx->hooks);
+            }
         } else {
             LOGD("3D hardware acceleration is disabled");
         }
@@ -864,6 +889,8 @@
         
         d->dpys[IMPL_HARDWARE] = cnx->hooks->egl.eglGetDisplay(display);
         if (d->dpys[IMPL_HARDWARE] == EGL_NO_DISPLAY) {
+            LOGE("h/w accelerated eglGetDisplay() failed (%s)",
+                    egl_strerror(cnx->hooks->egl.eglGetError()));
             dlclose((void*)cnx->dso);
             cnx->dso = 0;
             // in case of failure, we want to make sure we don't try again
@@ -900,7 +927,10 @@
         egl_connection_t* const cnx = &gEGLImpl[i];
         cnx->major = -1;
         cnx->minor = -1;
-        if (cnx->dso && cnx->hooks->egl.eglInitialize(
+        if (!cnx->dso) 
+            continue;
+
+        if (cnx->hooks->egl.eglInitialize(
                 dp->dpys[i], &cnx->major, &cnx->minor)) {
 
             //LOGD("initialized %d dpy=%p, ver=%d.%d, cnx=%p",
@@ -912,10 +942,10 @@
             dp->queryString[i].version =
                 cnx->hooks->egl.eglQueryString(dp->dpys[i], EGL_VERSION);
             dp->queryString[i].extensions = strdup(
-                cnx->hooks->egl.eglQueryString(dp->dpys[i], EGL_EXTENSIONS));
+                    cnx->hooks->egl.eglQueryString(dp->dpys[i], EGL_EXTENSIONS));
             dp->queryString[i].clientApi =
                 cnx->hooks->egl.eglQueryString(dp->dpys[i], EGL_CLIENT_APIS);
-            
+
             // Dynamically insert extensions we know about
             if (cnx->hooks->egl.eglSwapRectangleANDROID)
                 add_extension(dp, dp->queryString[i].extensions,
@@ -924,12 +954,15 @@
             if (cnx->hooks->egl.eglQueryStringConfigANDROID)
                 add_extension(dp, dp->queryString[i].extensions,
                         "EGL_ANDROID_query_string_config");
+        } else {
+            LOGD("%d: eglInitialize() failed (%s)", 
+                    i, egl_strerror(cnx->hooks->egl.eglGetError()));
         }
     }
-            
+
     // Build the extension list that depends on the current config.
     // It is the intersection of our extension list and the
-    // underlaying EGL's extensions list
+    // underlying EGL's extensions list
     EGLBoolean res = EGL_FALSE;
     for (int i=0 ; i<2 ; i++) {
         egl_connection_t* const cnx = &gEGLImpl[i];
@@ -951,10 +984,10 @@
             } while (*p);
             free((void*)our_extensions_org);
 
-            // remove the trailling white space
+            // remove the trailing white space
             if (extensions_config[0] != 0) {
                 size_t l = strlen(extensions_config) - 1; // new size
-                extensions_config[l] = 0; // remove the trailling white space
+                extensions_config[l] = 0; // remove the trailing white space
                 extensions_config = (char*)realloc(extensions_config, l+1);
             } else {
                 extensions_config = (char*)realloc(extensions_config, 1);
@@ -1065,15 +1098,74 @@
         return EGL_TRUE;
     }
 
+    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;
+    while ((attr=attrib_list[size])) {
+        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
+        int i, index;
+        EGLint& configId(new_list[patch_index+1]);
+        uniqueIdToConfig(dp, configId, i, index);
+        
+        egl_connection_t* const cnx = &gEGLImpl[i];
+        if (cnx->dso) {
+            cnx->hooks->egl.eglGetConfigAttrib(
+                    dp->dpys[i], dp->configs[i][index], 
+                    EGL_CONFIG_ID, &configId);
+
+            // 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->hooks->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->hooks->egl.eglChooseConfig(
+                    dp->dpys[i], 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).
+                configs[0] = MAKE_CONFIG(i, index);
+                *num_config = 1;
+            }
+        }
+
+        free(const_cast<EGLint *>(attrib_list));
+        return res;
+    }
+
     for (int i=0 ; i<2 ; i++) {
         egl_connection_t* const cnx = &gEGLImpl[i];
         if (cnx->dso) {
-            EGLint n;
             if (cnx->hooks->egl.eglChooseConfig(
-                    dp->dpys[i], attrib_list, configs, config_size, &n))
-            {
+                    dp->dpys[i], attrib_list, configs, config_size, &n)) {
                 // now we need to convert these client EGLConfig to our
                 // internal EGLConfig format. This is done in O(n log n).
                 for (int j=0 ; j<n ; j++) {
@@ -1102,6 +1194,13 @@
     int i=0, index=0;
     egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index);
     if (!cnx) return EGL_FALSE;
+    
+    if (attribute == EGL_CONFIG_ID) {
+        // EGL_CONFIG_IDs must be unique, just use the order of the selected
+        // EGLConfig.
+        *value = configToUniqueId(dp, i, index);
+        return EGL_TRUE;
+    }
     return cnx->hooks->egl.eglGetConfigAttrib(
             dp->dpys[i], dp->configs[i][index], attribute, value);
 }