1/* 2// Copyright (c) 2014 Intel Corporation 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// http://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15*/ 16 17#include <HwcTrace.h> 18#include <hardware/hwcomposer.h> 19#include <BufferManager.h> 20#include <hal_public.h> 21#include <DrmConfig.h> 22 23namespace android { 24namespace intel { 25 26BufferManager::BufferManager() 27 : mGralloc(NULL), 28 mFrameBuffers(), 29 mBufferPool(NULL), 30 mDataBuffer(NULL), 31 mDataBufferLock(), 32 mInitialized(false) 33{ 34 CTRACE(); 35} 36 37BufferManager::~BufferManager() 38{ 39 WARN_IF_NOT_DEINIT(); 40} 41 42bool BufferManager::initCheck() const 43{ 44 return mInitialized; 45} 46 47bool BufferManager::initialize() 48{ 49 CTRACE(); 50 51 // create buffer pool 52 mBufferPool = new BufferCache(DEFAULT_BUFFER_POOL_SIZE); 53 if (!mBufferPool) { 54 ETRACE("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 73void 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 107void BufferManager::dump(Dump& d) 108{ 109 d.append("Buffer Manager status: pool size %d\n", mBufferPool->getCacheSize()); 110 d.append("-------------------------------------------------------------\n"); 111 for (uint32_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 124DataBuffer* BufferManager::lockDataBuffer(buffer_handle_t handle) 125{ 126 mDataBufferLock.lock(); 127 mDataBuffer->resetBuffer(handle); 128 return mDataBuffer; 129} 130 131void BufferManager::unlockDataBuffer(DataBuffer *buffer) 132{ 133 mDataBufferLock.unlock(); 134} 135 136DataBuffer* BufferManager::get(buffer_handle_t handle) 137{ 138 return createDataBuffer(handle); 139} 140 141void BufferManager::put(DataBuffer *buffer) 142{ 143 delete buffer; 144} 145 146BufferMapper* 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 VTRACE("new buffer, will add it"); 164 mapper = createBufferMapper(buffer); 165 if (!mapper) { 166 ETRACE("failed to allocate mapper"); 167 break; 168 } 169 ret = mapper->map(); 170 if (!ret) { 171 ETRACE("failed to map"); 172 delete mapper; 173 mapper = NULL; 174 break; 175 } 176 ret = mBufferPool->addMapper(buffer.getKey(), mapper); 177 if (!ret) { 178 ETRACE("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 194void BufferManager::unmap(BufferMapper *mapper) 195{ 196 Mutex::Autolock _l(mLock); 197 if (!mapper) { 198 ETRACE("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 ETRACE("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 214buffer_handle_t BufferManager::allocFrameBuffer(int width, int height, int *stride) 215{ 216 RETURN_NULL_IF_NOT_INIT(); 217 218 if (!mGralloc) { 219 WTRACE("Alloc device is not available"); 220 return 0; 221 } 222 223 if (!width || !height || !stride) { 224 ETRACE("invalid input parameter"); 225 return 0; 226 } 227 228 ITRACE("size of frame buffer to create: %dx%d", width, height); 229 buffer_handle_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 &handle, 237 stride); 238 239 if (err != 0) { 240 ETRACE("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 ETRACE("failed to get data buffer, handle = %p", handle); 251 break; 252 } 253 254 mapper = createBufferMapper(*buffer); 255 if (!mapper) { 256 ETRACE("failed to create buffer mapper"); 257 break; 258 } 259 260 buffer_handle_t fbHandle; 261 if (!(fbHandle = mapper->getFbHandle(0))) { 262 ETRACE("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, handle); 279 return 0; 280} 281 282void BufferManager::freeFrameBuffer(buffer_handle_t fbHandle) 283{ 284 RETURN_VOID_IF_NOT_INIT(); 285 286 if (!mGralloc) { 287 WTRACE("Alloc device is not available"); 288 return; 289 } 290 291 ssize_t index = mFrameBuffers.indexOfKey(fbHandle); 292 if (index < 0) { 293 ETRACE("invalid kernel handle"); 294 return; 295 } 296 297 BufferMapper *mapper = mFrameBuffers.valueAt(index); 298 buffer_handle_t handle = mapper->getHandle(); 299 mapper->putFbHandle(); 300 delete mapper; 301 mFrameBuffers.removeItem(fbHandle); 302 gralloc_device_free_img(mGralloc, handle); 303} 304 305buffer_handle_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 WTRACE("Alloc device is not available"); 311 return 0; 312 } 313 314 if (!width || !height) { 315 ETRACE("invalid input parameter"); 316 return 0; 317 } 318 319 ITRACE("size of graphic buffer to create: %dx%d", width, height); 320 buffer_handle_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 &handle, 329 &stride); 330 if (err != 0) { 331 ETRACE("failed to allocate gralloc buffer, error = %d", err); 332 return 0; 333 } 334 335 return handle; 336} 337 338void BufferManager::freeGrallocBuffer(buffer_handle_t handle) 339{ 340 RETURN_VOID_IF_NOT_INIT(); 341 if (!mGralloc) { 342 WTRACE("Alloc device is not available"); 343 return; 344 } 345 346 if (handle) 347 gralloc_device_free_img(mGralloc, handle); 348} 349 350} // namespace intel 351} // namespace android 352