GraphicBufferAllocator.cpp revision 4243e666213029a293935987c979831093fb0779
1/* 2** 3** Copyright 2009, The Android Open Source Project 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18#include <sys/mman.h> 19#include <utils/CallStack.h> 20#include <cutils/ashmem.h> 21#include <cutils/log.h> 22 23#include <utils/Singleton.h> 24#include <utils/String8.h> 25 26#include <ui/BufferMapper.h> 27 28#include "BufferAllocator.h" 29 30// FIXME: ANDROID_GRALLOC_DEBUG must only be used with *our* gralloc 31#define ANDROID_GRALLOC_DEBUG 1 32 33 34namespace android { 35// --------------------------------------------------------------------------- 36 37template<class BufferAllocator> Mutex Singleton<BufferAllocator>::sLock; 38template<> BufferAllocator* Singleton<BufferAllocator>::sInstance(0); 39 40Mutex BufferAllocator::sLock; 41KeyedVector<buffer_handle_t, BufferAllocator::alloc_rec_t> BufferAllocator::sAllocList; 42 43BufferAllocator::BufferAllocator() 44 : mAllocDev(0) 45{ 46 hw_module_t const* module; 47 int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); 48 LOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID); 49 if (err == 0) { 50 gralloc_open(module, &mAllocDev); 51 } 52} 53 54BufferAllocator::~BufferAllocator() 55{ 56 gralloc_close(mAllocDev); 57} 58 59void BufferAllocator::dump(String8& result) const 60{ 61 Mutex::Autolock _l(sLock); 62 KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList); 63 size_t total = 0; 64 const size_t SIZE = 512; 65 char buffer[SIZE]; 66 snprintf(buffer, SIZE, "Allocated buffers:\n"); 67 result.append(buffer); 68 const size_t c = list.size(); 69 for (size_t i=0 ; i<c ; i++) { 70 const alloc_rec_t& rec(list.valueAt(i)); 71 snprintf(buffer, SIZE, "%10p: %10p | %7.2f KB | %4u x %4u | %2d | 0x%08x\n", 72 list.keyAt(i), rec.vaddr, rec.size/1024.0f, 73 rec.w, rec.h, rec.format, rec.usage); 74 result.append(buffer); 75 total += rec.size; 76 } 77 snprintf(buffer, SIZE, "Total allocated: %.2f KB\n", total/1024.0f); 78 result.append(buffer); 79} 80 81status_t BufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat format, 82 int usage, buffer_handle_t* handle, int32_t* stride) 83{ 84 Mutex::Autolock _l(mLock); 85 86 // we have a h/w allocator and h/w buffer is requested 87 status_t err = mAllocDev->alloc(mAllocDev, 88 w, h, format, usage, handle, stride); 89 LOGW_IF(err, "alloc(%u, %u, %d, %08x, ...) failed %d (%s)", 90 w, h, format, usage, err, strerror(-err)); 91 92 if (err == NO_ERROR) { 93 Mutex::Autolock _l(sLock); 94 KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList); 95 alloc_rec_t rec; 96 rec.w = w; 97 rec.h = h; 98 rec.format = format; 99 rec.usage = usage; 100 rec.vaddr = 0; 101 rec.size = h * stride[0] * bytesPerPixel(format); 102 list.add(*handle, rec); 103 } 104 105 return err; 106} 107 108status_t BufferAllocator::free(buffer_handle_t handle) 109{ 110 Mutex::Autolock _l(mLock); 111 112#if ANDROID_GRALLOC_DEBUG 113 void* base = (void*)(handle->data[2]); 114#endif 115 116 status_t err = mAllocDev->free(mAllocDev, handle); 117 LOGW_IF(err, "free(...) failed %d (%s)", err, strerror(-err)); 118 119#if ANDROID_GRALLOC_DEBUG 120 if (base) { 121 LOGD("freeing mapped handle %p from:", handle); 122 CallStack s; 123 s.update(); 124 s.dump(""); 125 BufferMapper::get().dump(handle); 126 } 127#endif 128 129 if (err == NO_ERROR) { 130 Mutex::Autolock _l(sLock); 131 KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList); 132 list.removeItem(handle); 133 } 134 135 return err; 136} 137 138status_t BufferAllocator::map(buffer_handle_t handle, void** addr) 139{ 140 Mutex::Autolock _l(mLock); 141 status_t err = BufferMapper::get().map(handle, addr, this); 142 if (err == NO_ERROR) { 143 Mutex::Autolock _l(sLock); 144 KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList); 145 ssize_t idx = list.indexOfKey(handle); 146 if (idx >= 0) 147 list.editValueAt(idx).vaddr = addr; 148 } 149 150 return err; 151} 152 153status_t BufferAllocator::unmap(buffer_handle_t handle) 154{ 155 Mutex::Autolock _l(mLock); 156 gralloc_module_t* mod = (gralloc_module_t*)mAllocDev->common.module; 157 status_t err = BufferMapper::get().unmap(handle, this); 158 if (err == NO_ERROR) { 159 Mutex::Autolock _l(sLock); 160 KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList); 161 ssize_t idx = list.indexOfKey(handle); 162 if (idx >= 0) 163 list.editValueAt(idx).vaddr = 0; 164 } 165 166 return err; 167} 168 169 170// --------------------------------------------------------------------------- 171}; // namespace android 172