Home | History | Annotate | Download | only in planes
      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 #include <HwcTrace.h>
     17 #include <Hwcomposer.h>
     18 #include <DisplayPlane.h>
     19 #include <GraphicBuffer.h>
     20 
     21 namespace android {
     22 namespace intel {
     23 
     24 DisplayPlane::DisplayPlane(int index, int type, int disp)
     25     : mIndex(index),
     26       mType(type),
     27       mZOrder(-1),
     28       mDevice(disp),
     29       mInitialized(false),
     30       mDataBuffers(),
     31       mActiveBuffers(),
     32       mCacheCapacity(0),
     33       mIsProtectedBuffer(false),
     34       mTransform(0),
     35       mPlaneAlpha(0),
     36       mBlending(HWC_BLENDING_NONE),
     37       mCurrentDataBuffer(0),
     38       mUpdateMasks(0)
     39 {
     40     CTRACE();
     41     memset(&mPosition, 0, sizeof(mPosition));
     42     memset(&mSrcCrop, 0, sizeof(mSrcCrop));
     43 }
     44 
     45 DisplayPlane::~DisplayPlane()
     46 {
     47     WARN_IF_NOT_DEINIT();
     48 }
     49 
     50 bool DisplayPlane::initialize(uint32_t bufferCount)
     51 {
     52     CTRACE();
     53 
     54     if (bufferCount < MIN_DATA_BUFFER_COUNT) {
     55         WTRACE("buffer count %d is too small", bufferCount);
     56         bufferCount = MIN_DATA_BUFFER_COUNT;
     57     }
     58 
     59     // create buffer cache, adding few extra slots as buffer rendering is async
     60     // buffer could still be queued in the display pipeline such that they
     61     // can't be unmapped]
     62     mCacheCapacity = bufferCount;
     63     mDataBuffers.setCapacity(bufferCount);
     64     mActiveBuffers.setCapacity(MIN_DATA_BUFFER_COUNT);
     65     mInitialized = true;
     66     return true;
     67 }
     68 
     69 void DisplayPlane::deinitialize()
     70 {
     71     // invalidate cached data buffers
     72     if (mDataBuffers.size()) {
     73         // invalidateBufferCache will assert if object is not initialized
     74         // so invoking it only there is buffer to invalidate.
     75         invalidateBufferCache();
     76     }
     77 
     78     // invalidate active buffers
     79     if (mActiveBuffers.size()) {
     80         invalidateActiveBuffers();
     81     }
     82 
     83     mCurrentDataBuffer = 0;
     84     mInitialized = false;
     85 }
     86 
     87 void DisplayPlane::checkPosition(int& x, int& y, int& w, int& h)
     88 {
     89     drmModeModeInfoPtr mode = &mModeInfo;
     90 
     91     if (mode->hdisplay == 0 || mode->vdisplay == 0)
     92         return;
     93 
     94     if (x < 0)
     95         x = 0;
     96     if (y < 0)
     97         y = 0;
     98     if ((x + w) > mode->hdisplay)
     99         w = mode->hdisplay - x;
    100     if ((y + h) > mode->vdisplay)
    101         h = mode->vdisplay - y;
    102 }
    103 
    104 void DisplayPlane::setPosition(int x, int y, int w, int h)
    105 {
    106     ATRACE("Position = %d, %d - %dx%d", x, y, w, h);
    107 
    108     if (mPosition.x != x || mPosition.y != y ||
    109         mPosition.w != w || mPosition.h != h) {
    110         mUpdateMasks |= PLANE_POSITION_CHANGED;
    111         mPosition.x = x;
    112         mPosition.y = y;
    113         mPosition.w = w;
    114         mPosition.h = h;
    115     }
    116 }
    117 
    118 void DisplayPlane::setSourceCrop(int x, int y, int w, int h)
    119 {
    120     ATRACE("Source crop = %d, %d - %dx%d", x, y, w, h);
    121 
    122     if (mSrcCrop.x != x || mSrcCrop.y != y ||
    123         mSrcCrop.w != w || mSrcCrop.h != h) {
    124         mUpdateMasks |= PLANE_SOURCE_CROP_CHANGED;
    125         mSrcCrop.x = x;
    126         mSrcCrop.y = y;
    127         if (mType == DisplayPlane::PLANE_OVERLAY) {
    128             mSrcCrop.w = w & (~0x01);
    129             mSrcCrop.h = h & (~0x01);
    130         } else {
    131             mSrcCrop.w = w;
    132             mSrcCrop.h = h;
    133         }
    134     }
    135 }
    136 
    137 void DisplayPlane::setTransform(int trans)
    138 {
    139     ATRACE("transform = %d", trans);
    140 
    141     if (mTransform == trans) {
    142         return;
    143     }
    144 
    145     mTransform = trans;
    146 
    147     mUpdateMasks |= PLANE_TRANSFORM_CHANGED;
    148 }
    149 
    150 void DisplayPlane::setPlaneAlpha(uint8_t alpha, uint32_t blending)
    151 {
    152     ATRACE("plane alpha = 0x%x", alpha);
    153 
    154     if (mPlaneAlpha != alpha) {
    155         mPlaneAlpha = alpha;
    156         mUpdateMasks |= PLANE_BUFFER_CHANGED;
    157     }
    158 
    159     if (mBlending != blending) {
    160         mBlending = blending;
    161         mUpdateMasks |= PLANE_BUFFER_CHANGED;
    162     }
    163 }
    164 
    165 bool DisplayPlane::setDataBuffer(buffer_handle_t handle)
    166 {
    167     DataBuffer *buffer;
    168     BufferMapper *mapper;
    169     ssize_t index;
    170     bool ret;
    171     bool isCompression;
    172     BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
    173 
    174     RETURN_FALSE_IF_NOT_INIT();
    175     ATRACE("handle = %#x", handle);
    176 
    177     if (!handle) {
    178         WTRACE("invalid buffer handle");
    179         return false;
    180     }
    181 
    182     // do not need to update the buffer handle
    183     if (mCurrentDataBuffer != handle)
    184         mUpdateMasks |= PLANE_BUFFER_CHANGED;
    185 
    186     // if no update then do Not need set data buffer
    187     if (!mUpdateMasks)
    188         return true;
    189 
    190     buffer = bm->lockDataBuffer(handle);
    191     if (!buffer) {
    192         ETRACE("failed to get buffer");
    193         return false;
    194     }
    195 
    196     mIsProtectedBuffer = GraphicBuffer::isProtectedBuffer((GraphicBuffer*)buffer);
    197     isCompression = GraphicBuffer::isCompressionBuffer((GraphicBuffer*)buffer);
    198 
    199     // map buffer if it's not in cache
    200     index = mDataBuffers.indexOfKey(buffer->getKey());
    201     if (index < 0) {
    202         VTRACE("unmapped buffer, mapping...");
    203         mapper = mapBuffer(buffer);
    204         if (!mapper) {
    205             ETRACE("failed to map buffer %p", handle);
    206             bm->unlockDataBuffer(buffer);
    207             return false;
    208         }
    209     } else {
    210         VTRACE("got mapper in saved data buffers and update source Crop");
    211         mapper = mDataBuffers.valueAt(index);
    212     }
    213 
    214     // always update source crop to mapper
    215     mapper->setCrop(mSrcCrop.x, mSrcCrop.y, mSrcCrop.w, mSrcCrop.h);
    216 
    217     mapper->setIsCompression(isCompression);
    218 
    219     // unlock buffer after getting mapper
    220     bm->unlockDataBuffer(buffer);
    221     buffer = NULL;
    222 
    223     ret = setDataBuffer(*mapper);
    224     if (ret) {
    225         mCurrentDataBuffer = handle;
    226         // update active buffers
    227         updateActiveBuffers(mapper);
    228     }
    229     return ret;
    230 }
    231 
    232 BufferMapper* DisplayPlane::mapBuffer(DataBuffer *buffer)
    233 {
    234     BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
    235 
    236     // invalidate buffer cache  if cache is full
    237     if ((int)mDataBuffers.size() >= mCacheCapacity) {
    238         invalidateBufferCache();
    239     }
    240 
    241     BufferMapper *mapper = bm->map(*buffer);
    242     if (!mapper) {
    243         ETRACE("failed to map buffer");
    244         return NULL;
    245     }
    246 
    247     // add it to data buffers
    248     ssize_t index = mDataBuffers.add(buffer->getKey(), mapper);
    249     if (index < 0) {
    250         ETRACE("failed to add mapper");
    251         bm->unmap(mapper);
    252         return NULL;
    253     }
    254 
    255     return mapper;
    256 }
    257 
    258 int DisplayPlane::findActiveBuffer(BufferMapper *mapper)
    259 {
    260     for (size_t i = 0; i < mActiveBuffers.size(); i++) {
    261         BufferMapper *activeMapper = mActiveBuffers.itemAt(i);
    262         if (!activeMapper)
    263             continue;
    264         if (activeMapper->getKey() == mapper->getKey())
    265             return i;
    266     }
    267 
    268     return -1;
    269 }
    270 
    271 void DisplayPlane::updateActiveBuffers(BufferMapper *mapper)
    272 {
    273     BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
    274     int index = findActiveBuffer(mapper);
    275     bool exist = (0 <= index && index < (int)mActiveBuffers.size());
    276 
    277     // unmap the first entry (oldest buffer)
    278     if (!exist && mActiveBuffers.size() >= MIN_DATA_BUFFER_COUNT) {
    279         BufferMapper *oldest = mActiveBuffers.itemAt(0);
    280         bm->unmap(oldest);
    281         mActiveBuffers.removeAt(0);
    282     }
    283 
    284     // queue it to active buffers
    285     if (!exist) {
    286         mapper->incRef();
    287     } else {
    288         mActiveBuffers.removeAt(index);
    289     }
    290     mActiveBuffers.push_back(mapper);
    291 }
    292 
    293 void DisplayPlane::invalidateActiveBuffers()
    294 {
    295     BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
    296     BufferMapper* mapper;
    297 
    298     RETURN_VOID_IF_NOT_INIT();
    299 
    300     VTRACE("invalidating active buffers");
    301 
    302     for (size_t i = 0; i < mActiveBuffers.size(); i++) {
    303         mapper = mActiveBuffers.itemAt(i);
    304         // unmap it
    305         bm->unmap(mapper);
    306     }
    307 
    308     // clear recorded data buffers
    309     mActiveBuffers.clear();
    310 }
    311 
    312 void DisplayPlane::invalidateBufferCache()
    313 {
    314     BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
    315     BufferMapper* mapper;
    316 
    317     RETURN_VOID_IF_NOT_INIT();
    318 
    319     for (size_t i = 0; i < mDataBuffers.size(); i++) {
    320         mapper = mDataBuffers.valueAt(i);
    321         bm->unmap(mapper);
    322     }
    323 
    324     mDataBuffers.clear();
    325     // reset current buffer
    326     mCurrentDataBuffer = 0;
    327 }
    328 
    329 bool DisplayPlane::assignToDevice(int disp)
    330 {
    331     RETURN_FALSE_IF_NOT_INIT();
    332     ATRACE("disp = %d", disp);
    333 
    334     mDevice = disp;
    335 
    336     Drm *drm = Hwcomposer::getInstance().getDrm();
    337     if (!drm->getModeInfo(mDevice, mModeInfo)) {
    338         ETRACE("failed to get mode info");
    339     }
    340 
    341     mPanelOrientation = drm->getPanelOrientation(mDevice);
    342 
    343     return true;
    344 }
    345 
    346 bool DisplayPlane::flip(void *ctx)
    347 {
    348     RETURN_FALSE_IF_NOT_INIT();
    349 
    350     // always flip
    351     return true;
    352 }
    353 
    354 void DisplayPlane::postFlip()
    355 {
    356     mUpdateMasks = 0;
    357 }
    358 
    359 bool DisplayPlane::reset()
    360 {
    361     // reclaim all allocated resources
    362     if (mDataBuffers.size() > 0) {
    363         invalidateBufferCache();
    364     }
    365 
    366     if (mActiveBuffers.size() > 0) {
    367         invalidateActiveBuffers();
    368     }
    369 
    370     return true;
    371 }
    372 
    373 void DisplayPlane::setZOrder(int zorder)
    374 {
    375     mZOrder = zorder;
    376 }
    377 
    378 int DisplayPlane::getZOrder() const
    379 {
    380     return mZOrder;
    381 }
    382 
    383 } // namespace intel
    384 } // namespace android
    385