Home | History | Annotate | Download | only in buffers
      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*)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(mGrallocModule, 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(mGrallocModule, 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(mGrallocModule, 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(mGrallocModule, *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