Merge "Modify getState to prefer AKEY_STATE_DOWN and AKEY_STATE_UP over AKEY_STATE_UNKNOWN."
diff --git a/include/utils/GenerationCache.h b/include/utils/GenerationCache.h
index bb9ddd6..83cda86 100644
--- a/include/utils/GenerationCache.h
+++ b/include/utils/GenerationCache.h
@@ -34,17 +34,17 @@
 
 template<typename EntryKey, typename EntryValue>
 struct Entry: public LightRefBase<Entry<EntryKey, EntryValue> > {
-    Entry() { }
-    Entry(const Entry<EntryKey, EntryValue>& e):
-            key(e.key), value(e.value), parent(e.parent), child(e.child) { }
-    Entry(sp<Entry<EntryKey, EntryValue> > e):
-            key(e->key), value(e->value), parent(e->parent), child(e->child) { }
+    Entry(const Entry<EntryKey, EntryValue>& e) :
+            key(e.key), value(e.value),
+            parent(e.parent), child(e.child) { }
+    Entry(const EntryKey& key, const EntryValue& value) :
+            key(key), value(value) { }
 
     EntryKey key;
     EntryValue value;
 
-    sp<Entry<EntryKey, EntryValue> > parent;
-    sp<Entry<EntryKey, EntryValue> > child;
+    sp<Entry<EntryKey, EntryValue> > parent; // next older entry
+    sp<Entry<EntryKey, EntryValue> > child;  // next younger entry
 }; // struct Entry
 
 /**
@@ -62,23 +62,20 @@
 
     void setOnEntryRemovedListener(OnEntryRemoved<K, V>* listener);
 
+    size_t size() const;
+
     void clear();
 
-    bool contains(K key) const;
-    V get(K key);
-    K getKeyAt(uint32_t index) const;
-    bool put(K key, V value);
-    V remove(K key);
-    V removeOldest();
-    V getValueAt(uint32_t index) const;
+    bool contains(const K& key) const;
+    const K& getKeyAt(size_t index) const;
+    const V& getValueAt(size_t index) const;
 
-    uint32_t size() const;
+    const V& get(const K& key);
+    bool put(const K& key, const V& value);
 
-    void addToCache(sp<Entry<K, V> > entry, K key, V value);
-    void attachToCache(sp<Entry<K, V> > entry);
-    void detachFromCache(sp<Entry<K, V> > entry);
-
-    V removeAt(ssize_t index);
+    void removeAt(ssize_t index);
+    bool remove(const K& key);
+    bool removeOldest();
 
 private:
     KeyedVector<K, sp<Entry<K, V> > > mCache;
@@ -88,6 +85,9 @@
 
     sp<Entry<K, V> > mOldest;
     sp<Entry<K, V> > mYoungest;
+
+    void attachToCache(const sp<Entry<K, V> >& entry);
+    void detachFromCache(const sp<Entry<K, V> >& entry);
 }; // class GenerationCache
 
 template<typename K, typename V>
@@ -130,45 +130,44 @@
 }
 
 template<typename K, typename V>
-bool GenerationCache<K, V>::contains(K key) const {
+bool GenerationCache<K, V>::contains(const K& key) const {
     return mCache.indexOfKey(key) >= 0;
 }
 
 template<typename K, typename V>
-K GenerationCache<K, V>::getKeyAt(uint32_t index) const {
+const K& GenerationCache<K, V>::getKeyAt(size_t index) const {
     return mCache.keyAt(index);
 }
 
 template<typename K, typename V>
-V GenerationCache<K, V>::getValueAt(uint32_t index) const {
+const V& GenerationCache<K, V>::getValueAt(size_t index) const {
     return mCache.valueAt(index)->value;
 }
 
 template<typename K, typename V>
-V GenerationCache<K, V>::get(K key) {
+const V& GenerationCache<K, V>::get(const K& key) {
     ssize_t index = mCache.indexOfKey(key);
     if (index >= 0) {
-        sp<Entry<K, V> > entry = mCache.valueAt(index);
-        if (entry.get()) {
-            detachFromCache(entry);
-            attachToCache(entry);
-            return entry->value;
-        }
+        const sp<Entry<K, V> >& entry = mCache.valueAt(index);
+        detachFromCache(entry);
+        attachToCache(entry);
+        return entry->value;
     }
 
     return NULL;
 }
 
 template<typename K, typename V>
-bool GenerationCache<K, V>::put(K key, V value) {
+bool GenerationCache<K, V>::put(const K& key, const V& value) {
     if (mMaxCapacity != kUnlimitedCapacity && mCache.size() >= mMaxCapacity) {
         removeOldest();
     }
 
     ssize_t index = mCache.indexOfKey(key);
     if (index < 0) {
-        sp<Entry<K, V> > entry = new Entry<K, V>;
-        addToCache(entry, key, value);
+        sp<Entry<K, V> > entry = new Entry<K, V>(key, value);
+        mCache.add(key, entry);
+        attachToCache(entry);
         return true;
     }
 
@@ -176,49 +175,44 @@
 }
 
 template<typename K, typename V>
-void GenerationCache<K, V>::addToCache(sp<Entry<K, V> > entry, K key, V value) {
-    entry->key = key;
-    entry->value = value;
-    mCache.add(key, entry);
-    attachToCache(entry);
-}
-
-template<typename K, typename V>
-V GenerationCache<K, V>::remove(K key) {
+bool GenerationCache<K, V>::remove(const K& key) {
     ssize_t index = mCache.indexOfKey(key);
     if (index >= 0) {
-        return removeAt(index);
+        removeAt(index);
+        return true;
     }
 
-    return NULL;
+    return false;
 }
 
 template<typename K, typename V>
-V GenerationCache<K, V>::removeAt(ssize_t index) {
+void GenerationCache<K, V>::removeAt(ssize_t index) {
     sp<Entry<K, V> > entry = mCache.valueAt(index);
     if (mListener) {
         (*mListener)(entry->key, entry->value);
     }
     mCache.removeItemsAt(index, 1);
     detachFromCache(entry);
-
-    return entry->value;
 }
 
 template<typename K, typename V>
-V GenerationCache<K, V>::removeOldest() {
+bool GenerationCache<K, V>::removeOldest() {
     if (mOldest.get()) {
         ssize_t index = mCache.indexOfKey(mOldest->key);
         if (index >= 0) {
-            return removeAt(index);
+            removeAt(index);
+            return true;
         }
+        LOGE("GenerationCache: removeOldest failed to find the item in the cache "
+                "with the given key, but we know it must be in there.  "
+                "Is the key comparator kaput?");
     }
 
-    return NULL;
+    return false;
 }
 
 template<typename K, typename V>
-void GenerationCache<K, V>::attachToCache(sp<Entry<K, V> > entry) {
+void GenerationCache<K, V>::attachToCache(const sp<Entry<K, V> >& entry) {
     if (!mYoungest.get()) {
         mYoungest = mOldest = entry;
     } else {
@@ -229,20 +223,16 @@
 }
 
 template<typename K, typename V>
-void GenerationCache<K, V>::detachFromCache(sp<Entry<K, V> > entry) {
+void GenerationCache<K, V>::detachFromCache(const sp<Entry<K, V> >& entry) {
     if (entry->parent.get()) {
         entry->parent->child = entry->child;
+    } else {
+        mOldest = entry->child;
     }
 
     if (entry->child.get()) {
         entry->child->parent = entry->parent;
-    }
-
-    if (mOldest == entry) {
-        mOldest = entry->child;
-    }
-
-    if (mYoungest == entry) {
+    } else {
         mYoungest = entry->parent;
     }
 
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk
index 2d716c7..b7e3ee3 100644
--- a/libs/gui/Android.mk
+++ b/libs/gui/Android.mk
@@ -32,6 +32,10 @@
 
 LOCAL_MODULE:= libgui
 
+ifeq ($(TARGET_BOARD_PLATFORM), tegra)
+	LOCAL_CFLAGS += -DALLOW_DEQUEUE_CURRENT_BUFFER
+endif
+
 include $(BUILD_SHARED_LIBRARY)
 
 ifeq (,$(ONE_SHOT_MAKEFILE))
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 6cd6dc5..ba7c35b 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -36,8 +36,12 @@
 #include <utils/Log.h>
 #include <utils/String8.h>
 
-
-#define ALLOW_DEQUEUE_CURRENT_BUFFER    false
+#ifdef ALLOW_DEQUEUE_CURRENT_BUFFER
+#define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER    true
+#warning "ALLOW_DEQUEUE_CURRENT_BUFFER enabled"
+#else
+#define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER    false
+#endif
 
 // Macros for including the SurfaceTexture name in log messages
 #define ST_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
@@ -323,7 +327,7 @@
             LOGW_IF((state == BufferSlot::FREE) && (mCurrentTexture==i),
                     "dequeueBuffer: buffer %d is both FREE and current!", i);
 
-            if (ALLOW_DEQUEUE_CURRENT_BUFFER) {
+            if (FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER) {
                 if (state == BufferSlot::FREE || i == mCurrentTexture) {
                     foundSync = i;
                     if (i != mCurrentTexture) {
diff --git a/opengl/include/EGL/eglext.h b/opengl/include/EGL/eglext.h
index 8e8e26c..c926670 100644
--- a/opengl/include/EGL/eglext.h
+++ b/opengl/include/EGL/eglext.h
@@ -261,14 +261,14 @@
  */
 #ifndef EGL_ANDROID_blob_cache
 #define EGL_ANDROID_blob_cache 1
-typedef khronos_ssize_t EGLsizei;
-typedef void (*EGLSetBlobFunc) (const void* key, EGLsizei keySize, const void* value, EGLsizei valueSize);
-typedef EGLsizei (*EGLGetBlobFunc) (const void* key, EGLsizei keySize, void* value, EGLsizei valueSize);
+typedef khronos_ssize_t EGLsizeiANDROID;
+typedef void (*EGLSetBlobFuncANDROID) (const void* key, EGLsizeiANDROID keySize, const void* value, EGLsizeiANDROID valueSize);
+typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void* key, EGLsizeiANDROID keySize, void* value, EGLsizeiANDROID valueSize);
 #ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncs(EGLDisplay dpy, EGLSetBlobFunc set, EGLGetBlobFunc get);
+EGLAPI void EGLAPIENTRY eglSetBlobCacheFuncsANDROID(EGLDisplay dpy, EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
 #endif /* EGL_EGLEXT_PROTOTYPES */
-typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSPROC) (EGLDisplay dpy,
-        EGLSetBlobFunc set, EGLGetBlobFunc get);
+typedef void (EGLAPIENTRYP PFNEGLSETBLOBCACHEFUNCSANDROIDPROC) (EGLDisplay dpy,
+        EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
 #endif
 
 #ifdef __cplusplus
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 1e43195..6ad06af 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -212,16 +212,20 @@
 
 EGLImageKHR egl_get_image_for_current_context(EGLImageKHR image)
 {
-    ImageRef _i(image);
-    if (!_i.get())
-        return EGL_NO_IMAGE_KHR;
-
     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
+    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
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 60ac34b..095f10c 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -451,7 +451,7 @@
     egl_display_t const * const dp = validate_display(dpy);
     if (!dp) return EGL_FALSE;
 
-    SurfaceRef _s(surface);
+    SurfaceRef _s(dp, surface);
     if (!_s.get())
         return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -472,7 +472,7 @@
     egl_display_t const * const dp = validate_display(dpy);
     if (!dp) return EGL_FALSE;
 
-    SurfaceRef _s(surface);
+    SurfaceRef _s(dp, surface);
     if (!_s.get())
         return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -541,7 +541,7 @@
     if (!dp)
         return EGL_FALSE;
 
-    ContextRef _c(ctx);
+    ContextRef _c(dp, ctx);
     if (!_c.get())
         return setError(EGL_BAD_CONTEXT, EGL_FALSE);
     
@@ -592,9 +592,9 @@
     }
 
     // get a reference to the object passed in
-    ContextRef _c(ctx);
-    SurfaceRef _d(draw);
-    SurfaceRef _r(read);
+    ContextRef _c(dp, ctx);
+    SurfaceRef _d(dp, draw);
+    SurfaceRef _r(dp, read);
 
     // validate the context (if not EGL_NO_CONTEXT)
     if ((ctx != EGL_NO_CONTEXT) && !_c.get()) {
@@ -696,7 +696,7 @@
     egl_display_t const * const dp = validate_display(dpy);
     if (!dp) return EGL_FALSE;
 
-    ContextRef _c(ctx);
+    ContextRef _c(dp, ctx);
     if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
 
     egl_context_t * const c = get_context(ctx);
@@ -860,7 +860,7 @@
 
     // The EGL_ANDROID_blob_cache extension should not be exposed to
     // applications.  It is used internally by the Android EGL layer.
-    if (!strcmp(procname, "eglSetBlobCacheFuncs")) {
+    if (!strcmp(procname, "eglSetBlobCacheFuncsANDROID")) {
         return NULL;
     }
 
@@ -944,7 +944,7 @@
     egl_display_t const * const dp = validate_display(dpy);
     if (!dp) return EGL_FALSE;
 
-    SurfaceRef _s(draw);
+    SurfaceRef _s(dp, draw);
     if (!_s.get())
         return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -960,7 +960,7 @@
     egl_display_t const * const dp = validate_display(dpy);
     if (!dp) return EGL_FALSE;
 
-    SurfaceRef _s(surface);
+    SurfaceRef _s(dp, surface);
     if (!_s.get())
         return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -1002,7 +1002,7 @@
     egl_display_t const * const dp = validate_display(dpy);
     if (!dp) return EGL_FALSE;
 
-    SurfaceRef _s(surface);
+    SurfaceRef _s(dp, surface);
     if (!_s.get())
         return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -1022,7 +1022,7 @@
     egl_display_t const * const dp = validate_display(dpy);
     if (!dp) return EGL_FALSE;
 
-    SurfaceRef _s(surface);
+    SurfaceRef _s(dp, surface);
     if (!_s.get())
         return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -1042,7 +1042,7 @@
     egl_display_t const * const dp = validate_display(dpy);
     if (!dp) return EGL_FALSE;
 
-    SurfaceRef _s(surface);
+    SurfaceRef _s(dp, surface);
     if (!_s.get())
         return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -1201,7 +1201,7 @@
     egl_display_t const * const dp = validate_display(dpy);
     if (!dp) return EGL_FALSE;
 
-    SurfaceRef _s(surface);
+    SurfaceRef _s(dp, surface);
     if (!_s.get())
         return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -1220,7 +1220,7 @@
     egl_display_t const * const dp = validate_display(dpy);
     if (!dp) return EGL_FALSE;
 
-    SurfaceRef _s(surface);
+    SurfaceRef _s(dp, surface);
     if (!_s.get())
         return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
@@ -1241,7 +1241,7 @@
     if (!dp) return EGL_NO_IMAGE_KHR;
 
     if (ctx != EGL_NO_CONTEXT) {
-        ContextRef _c(ctx);
+        ContextRef _c(dp, ctx);
         if (!_c.get())
             return setError(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
         egl_context_t * const c = get_context(ctx);
@@ -1310,7 +1310,7 @@
     egl_display_t const * const dp = validate_display(dpy);
     if (!dp) return EGL_FALSE;
 
-    ImageRef _i(img);
+    ImageRef _i(dp, img);
     if (!_i.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE);
 
     egl_image_t* image = get_image(img);
@@ -1349,7 +1349,7 @@
     if (!dp) return EGL_NO_SYNC_KHR;
 
     EGLContext ctx = eglGetCurrentContext();
-    ContextRef _c(ctx);
+    ContextRef _c(dp, ctx);
     if (!_c.get())
         return setError(EGL_BAD_CONTEXT, EGL_NO_SYNC_KHR);
 
@@ -1372,12 +1372,12 @@
     egl_display_t const * const dp = validate_display(dpy);
     if (!dp) return EGL_FALSE;
 
-    SyncRef _s(sync);
+    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(ctx);
+    ContextRef _c(dp, ctx);
     if (!_c.get())
         return setError(EGL_BAD_CONTEXT, EGL_FALSE);
 
@@ -1399,12 +1399,12 @@
     egl_display_t const * const dp = validate_display(dpy);
     if (!dp) return EGL_FALSE;
 
-    SyncRef _s(sync);
+    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(ctx);
+    ContextRef _c(dp, ctx);
     if (!_c.get())
         return setError(EGL_BAD_CONTEXT, EGL_FALSE);
 
@@ -1424,13 +1424,13 @@
     egl_display_t const * const dp = validate_display(dpy);
     if (!dp) return EGL_FALSE;
 
-    SyncRef _s(sync);
+    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(ctx);
+    ContextRef _c(dp, ctx);
     if (!_c.get())
         return setError(EGL_BAD_CONTEXT, EGL_FALSE);
 
@@ -1455,7 +1455,7 @@
     egl_display_t const * const dp = validate_display(dpy);
     if (!dp) return EGL_FALSE;
 
-    SurfaceRef _s(draw);
+    SurfaceRef _s(dp, draw);
     if (!_s.get())
         return setError(EGL_BAD_SURFACE, EGL_FALSE);
 
diff --git a/opengl/libs/EGL/egl_cache.cpp b/opengl/libs/EGL/egl_cache.cpp
index 522421b..13a4929 100644
--- a/opengl/libs/EGL/egl_cache.cpp
+++ b/opengl/libs/EGL/egl_cache.cpp
@@ -46,13 +46,13 @@
 //
 // Callback functions passed to EGL.
 //
-static void setBlob(const void* key, EGLsizei keySize, const void* value,
-        EGLsizei valueSize) {
+static void setBlob(const void* key, EGLsizeiANDROID keySize,
+        const void* value, EGLsizeiANDROID valueSize) {
     egl_cache_t::get()->setBlob(key, keySize, value, valueSize);
 }
 
-static EGLsizei getBlob(const void* key, EGLsizei keySize, void* value,
-        EGLsizei valueSize) {
+static EGLsizeiANDROID getBlob(const void* key, EGLsizeiANDROID keySize,
+        void* value, EGLsizeiANDROID valueSize) {
     return egl_cache_t::get()->getBlob(key, keySize, value, valueSize);
 }
 
@@ -87,22 +87,23 @@
                     !strcmp(" " BC_EXT_STR, exts + extsLen - (bcExtLen+1));
             bool inMiddle = strstr(" " BC_EXT_STR " ", exts);
             if (equal || atStart || atEnd || inMiddle) {
-                PFNEGLSETBLOBCACHEFUNCSPROC eglSetBlobCacheFuncs;
-                eglSetBlobCacheFuncs =
-                        reinterpret_cast<PFNEGLSETBLOBCACHEFUNCSPROC>(
-                            cnx->egl.eglGetProcAddress("eglSetBlobCacheFuncs"));
-                if (eglSetBlobCacheFuncs == NULL) {
+                PFNEGLSETBLOBCACHEFUNCSANDROIDPROC eglSetBlobCacheFuncsANDROID;
+                eglSetBlobCacheFuncsANDROID =
+                        reinterpret_cast<PFNEGLSETBLOBCACHEFUNCSANDROIDPROC>(
+                            cnx->egl.eglGetProcAddress(
+                                    "eglSetBlobCacheFuncsANDROID"));
+                if (eglSetBlobCacheFuncsANDROID == NULL) {
                     LOGE("EGL_ANDROID_blob_cache advertised by display %d, "
-                            "but unable to get eglSetBlobCacheFuncs", i);
+                            "but unable to get eglSetBlobCacheFuncsANDROID", i);
                     continue;
                 }
 
-                eglSetBlobCacheFuncs(display->disp[i].dpy, android::setBlob,
-                        android::getBlob);
+                eglSetBlobCacheFuncsANDROID(display->disp[i].dpy,
+                        android::setBlob, android::getBlob);
                 EGLint err = cnx->egl.eglGetError();
                 if (err != EGL_SUCCESS) {
-                    LOGE("eglSetBlobCacheFuncs resulted in an error: %#x",
-                            err);
+                    LOGE("eglSetBlobCacheFuncsANDROID resulted in an error: "
+                            "%#x", err);
                 }
             }
         }
@@ -119,8 +120,8 @@
     mInitialized = false;
 }
 
-void egl_cache_t::setBlob(const void* key, EGLsizei keySize, const void* value,
-        EGLsizei valueSize) {
+void egl_cache_t::setBlob(const void* key, EGLsizeiANDROID keySize,
+        const void* value, EGLsizeiANDROID valueSize) {
     Mutex::Autolock lock(mMutex);
 
     if (keySize < 0 || valueSize < 0) {
@@ -158,8 +159,8 @@
     }
 }
 
-EGLsizei egl_cache_t::getBlob(const void* key, EGLsizei keySize, void* value,
-        EGLsizei valueSize) {
+EGLsizeiANDROID egl_cache_t::getBlob(const void* key, EGLsizeiANDROID keySize,
+        void* value, EGLsizeiANDROID valueSize) {
     Mutex::Autolock lock(mMutex);
 
     if (keySize < 0 || valueSize < 0) {
@@ -323,7 +324,8 @@
             return;
         }
 
-        status_t err = mBlobCache->unflatten(buf + headerSize, cacheSize, NULL, 0);
+        status_t err = mBlobCache->unflatten(buf + headerSize, cacheSize, NULL,
+                0);
         if (err != OK) {
             LOGE("error reading cache contents: %s (%d)", strerror(-err),
                     -err);
diff --git a/opengl/libs/EGL/egl_cache.h b/opengl/libs/EGL/egl_cache.h
index 4389623..8760009 100644
--- a/opengl/libs/EGL/egl_cache.h
+++ b/opengl/libs/EGL/egl_cache.h
@@ -52,14 +52,14 @@
     // setBlob attempts to insert a new key/value blob pair into the cache.
     // This will be called by the hardware vendor's EGL implementation via the
     // EGL_ANDROID_blob_cache extension.
-    void setBlob(const void* key, EGLsizei keySize, const void* value,
-        EGLsizei valueSize);
+    void setBlob(const void* key, EGLsizeiANDROID keySize, const void* value,
+        EGLsizeiANDROID valueSize);
 
     // getBlob attempts to retrieve the value blob associated with a given key
     // blob from cache.  This will be called by the hardware vendor's EGL
     // implementation via the EGL_ANDROID_blob_cache extension.
-    EGLsizei getBlob(const void* key, EGLsizei keySize, void* value,
-        EGLsizei valueSize);
+    EGLsizeiANDROID getBlob(const void* key, EGLsizeiANDROID keySize,
+        void* value, EGLsizeiANDROID valueSize);
 
     // setCacheFilename sets the name of the file that should be used to store
     // cache contents from one program invocation to another.
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 558ca77..2935832 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -62,11 +62,13 @@
     objects.remove(object);
 }
 
-bool egl_display_t::getObject(egl_object_t* object) {
+bool egl_display_t::getObject(egl_object_t* object) const {
     Mutex::Autolock _l(lock);
     if (objects.indexOf(object) >= 0) {
-        object->incRef();
-        return true;
+        if (object->getDisplay() == this) {
+            object->incRef();
+            return true;
+        }
     }
     return false;
 }
diff --git a/opengl/libs/EGL/egl_display.h b/opengl/libs/EGL/egl_display.h
index e0a367d..94077be 100644
--- a/opengl/libs/EGL/egl_display.h
+++ b/opengl/libs/EGL/egl_display.h
@@ -81,7 +81,7 @@
     // remove object from this display's list
     void removeObject(egl_object_t* object);
     // add reference to this object. returns true if this is a valid object.
-    bool getObject(egl_object_t* object);
+    bool getObject(egl_object_t* object) const;
 
 
     static egl_display_t* get(EGLDisplay dpy);
@@ -119,9 +119,9 @@
     egl_config_t*   configs;
 
 private:
-    uint32_t        refs;
-    Mutex           lock;
-    SortedVector<egl_object_t*> objects;
+            uint32_t                    refs;
+    mutable Mutex                       lock;
+            SortedVector<egl_object_t*> objects;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/opengl/libs/EGL/egl_object.cpp b/opengl/libs/EGL/egl_object.cpp
index dbf9a01..20cdc7e 100644
--- a/opengl/libs/EGL/egl_object.cpp
+++ b/opengl/libs/EGL/egl_object.cpp
@@ -55,10 +55,10 @@
     }
 }
 
-bool egl_object_t::get() {
+bool egl_object_t::get(egl_display_t const* display, egl_object_t* object) {
     // used by LocalRef, this does an incRef() atomically with
     // checking that the object is valid.
-    return display->getObject(this);
+    return display->getObject(object);
 }
 
 // ----------------------------------------------------------------------------
diff --git a/opengl/libs/EGL/egl_object.h b/opengl/libs/EGL/egl_object.h
index 46f7139..df1b261 100644
--- a/opengl/libs/EGL/egl_object.h
+++ b/opengl/libs/EGL/egl_object.h
@@ -52,10 +52,11 @@
 
     inline int32_t incRef() { return android_atomic_inc(&count); }
     inline int32_t decRef() { return android_atomic_dec(&count); }
+    inline egl_display_t* getDisplay() const { return display; }
 
 private:
     void terminate();
-    bool get();
+    static bool get(egl_display_t const* display, egl_object_t* object);
 
 public:
     template <typename N, typename T>
@@ -66,9 +67,9 @@
     public:
         ~LocalRef();
         explicit LocalRef(egl_object_t* rhs);
-        explicit LocalRef(T o) : ref(0) {
+        explicit LocalRef(egl_display_t const* display, T o) : ref(0) {
             egl_object_t* native = reinterpret_cast<N*>(o);
-            if (o && native->get()) {
+            if (o && egl_object_t::get(display, native)) {
                 ref = native;
             }
         }
diff --git a/opengl/specs/EGL_ANDROID_blob_cache.txt b/opengl/specs/EGL_ANDROID_blob_cache.txt
index 55dc900..61f45d3 100644
--- a/opengl/specs/EGL_ANDROID_blob_cache.txt
+++ b/opengl/specs/EGL_ANDROID_blob_cache.txt
@@ -63,33 +63,33 @@
 New Types
 
     /*
-     * EGLsizei is a signed integer type for representing the size of a memory
-     * buffer.
+     * EGLsizeiANDROID is a signed integer type for representing the size of a
+     * memory buffer.
      */
     #include <khrplatform.h>
-    typedef khronos_ssize_t EGLsizei;
+    typedef khronos_ssize_t EGLsizeiANDROID;
 
     /*
      * EGLSetBlobFunc is a pointer to an application-provided function that a
      * client API implementation may use to insert a key/value pair into the
      * cache.
      */
-    typedef void (*EGLSetBlobFunc) (const void* key, EGLsizei keySize,
-        const void* value, EGLsizei valueSize)
+    typedef void (*EGLSetBlobFuncANDROID) (const void* key,
+        EGLsizeiANDROID keySize, const void* value, EGLsizeiANDROID valueSize)
 
     /*
      * EGLGetBlobFunc is a pointer to an application-provided function that a
      * client API implementation may use to retrieve a cached value from the
      * cache.
      */
-    typedef EGLsizei (*EGLGetBlobFunc) (const void* key, EGLsizei keySize,
-        void* value, EGLsizei valueSize)
+    typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void* key,
+        EGLsizeiANDROID keySize, void* value, EGLsizeiANDROID valueSize)
 
 New Procedures and Functions
 
-    void eglSetBlobCacheFuncs(EGLDisplay dpy,
-                              EGLSetBlobFunc set,
-                              EGLGetBlobFunc get);
+    void eglSetBlobCacheFuncsANDROID(EGLDisplay dpy,
+                                     EGLSetBlobFunc set,
+                                     EGLGetBlobFunc get);
 
 New Tokens
 
@@ -107,8 +107,8 @@
     function pointers through which the client APIs can request data be cached
     and retrieved.  The command
 
-        void eglSetBlobCacheFuncs(EGLDisplay dpy,
-            EGLSetBlobFunc set, EGLGetBlobFunc get);
+        void eglSetBlobCacheFuncsANDROID(EGLDisplay dpy,
+            EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
 
     sets the callback function pointers that client APIs associated with
     display <dpy> can use to interact with caching functionality provided by
@@ -120,17 +120,17 @@
 
     Cache functions may only be specified once during the lifetime of an
     EGLDisplay.  The <set> and <get> functions may be called at any time and
-    from any thread from the time at which eglSetBlobCacheFuncs is called until
-    the time that the last resource associated with <dpy> is deleted and <dpy>
-    itself is terminated.  Concurrent calls to these functions from different
-    threads is also allowed.
+    from any thread from the time at which eglSetBlobCacheFuncsANDROID is
+    called until the time that the last resource associated with <dpy> is
+    deleted and <dpy> itself is terminated.  Concurrent calls to these
+    functions from different threads is also allowed.
 
-    If eglSetBlobCacheFuncs generates an error then all client APIs must behave
-    as though eglSetBlobCacheFuncs was not called for the display <dpy>.  If
-    <set> or <get> is NULL then an EGL_BAD_PARAMETER error is generated.  If a
-    successful eglSetBlobCacheFuncs call was already made for <dpy> and the
-    display has not since been terminated then an EGL_BAD_PARAMETER error is
-    generated.
+    If eglSetBlobCacheFuncsANDROID generates an error then all client APIs must
+    behave as though eglSetBlobCacheFuncsANDROID was not called for the display
+    <dpy>.  If <set> or <get> is NULL then an EGL_BAD_PARAMETER error is
+    generated.  If a successful eglSetBlobCacheFuncsANDROID call was already
+    made for <dpy> and the display has not since been terminated then an
+    EGL_BAD_PARAMETER error is generated.
 
     3.9.1 Cache Operations
 
@@ -138,8 +138,8 @@
     key, a client API implementation can call the application-provided callback
     function
 
-        void (*set) (const void* key, EGLsizei keySize, const void* value,
-            EGLsizei valueSize)
+        void (*set) (const void* key, EGLsizeiANDROID keySize,
+            const void* value, EGLsizeiANDROID valueSize)
 
     <key> and <value> are pointers to the beginning of the key and value,
     respectively, that are to be inserted.  <keySize> and <valueSize> specify
@@ -157,8 +157,8 @@
     client API implementation can call the application-provided callback
     function
 
-        EGLsizei (*get) (const void* key, EGLsizei keySize, void* value,
-            EGLsizei valueSize)
+        EGLsizeiANDROID (*get) (const void* key, EGLsizeiANDROID keySize,
+            void* value, EGLsizeiANDROID valueSize)
 
     <key> is a pointer to the beginning of the key.  <keySize> specifies the
     size in bytes of the binary key pointed to by <key>.  If the cache contains