1 /* 2 // Copyright(c)2014 IntelCorporation 3 // 4 // LicensedundertheApacheLicense,Version2.0(the"License"); 5 // youmaynotusethisfileexceptincompliancewiththeLicense. 6 // YoumayobtainacopyoftheLicenseat 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unlessrequiredbyapplicablelaworagreedtoinwriting,software 11 // distributedundertheLicenseisdistributedonan"ASIS"BASIS, 12 // WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied. 13 // SeetheLicenseforthespecificlanguagegoverningpermissionsand 14 // limitationsundertheLicense. 15 */ 16 17 #include <common/utils/HwcTrace.h> 18 #include <hardware/hwcomposer.h> 19 #include <BufferManager.h> 20 #include <DrmConfig.h> 21 22 namespace android { 23 namespace intel { 24 25 BufferManager::BufferManager() 26 : mGrallocModule(NULL), 27 mAllocDev(NULL), 28 mFrameBuffers(), 29 mBufferPool(NULL), 30 mDataBuffer(NULL), 31 mDataBufferLock(), 32 mInitialized(false) 33 { 34 CTRACE(); 35 } 36 37 BufferManager::~BufferManager() 38 { 39 WARN_IF_NOT_DEINIT(); 40 } 41 42 bool BufferManager::initCheck() const 43 { 44 return mInitialized; 45 } 46 47 bool BufferManager::initialize() 48 { 49 CTRACE(); 50 51 // create buffer pool 52 mBufferPool = new BufferCache(DEFAULT_BUFFER_POOL_SIZE); 53 if (!mBufferPool) { 54 ELOGTRACE("failed to create gralloc buffer cache"); 55 return false; 56 } 57 58 // init gralloc module 59 hw_module_t const* module; 60 if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module)) { 61 DEINIT_AND_RETURN_FALSE("failed to get gralloc module"); 62 } 63 mGrallocModule = (gralloc_module_t const*)module; 64 65 gralloc_open(module, &mAllocDev); 66 if (!mAllocDev) { 67 WLOGTRACE("failed to open alloc device"); 68 } 69 70 // create a dummy data buffer 71 mDataBuffer = createDataBuffer(0); 72 if (!mDataBuffer) { 73 DEINIT_AND_RETURN_FALSE("failed to create data buffer"); 74 } 75 76 mInitialized = true; 77 return true; 78 } 79 80 void BufferManager::deinitialize() 81 { 82 mInitialized = false; 83 84 if (mBufferPool) { 85 // unmap & delete all cached buffer mappers 86 for (size_t i = 0; i < mBufferPool->getCacheSize(); i++) { 87 BufferMapper *mapper = mBufferPool->getMapper(i); 88 mapper->unmap(); 89 delete mapper; 90 } 91 92 delete mBufferPool; 93 mBufferPool = NULL; 94 } 95 96 for (size_t j = 0; j < mFrameBuffers.size(); j++) { 97 BufferMapper *mapper = mFrameBuffers.valueAt(j); 98 mapper->unmap(); 99 delete mapper; 100 } 101 mFrameBuffers.clear(); 102 103 if (mAllocDev) { 104 gralloc_close(mAllocDev); 105 mAllocDev = NULL; 106 } 107 108 if (mDataBuffer) { 109 delete mDataBuffer; 110 mDataBuffer = NULL; 111 } 112 } 113 114 void BufferManager::dump(Dump& d) 115 { 116 d.append("Buffer Manager status: pool size %d\n", mBufferPool->getCacheSize()); 117 d.append("-------------------------------------------------------------\n"); 118 for (size_t i = 0; i < mBufferPool->getCacheSize(); i++) { 119 BufferMapper *mapper = mBufferPool->getMapper(i); 120 d.append("Buffer %d: handle %#x, (%dx%d), format %d, refCount %d\n", 121 i, 122 mapper->getHandle(), 123 mapper->getWidth(), 124 mapper->getHeight(), 125 mapper->getFormat(), 126 mapper->getRef()); 127 } 128 return; 129 } 130 131 DataBuffer* BufferManager::lockDataBuffer(uint32_t handle) 132 { 133 mDataBufferLock.lock(); 134 mDataBuffer->resetBuffer(handle); 135 return mDataBuffer; 136 } 137 138 void BufferManager::unlockDataBuffer(DataBuffer * /* buffer */) 139 { 140 mDataBufferLock.unlock(); 141 } 142 143 DataBuffer* BufferManager::get(uint32_t handle) 144 { 145 return createDataBuffer(handle); 146 } 147 148 void BufferManager::put(DataBuffer *buffer) 149 { 150 delete buffer; 151 } 152 153 BufferMapper* BufferManager::map(DataBuffer& buffer) 154 { 155 bool ret; 156 BufferMapper* mapper; 157 158 CTRACE(); 159 Mutex::Autolock _l(mLock); 160 //try to get mapper from pool 161 mapper = mBufferPool->getMapper(buffer.getKey()); 162 if (mapper) { 163 // increase mapper ref count 164 mapper->incRef(); 165 return mapper; 166 } 167 168 // create a new buffer mapper and add it to pool 169 do { 170 VLOGTRACE("new buffer, will add it"); 171 mapper = createBufferMapper(buffer); 172 if (!mapper) { 173 ELOGTRACE("failed to allocate mapper"); 174 break; 175 } 176 ret = mapper->map(); 177 if (!ret) { 178 ELOGTRACE("failed to map"); 179 delete mapper; 180 mapper = NULL; 181 break; 182 } 183 ret = mBufferPool->addMapper(buffer.getKey(), mapper); 184 if (!ret) { 185 ELOGTRACE("failed to add mapper"); 186 break; 187 } 188 // increase mapper ref count 189 mapper->incRef(); 190 return mapper; 191 } while (0); 192 193 // error handling 194 if (mapper) { 195 mapper->unmap(); 196 delete mapper; 197 } 198 return NULL; 199 } 200 201 void BufferManager::unmap(BufferMapper *mapper) 202 { 203 Mutex::Autolock _l(mLock); 204 if (!mapper) { 205 ELOGTRACE("invalid mapper"); 206 return; 207 } 208 209 // unmap & remove this mapper from buffer when refCount = 0 210 int refCount = mapper->decRef(); 211 if (refCount < 0) { 212 ELOGTRACE("invalid ref count"); 213 } else if (!refCount) { 214 // remove mapper from buffer pool 215 mBufferPool->removeMapper(mapper); 216 mapper->unmap(); 217 delete mapper; 218 } 219 } 220 221 uint32_t BufferManager::allocFrameBuffer(int width, int height, int *stride) 222 { 223 RETURN_NULL_IF_NOT_INIT(); 224 225 if (!mAllocDev) { 226 WLOGTRACE("Alloc device is not available"); 227 return 0; 228 } 229 230 if (!width || !height || !stride) { 231 ELOGTRACE("invalid input parameter"); 232 return 0; 233 } 234 235 ILOGTRACE("size of frame buffer to create: %dx%d", width, height); 236 uint32_t handle = 0; 237 status_t err = mAllocDev->alloc( 238 mAllocDev, 239 width, 240 height, 241 DrmConfig::getFrameBufferFormat(), 242 0, // GRALLOC_USAGE_HW_FB 243 (buffer_handle_t *)&handle, 244 stride); 245 246 if (err != 0) { 247 ELOGTRACE("failed to allocate frame buffer, error = %d", err); 248 return 0; 249 } 250 251 DataBuffer *buffer = NULL; 252 BufferMapper *mapper = NULL; 253 254 do { 255 buffer = lockDataBuffer(handle); 256 if (!buffer) { 257 ELOGTRACE("failed to get data buffer, handle = %#x", handle); 258 break; 259 } 260 261 mapper = createBufferMapper(*buffer); 262 if (!mapper) { 263 ELOGTRACE("failed to create buffer mapper"); 264 break; 265 } 266 267 uint32_t fbHandle; 268 if (!(fbHandle = mapper->getFbHandle(0))) { 269 ELOGTRACE("failed to get Fb handle"); 270 break; 271 } 272 273 mFrameBuffers.add(fbHandle, mapper); 274 unlockDataBuffer(buffer); 275 return fbHandle; 276 } while (0); 277 278 // error handling, release all allocated resources 279 if (buffer) { 280 unlockDataBuffer(buffer); 281 } 282 if (mapper) { 283 delete mapper; 284 } 285 mAllocDev->free(mAllocDev, (buffer_handle_t)handle); 286 return 0; 287 } 288 289 void BufferManager::freeFrameBuffer(uint32_t fbHandle) 290 { 291 RETURN_VOID_IF_NOT_INIT(); 292 293 if (!mAllocDev) { 294 WLOGTRACE("Alloc device is not available"); 295 return; 296 } 297 298 ssize_t index = mFrameBuffers.indexOfKey(fbHandle); 299 if (index < 0) { 300 ELOGTRACE("invalid kernel handle"); 301 return; 302 } 303 304 BufferMapper *mapper = mFrameBuffers.valueAt(index); 305 uint32_t handle = mapper->getHandle(); 306 mapper->putFbHandle(); 307 delete mapper; 308 mFrameBuffers.removeItem(fbHandle); 309 mAllocDev->free(mAllocDev, (buffer_handle_t)handle); 310 } 311 312 uint32_t BufferManager::allocGrallocBuffer(uint32_t width, uint32_t height, uint32_t format, uint32_t usage) 313 { 314 RETURN_NULL_IF_NOT_INIT(); 315 316 if (!mAllocDev) { 317 WLOGTRACE("Alloc device is not available"); 318 return 0; 319 } 320 321 if (!width || !height) { 322 ELOGTRACE("invalid input parameter"); 323 return 0; 324 } 325 326 ILOGTRACE("size of graphic buffer to create: %dx%d", width, height); 327 uint32_t handle = 0; 328 int stride; 329 status_t err = mAllocDev->alloc( 330 mAllocDev, 331 width, 332 height, 333 format, 334 usage, 335 (buffer_handle_t *)&handle, 336 &stride); 337 if (err != 0) { 338 ELOGTRACE("failed to allocate gralloc buffer, error = %d", err); 339 return 0; 340 } 341 342 return handle; 343 } 344 345 void BufferManager::freeGrallocBuffer(uint32_t handle) 346 { 347 RETURN_VOID_IF_NOT_INIT(); 348 if (!mAllocDev) { 349 WLOGTRACE("Alloc device is not available"); 350 return; 351 } 352 353 if (handle) 354 mAllocDev->free(mAllocDev, (buffer_handle_t)handle); 355 } 356 357 } // namespace intel 358 } // namespace android 359