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