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 <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