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         if (!mapper) {
    221             ELOGTRACE("failed to map buffer %#x", handle);
    222             bm->unlockDataBuffer(buffer);
    223             return false;
    224         }
    225     } else {
    226         VLOGTRACE("got mapper in saved data buffers and update source Crop");
    227         mapper = mDataBuffers.valueAt(index);
    228     }
    229 
    230     // always update source crop to mapper
    231     mapper->setCrop(mSrcCrop.x, mSrcCrop.y, mSrcCrop.w, mSrcCrop.h);
    232 
    233     mapper->setIsCompression(isCompression);
    234 
    235     // unlock buffer after getting mapper
    236     bm->unlockDataBuffer(buffer);
    237     buffer = NULL;
    238 
    239     ret = setDataBuffer(*mapper);
    240     if (ret) {
    241         mCurrentDataBuffer = handle;
    242         // update active buffers
    243         updateActiveBuffers(mapper);
    244     }
    245     return ret;
    246 }
    247 
    248 BufferMapper* DisplayPlane::mapBuffer(DataBuffer *buffer)
    249 {
    250     BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
    251 
    252     // invalidate buffer cache  if cache is full
    253     if ((int)mDataBuffers.size() >= mCacheCapacity) {
    254         invalidateBufferCache();
    255     }
    256 
    257     BufferMapper *mapper = bm->map(*buffer);
    258     if (!mapper) {
    259         ELOGTRACE("failed to map buffer");
    260         return NULL;
    261     }
    262 
    263     // add it to data buffers
    264     ssize_t index = mDataBuffers.add(buffer->getKey(), mapper);
    265     if (index < 0) {
    266         ELOGTRACE("failed to add mapper");
    267         bm->unmap(mapper);
    268         return NULL;
    269     }
    270 
    271     return mapper;
    272 }
    273 
    274 bool DisplayPlane::isActiveBuffer(BufferMapper *mapper)
    275 {
    276     for (size_t i = 0; i < mActiveBuffers.size(); i++) {
    277         BufferMapper *activeMapper = mActiveBuffers.itemAt(i);
    278         if (!activeMapper)
    279             continue;
    280         if (activeMapper->getKey() == mapper->getKey())
    281             return true;
    282     }
    283 
    284     return false;
    285 }
    286 
    287 void DisplayPlane::updateActiveBuffers(BufferMapper *mapper)
    288 {
    289     BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
    290 
    291     // unmap the first entry (oldest buffer)
    292     if (mActiveBuffers.size() >= MIN_DATA_BUFFER_COUNT) {
    293         BufferMapper *oldest = mActiveBuffers.itemAt(0);
    294         bm->unmap(oldest);
    295         mActiveBuffers.removeAt(0);
    296     }
    297 
    298     // queue it to active buffers
    299     if (!isActiveBuffer(mapper)) {
    300         mapper->incRef();
    301         mActiveBuffers.push_back(mapper);
    302     }
    303 }
    304 
    305 void DisplayPlane::invalidateActiveBuffers()
    306 {
    307     BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
    308     BufferMapper* mapper;
    309 
    310     RETURN_VOID_IF_NOT_INIT();
    311 
    312     VLOGTRACE("invalidating active buffers");
    313 
    314     for (size_t i = 0; i < mActiveBuffers.size(); i++) {
    315         mapper = mActiveBuffers.itemAt(i);
    316         // unmap it
    317         bm->unmap(mapper);
    318     }
    319 
    320     // clear recorded data buffers
    321     mActiveBuffers.clear();
    322 }
    323 
    324 void DisplayPlane::invalidateBufferCache()
    325 {
    326     BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
    327     BufferMapper* mapper;
    328 
    329     RETURN_VOID_IF_NOT_INIT();
    330 
    331     for (size_t i = 0; i < mDataBuffers.size(); i++) {
    332         mapper = mDataBuffers.valueAt(i);
    333         bm->unmap(mapper);
    334     }
    335 
    336     mDataBuffers.clear();
    337     // reset current buffer
    338     mCurrentDataBuffer = 0;
    339 }
    340 
    341 bool DisplayPlane::assignToDevice(int disp)
    342 {
    343     RETURN_FALSE_IF_NOT_INIT();
    344     ALOGTRACE("disp = %d", disp);
    345 
    346     mDevice = disp;
    347 
    348     Drm *drm = Hwcomposer::getInstance().getDrm();
    349     if (!drm->getModeInfo(mDevice, mModeInfo)) {
    350         ELOGTRACE("failed to get mode info");
    351     }
    352 
    353     mPanelOrientation = drm->getPanelOrientation(mDevice);
    354 
    355     mForceScaling = DisplayQuery::forceFbScaling(disp);
    356     drm->getDisplayResolution(disp, mDisplayWidth, mDisplayHeight);
    357 
    358     if (mForceScaling) {
    359         mModeInfo.hdisplay = mDisplayWidth;
    360         mModeInfo.vdisplay = mDisplayHeight;
    361 
    362     }
    363 
    364     return true;
    365 }
    366 
    367 bool DisplayPlane::flip(void * /* ctx */)
    368 {
    369     RETURN_FALSE_IF_NOT_INIT();
    370 
    371     // always flip
    372     return true;
    373 }
    374 
    375 void DisplayPlane::postFlip()
    376 {
    377     mUpdateMasks = 0;
    378 }
    379 
    380 bool DisplayPlane::reset()
    381 {
    382     // reclaim all allocated resources
    383     if (mDataBuffers.size() > 0) {
    384         invalidateBufferCache();
    385     }
    386 
    387     if (mActiveBuffers.size() > 0) {
    388         invalidateActiveBuffers();
    389     }
    390 
    391     return true;
    392 }
    393 
    394 void DisplayPlane::setZOrder(int zorder)
    395 {
    396     mZOrder = zorder;
    397 }
    398 
    399 int DisplayPlane::getZOrder() const
    400 {
    401     return mZOrder;
    402 }
    403 
    404 } // namespace intel
    405 } // namespace android
    406