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         mPosition.x = (int) (((float)x/DEFAULT_DRM_FB_WIDTH)*mDisplayWidth);
    117         mPosition.y = (int) (((float)y/DEFAULT_DRM_FB_HEIGHT)*mDisplayHeight);
    118         mPosition.w = (int) (((float)w/DEFAULT_DRM_FB_WIDTH)*mDisplayWidth);
    119         mPosition.h = (int) (((float)h/DEFAULT_DRM_FB_HEIGHT)*mDisplayHeight);
    120 
    121         mDisplayCrop.x = 0;
    122         mDisplayCrop.y = 0;
    123         mDisplayCrop.w = mDisplayWidth;
    124         mDisplayCrop.h = mDisplayHeight;
    125 
    126         return;
    127     }
    128 
    129     if (mPosition.x != x || mPosition.y != y ||
    130         mPosition.w != w || mPosition.h != h) {
    131         mUpdateMasks |= PLANE_POSITION_CHANGED;
    132         mPosition.x = x;
    133         mPosition.y = y;
    134         mPosition.w = w;
    135         mPosition.h = h;
    136     }
    137 }
    138 
    139 void DisplayPlane::setSourceCrop(int x, int y, int w, int h)
    140 {
    141     ALOGTRACE("Source crop = %d, %d - %dx%d", x, y, w, h);
    142 
    143     if (mSrcCrop.x != x || mSrcCrop.y != y ||
    144         mSrcCrop.w != w || mSrcCrop.h != h) {
    145         mUpdateMasks |= PLANE_SOURCE_CROP_CHANGED;
    146         mSrcCrop.x = x;
    147         mSrcCrop.y = y;
    148         mSrcCrop.w = w;
    149         mSrcCrop.h = h;
    150     }
    151 }
    152 
    153 void DisplayPlane::setTransform(int trans)
    154 {
    155     ALOGTRACE("transform = %d", trans);
    156 
    157     if (mTransform == trans) {
    158         return;
    159     }
    160 
    161     mTransform = trans;
    162 
    163     mUpdateMasks |= PLANE_TRANSFORM_CHANGED;
    164 }
    165 
    166 void DisplayPlane::setPlaneAlpha(uint8_t alpha, uint32_t blending)
    167 {
    168     ALOGTRACE("plane alpha = 0x%x", alpha);
    169 
    170     if (mPlaneAlpha != alpha) {
    171         mPlaneAlpha = alpha;
    172         mUpdateMasks |= PLANE_BUFFER_CHANGED;
    173     }
    174 
    175     if (mBlending != blending) {
    176         mBlending = blending;
    177         mUpdateMasks |= PLANE_BUFFER_CHANGED;
    178     }
    179 }
    180 
    181 bool DisplayPlane::setDataBuffer(uint32_t handle)
    182 {
    183     DataBuffer *buffer;
    184     BufferMapper *mapper;
    185     ssize_t index;
    186     bool ret;
    187     bool isCompression;
    188     BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
    189 
    190     RETURN_FALSE_IF_NOT_INIT();
    191     ALOGTRACE("handle = %#x", handle);
    192 
    193     if (!handle) {
    194         WLOGTRACE("invalid buffer handle");
    195         return false;
    196     }
    197 
    198     // do not need to update the buffer handle
    199     if (mCurrentDataBuffer != handle)
    200         mUpdateMasks |= PLANE_BUFFER_CHANGED;
    201 
    202     // if no update then do Not need set data buffer
    203     if (!mUpdateMasks)
    204         return true;
    205 
    206     buffer = bm->lockDataBuffer(handle);
    207     if (!buffer) {
    208         ELOGTRACE("failed to get buffer");
    209         return false;
    210     }
    211 
    212     mIsProtectedBuffer = GraphicBuffer::isProtectedBuffer((GraphicBuffer*)buffer);
    213     isCompression = GraphicBuffer::isCompressionBuffer((GraphicBuffer*)buffer);
    214 
    215     // map buffer if it's not in cache
    216     index = mDataBuffers.indexOfKey(buffer->getKey());
    217     if (index < 0) {
    218         VLOGTRACE("unmapped buffer, mapping...");
    219         mapper = mapBuffer(buffer);
    220         // Skip the unsupported format in case that a new gralloc buffer was
    221         // created and added into the mapped list, triggered by SoftwareRender
    222         // with color conversion from known formats to YV12.
    223         if (!mapper || mapper->getFormat() == HAL_PIXEL_FORMAT_YV12) {
    224             ELOGTRACE("failed to map buffer %#x", handle);
    225             bm->unlockDataBuffer(buffer);
    226             return false;
    227         }
    228     } else {
    229         VLOGTRACE("got mapper in saved data buffers and update source Crop");
    230         mapper = mDataBuffers.valueAt(index);
    231     }
    232 
    233     // always update source crop to mapper
    234     mapper->setCrop(mSrcCrop.x, mSrcCrop.y, mSrcCrop.w, mSrcCrop.h);
    235 
    236     mapper->setIsCompression(isCompression);
    237 
    238     // unlock buffer after getting mapper
    239     bm->unlockDataBuffer(buffer);
    240     buffer = NULL;
    241 
    242     ret = setDataBuffer(*mapper);
    243     if (ret) {
    244         mCurrentDataBuffer = handle;
    245         // update active buffers
    246         updateActiveBuffers(mapper);
    247     }
    248     return ret;
    249 }
    250 
    251 BufferMapper* DisplayPlane::mapBuffer(DataBuffer *buffer)
    252 {
    253     BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
    254 
    255     // invalidate buffer cache  if cache is full
    256     if ((int)mDataBuffers.size() >= mCacheCapacity) {
    257         invalidateBufferCache();
    258     }
    259 
    260     BufferMapper *mapper = bm->map(*buffer);
    261     if (!mapper) {
    262         ELOGTRACE("failed to map buffer");
    263         return NULL;
    264     }
    265 
    266     // add it to data buffers
    267     ssize_t index = mDataBuffers.add(buffer->getKey(), mapper);
    268     if (index < 0) {
    269         ELOGTRACE("failed to add mapper");
    270         bm->unmap(mapper);
    271         return NULL;
    272     }
    273 
    274     return mapper;
    275 }
    276 
    277 bool DisplayPlane::isActiveBuffer(BufferMapper *mapper)
    278 {
    279     for (size_t i = 0; i < mActiveBuffers.size(); i++) {
    280         BufferMapper *activeMapper = mActiveBuffers.itemAt(i);
    281         if (!activeMapper)
    282             continue;
    283         if (activeMapper->getKey() == mapper->getKey())
    284             return true;
    285     }
    286 
    287     return false;
    288 }
    289 
    290 void DisplayPlane::updateActiveBuffers(BufferMapper *mapper)
    291 {
    292     BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
    293 
    294     // unmap the first entry (oldest buffer)
    295     if (mActiveBuffers.size() >= MIN_DATA_BUFFER_COUNT) {
    296         BufferMapper *oldest = mActiveBuffers.itemAt(0);
    297         bm->unmap(oldest);
    298         mActiveBuffers.removeAt(0);
    299     }
    300 
    301     // queue it to active buffers
    302     if (!isActiveBuffer(mapper)) {
    303         mapper->incRef();
    304         mActiveBuffers.push_back(mapper);
    305     }
    306 }
    307 
    308 void DisplayPlane::invalidateActiveBuffers()
    309 {
    310     BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
    311     BufferMapper* mapper;
    312 
    313     RETURN_VOID_IF_NOT_INIT();
    314 
    315     VLOGTRACE("invalidating active buffers");
    316 
    317     for (size_t i = 0; i < mActiveBuffers.size(); i++) {
    318         mapper = mActiveBuffers.itemAt(i);
    319         // unmap it
    320         bm->unmap(mapper);
    321     }
    322 
    323     // clear recorded data buffers
    324     mActiveBuffers.clear();
    325 }
    326 
    327 void DisplayPlane::invalidateBufferCache()
    328 {
    329     BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
    330     BufferMapper* mapper;
    331 
    332     RETURN_VOID_IF_NOT_INIT();
    333 
    334     for (size_t i = 0; i < mDataBuffers.size(); i++) {
    335         mapper = mDataBuffers.valueAt(i);
    336         bm->unmap(mapper);
    337     }
    338 
    339     mDataBuffers.clear();
    340     // reset current buffer
    341     mCurrentDataBuffer = 0;
    342 }
    343 
    344 bool DisplayPlane::assignToDevice(int disp)
    345 {
    346     RETURN_FALSE_IF_NOT_INIT();
    347     ALOGTRACE("disp = %d", disp);
    348 
    349     mDevice = disp;
    350 
    351     Drm *drm = Hwcomposer::getInstance().getDrm();
    352     if (!drm->getModeInfo(mDevice, mModeInfo)) {
    353         ELOGTRACE("failed to get mode info");
    354     }
    355 
    356     mPanelOrientation = drm->getPanelOrientation(mDevice);
    357 
    358     mForceScaling = DisplayQuery::forceFbScaling(disp);
    359     drm->getDisplayResolution(disp, mDisplayWidth, mDisplayHeight);
    360 
    361     if (mForceScaling) {
    362         mModeInfo.hdisplay = mDisplayWidth;
    363         mModeInfo.vdisplay = mDisplayHeight;
    364 
    365     }
    366 
    367     return true;
    368 }
    369 
    370 bool DisplayPlane::flip(void * /* ctx */)
    371 {
    372     RETURN_FALSE_IF_NOT_INIT();
    373 
    374     // always flip
    375     return true;
    376 }
    377 
    378 void DisplayPlane::postFlip()
    379 {
    380     mUpdateMasks = 0;
    381 }
    382 
    383 bool DisplayPlane::reset()
    384 {
    385     // reclaim all allocated resources
    386     if (mDataBuffers.size() > 0) {
    387         invalidateBufferCache();
    388     }
    389 
    390     if (mActiveBuffers.size() > 0) {
    391         invalidateActiveBuffers();
    392     }
    393 
    394     return true;
    395 }
    396 
    397 void DisplayPlane::setZOrder(int zorder)
    398 {
    399     mZOrder = zorder;
    400 }
    401 
    402 int DisplayPlane::getZOrder() const
    403 {
    404     return mZOrder;
    405 }
    406 
    407 } // namespace intel
    408 } // namespace android
    409