diff options
-rw-r--r-- | include/ui/BufferMapper.h | 14 | ||||
-rw-r--r-- | libs/surfaceflinger/BufferAllocator.cpp | 16 | ||||
-rw-r--r-- | libs/surfaceflinger/LayerBitmap.h | 2 | ||||
-rw-r--r-- | libs/ui/BufferMapper.cpp | 78 | ||||
-rw-r--r-- | 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 <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 @@ 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>; 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 @@ 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<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 @@ public: 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 @@ 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<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 @@ EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, 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 @@ EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img) 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)); } } |