From af9a515299b24031c7aa77bf163d0985cc862069 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Fri, 10 Apr 2009 20:34:46 -0700 Subject: more debugging tools around BufferMapper --- include/ui/BufferMapper.h | 14 ++++++ libs/surfaceflinger/BufferAllocator.cpp | 16 +++---- libs/surfaceflinger/LayerBitmap.h | 2 +- libs/ui/BufferMapper.cpp | 78 +++++++++++++++++++++++++++++++++ opengl/libagl/egl.cpp | 13 ++++-- 5 files changed, 110 insertions(+), 13 deletions(-) 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 #include + +#include #include #include +#include #include @@ -42,11 +45,22 @@ public: 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(); mutable Mutex mLock; gralloc_module_t const *mAllocMod; + + struct map_info_t { + int count; + KeyedVector callstacks; + }; + KeyedVector 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 @@ status_t BufferAllocator::free(buffer_handle_t handle) { 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 @@ status_t BufferAllocator::unmap(buffer_handle_t handle) { 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& 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 @@ public: private: friend class LightRefBase; 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 +// --------------------------------------------------------------------------- +// 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 @@ status_t BufferMapper::map(buffer_handle_t handle, void** addr) 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 @@ status_t BufferMapper::unmap(buffer_handle_t handle) 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 @@ status_t BufferMapper::unlock(buffer_handle_t handle) 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(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 @@ EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img) buffer_handle_t bufferHandle; gralloc_module_t const* module = reinterpret_cast(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)); } } -- cgit v1.1