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