more debugging tools around BufferMapper
diff --git a/include/ui/BufferMapper.h b/include/ui/BufferMapper.h
index 8a33b2e..9e5c5d7 100644
--- a/include/ui/BufferMapper.h
+++ b/include/ui/BufferMapper.h
@@ -19,8 +19,11 @@
 
 #include <stdint.h>
 #include <sys/types.h>
+
+#include <utils/CallStack.h>
 #include <utils/threads.h>
 #include <utils/Singleton.h>
+#include <utils/KeyedVector.h>
 
 #include <hardware/gralloc.h>
 
@@ -42,11 +45,22 @@
     status_t lock(buffer_handle_t handle, int usage, const Rect& bounds);
     status_t unlock(buffer_handle_t handle);
     
+    // dumps information about the mapping of this handle
+    void dump(buffer_handle_t handle);
+
 private:
     friend class Singleton<BufferMapper>;
     BufferMapper();
     mutable Mutex mLock;
     gralloc_module_t const *mAllocMod;
+    
+    struct map_info_t {
+        int count;
+        KeyedVector<CallStack, int> callstacks;
+    };
+    KeyedVector<buffer_handle_t, map_info_t> mMapInfo;
+    void logMapLocked(buffer_handle_t handle);
+    void logUnmapLocked(buffer_handle_t handle);
 };
 
 // ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/BufferAllocator.cpp b/libs/surfaceflinger/BufferAllocator.cpp
index ac32985..96a2c32 100644
--- a/libs/surfaceflinger/BufferAllocator.cpp
+++ b/libs/surfaceflinger/BufferAllocator.cpp
@@ -104,11 +104,13 @@
 {
     Mutex::Autolock _l(mLock);
 
-#if ANDROID_GRALLOC_DEBUG    
-    if (handle->data[2]) {
-            CallStack s;
-            s.update();
-            s.dump("");
+#if ANDROID_GRALLOC_DEBUG
+    void* base = (void*)(handle->data[2]);
+    if (base) {
+        CallStack s;
+        s.update();
+        s.dump("");
+        BufferMapper::get().dump(handle);
     }
 #endif
 
@@ -143,9 +145,7 @@
 {
     Mutex::Autolock _l(mLock);
     gralloc_module_t* mod = (gralloc_module_t*)mAllocDev->common.module;
-    status_t err = mod->unmap(mod, handle);
-    LOGW_IF(err, "unmap(...) failed %d (%s)", err, strerror(-err));
-    
+    status_t err = BufferMapper::get().unmap(handle);
     if (err == NO_ERROR) {
         Mutex::Autolock _l(sLock);
         KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
diff --git a/libs/surfaceflinger/LayerBitmap.h b/libs/surfaceflinger/LayerBitmap.h
index d1f7802..e673755 100644
--- a/libs/surfaceflinger/LayerBitmap.h
+++ b/libs/surfaceflinger/LayerBitmap.h
@@ -81,7 +81,7 @@
 private:
     friend class LightRefBase<Buffer>;
     Buffer(const Buffer& rhs);
-    ~Buffer();
+    virtual ~Buffer();
     Buffer& operator = (const Buffer& rhs);
     const Buffer& operator = (const Buffer& rhs) const;
 
diff --git a/libs/ui/BufferMapper.cpp b/libs/ui/BufferMapper.cpp
index a97188e..c7e439c 100644
--- a/libs/ui/BufferMapper.cpp
+++ b/libs/ui/BufferMapper.cpp
@@ -34,6 +34,13 @@
 
 #include <hardware/gralloc.h>
 
+// ---------------------------------------------------------------------------
+// enable mapping debugging
+#define DEBUG_MAPPINGS           1
+// never remove mappings from the list
+#define DEBUG_MAPPINGS_KEEP_ALL  1
+// ---------------------------------------------------------------------------
+
 namespace android {
 // ---------------------------------------------------------------------------
 
@@ -53,6 +60,10 @@
     Mutex::Autolock _l(mLock);
     status_t err = mAllocMod->map(mAllocMod, handle, addr);
     LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err));
+#if DEBUG_MAPPINGS
+    if (err == NO_ERROR)
+        logMapLocked(handle);
+#endif
     return err;
 }
 
@@ -61,6 +72,10 @@
     Mutex::Autolock _l(mLock);
     status_t err = mAllocMod->unmap(mAllocMod, handle);
     LOGW_IF(err, "unmap(...) failed %d (%s)", err, strerror(-err));
+#if DEBUG_MAPPINGS
+    if (err == NO_ERROR)
+        logUnmapLocked(handle);
+#endif
     return err;
 }
 
@@ -79,5 +94,68 @@
     return err;
 }
 
+void BufferMapper::logMapLocked(buffer_handle_t handle)
+{
+    CallStack stack;
+    stack.update(2);
+    
+    map_info_t info;
+    ssize_t index = mMapInfo.indexOfKey(handle);
+    if (index >= 0) {
+        info = mMapInfo.valueAt(index);
+    }
+    
+    ssize_t stackIndex = info.callstacks.indexOfKey(stack);
+    if (stackIndex >= 0) {
+        info.callstacks.editValueAt(stackIndex) += 1;
+    } else {
+        info.callstacks.add(stack, 1);
+    }
+    
+    if (index < 0) {
+        info.count = 1;
+        mMapInfo.add(handle, info);
+    } else {
+        info.count++;
+        mMapInfo.replaceValueAt(index, info);
+    }
+}
+
+void BufferMapper::logUnmapLocked(buffer_handle_t handle)
+{    
+    ssize_t index = mMapInfo.indexOfKey(handle);
+    if (index < 0) {
+        LOGE("unmapping %p which doesn't exist!", handle);
+        return;
+    }
+    
+    map_info_t& info = mMapInfo.editValueAt(index);
+    info.count--;
+    if (info.count == 0) {
+#if DEBUG_MAPPINGS_KEEP_ALL
+        info.callstacks.clear();
+#else
+        mMapInfo.removeItemsAt(index, 1);
+#endif
+    }
+}
+
+void BufferMapper::dump(buffer_handle_t handle)
+{
+    Mutex::Autolock _l(mLock);
+    ssize_t index = mMapInfo.indexOfKey(handle);
+    if (index < 0) {
+        LOGD("handle %p is not mapped through BufferMapper", handle);
+        return;
+    }
+    
+    const map_info_t& info = mMapInfo.valueAt(index);
+    LOGD("dumping buffer_handle_t %p mappings (count=%d)", handle, info.count);
+    for (size_t i=0 ; i<info.callstacks.size() ; i++) {
+        LOGD("#%d, count=%d", i, info.callstacks.valueAt(i));
+        info.callstacks.keyAt(i).dump();
+    }
+}
+
 // ---------------------------------------------------------------------------
 }; // namespace android
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index 5c91c92..9384e18 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -1699,9 +1699,12 @@
         reinterpret_cast<gralloc_module_t const*>(pModule);
     if (native_buffer->getHandle(native_buffer, &bufferHandle) < 0)
         return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
-    if (module->map(module, bufferHandle, &native_buffer->bits) < 0)
+    int err = module->map(module, bufferHandle, &native_buffer->bits);
+    if (err < 0) {
+        LOGW_IF(err, "map(...) failed %d (%s)", err, strerror(-err));
         return setError(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
-
+    }
+    
     native_buffer->common.incRef(&native_buffer->common);
     return (EGLImageKHR)native_buffer;
 }
@@ -1725,8 +1728,10 @@
         buffer_handle_t bufferHandle;
         gralloc_module_t const* module =
             reinterpret_cast<gralloc_module_t const*>(pModule);
-        if (native_buffer->getHandle(native_buffer, &bufferHandle) == 0) {
-            module->unmap(module, bufferHandle);
+        int err = native_buffer->getHandle(native_buffer, &bufferHandle);
+        if (err == 0) {
+            int err = module->unmap(module, bufferHandle);
+            LOGW_IF(err, "unmap(...) failed %d (%s)", err, strerror(-err));
         }
     }