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 <IDisplayDevice.h>
     18 #include <DisplayPlaneManager.h>
     19 
     20 namespace android {
     21 namespace intel {
     22 
     23 DisplayPlaneManager::DisplayPlaneManager()
     24     : mTotalPlaneCount(0),
     25       mPrimaryPlaneCount(DEFAULT_PRIMARY_PLANE_COUNT),
     26       mSpritePlaneCount(0),
     27       mOverlayPlaneCount(0),
     28       mInitialized(false)
     29 {
     30     int i;
     31 
     32     for (i = 0; i < DisplayPlane::PLANE_MAX; i++) {
     33         mPlaneCount[i] = 0;
     34         mFreePlanes[i] = 0;
     35         mReclaimedPlanes[i] = 0;
     36     }
     37 }
     38 
     39 DisplayPlaneManager::~DisplayPlaneManager()
     40 {
     41     WARN_IF_NOT_DEINIT();
     42 }
     43 
     44 void DisplayPlaneManager::deinitialize()
     45 {
     46     int i;
     47     size_t j;
     48 
     49     for (i = 0; i < DisplayPlane::PLANE_MAX; i++) {
     50         for (j = 0; j < mPlanes[i].size(); j++) {
     51             // reset plane
     52             DisplayPlane *plane = mPlanes[i].itemAt(j);
     53             plane->reset();
     54 
     55             DEINIT_AND_DELETE_OBJ(plane);
     56         }
     57         mPlanes[i].clear();
     58     }
     59 
     60     mInitialized = false;
     61 }
     62 
     63 bool DisplayPlaneManager::initialize()
     64 {
     65     int i, j;
     66 
     67     if (mInitialized) {
     68         WLOGTRACE("object has been initialized");
     69         return true;
     70     }
     71 
     72 
     73     // calculate total plane number and free plane bitmaps
     74     mPlaneCount[DisplayPlane::PLANE_SPRITE] = mSpritePlaneCount;
     75     mPlaneCount[DisplayPlane::PLANE_OVERLAY] = mOverlayPlaneCount;
     76     mPlaneCount[DisplayPlane::PLANE_PRIMARY] = mPrimaryPlaneCount;
     77     mPlaneCount[DisplayPlane::PLANE_CURSOR] = mCursorPlaneCount;
     78 
     79     mTotalPlaneCount = mSpritePlaneCount+ mOverlayPlaneCount+ mPrimaryPlaneCount + mCursorPlaneCount;
     80     if (mTotalPlaneCount == 0) {
     81         ELOGTRACE("plane count is not initialized");
     82         return false;
     83     }
     84 
     85     for (i = 0; i < DisplayPlane::PLANE_MAX; i++) {
     86         mFreePlanes[i] = ((1 << mPlaneCount[i]) - 1);
     87     }
     88 
     89     // allocate plane pools
     90     for (i = 0; i < DisplayPlane::PLANE_MAX; i++) {
     91         if (mPlaneCount[i]) {
     92             mPlanes[i].setCapacity(mPlaneCount[i]);
     93 
     94             for (j = 0; j < mPlaneCount[i]; j++) {
     95                 DisplayPlane* plane = allocPlane(j, i);
     96                 if (!plane) {
     97                     ELOGTRACE("failed to allocate plane %d, type %d", j, i);
     98                     DEINIT_AND_RETURN_FALSE();
     99                 }
    100                 mPlanes[i].push_back(plane);
    101             }
    102         }
    103     }
    104 
    105     mInitialized = true;
    106     return true;
    107 }
    108 
    109 int DisplayPlaneManager::getPlane(uint32_t& mask)
    110 {
    111     if (!mask)
    112         return -1;
    113 
    114     for (int i = 0; i < 32; i++) {
    115         int bit = (1 << i);
    116         if (bit & mask) {
    117             mask &= ~bit;
    118             return i;
    119         }
    120     }
    121 
    122     return -1;
    123 }
    124 
    125 void DisplayPlaneManager::putPlane(int index, uint32_t& mask)
    126 {
    127     if (index < 0 || index >= 32)
    128         return;
    129 
    130     int bit = (1 << index);
    131 
    132     if (bit & mask) {
    133         WLOGTRACE("bit %d was set", index);
    134         return;
    135     }
    136 
    137     mask |= bit;
    138 }
    139 
    140 int DisplayPlaneManager::getPlane(uint32_t& mask, int index)
    141 {
    142     if (!mask || index < 0 || index > mTotalPlaneCount)
    143         return -1;
    144 
    145     int bit = (1 << index);
    146     if (bit & mask) {
    147         mask &= ~bit;
    148         return index;
    149     }
    150 
    151     return -1;
    152 }
    153 
    154 DisplayPlane* DisplayPlaneManager::getPlane(int type, int index)
    155 {
    156     RETURN_NULL_IF_NOT_INIT();
    157 
    158     if (type < 0 || type >= DisplayPlane::PLANE_MAX) {
    159         ELOGTRACE("Invalid plane type %d", type);
    160         return 0;
    161     }
    162 
    163     int freePlaneIndex = getPlane(mReclaimedPlanes[type], index);
    164     if (freePlaneIndex >= 0)
    165         return mPlanes[type].itemAt(freePlaneIndex);
    166 
    167     freePlaneIndex = getPlane(mFreePlanes[type], index);
    168     if (freePlaneIndex >= 0)
    169         return mPlanes[type].itemAt(freePlaneIndex);
    170 
    171     return 0;
    172 }
    173 
    174 DisplayPlane* DisplayPlaneManager::getAnyPlane(int type)
    175 {
    176     RETURN_NULL_IF_NOT_INIT();
    177 
    178     if (type < 0 || type >= DisplayPlane::PLANE_MAX) {
    179         ELOGTRACE("Invalid plane type %d", type);
    180         return 0;
    181     }
    182 
    183     int freePlaneIndex = getPlane(mReclaimedPlanes[type]);
    184     if (freePlaneIndex >= 0)
    185         return mPlanes[type].itemAt(freePlaneIndex);
    186 
    187     freePlaneIndex = getPlane(mFreePlanes[type]);
    188     if (freePlaneIndex >= 0)
    189         return mPlanes[type].itemAt(freePlaneIndex);
    190 
    191     return 0;
    192 }
    193 
    194 void DisplayPlaneManager::putPlane(int /* dsp */, DisplayPlane& plane)
    195 {
    196     int index;
    197     int type;
    198 
    199     RETURN_VOID_IF_NOT_INIT();
    200 
    201     index = plane.getIndex();
    202     type = plane.getType();
    203 
    204     if (type < 0 || type >= DisplayPlane::PLANE_MAX) {
    205         ELOGTRACE("Invalid plane type %d", type);
    206         return;
    207     }
    208 
    209     putPlane(index, mFreePlanes[type]);
    210 }
    211 
    212 bool DisplayPlaneManager::isFreePlane(int type, int index)
    213 {
    214     if (type < 0 || type >= DisplayPlane::PLANE_MAX) {
    215         ELOGTRACE("Invalid plane type %d", type);
    216         return false;
    217     }
    218 
    219     int freePlanes = mFreePlanes[type] | mReclaimedPlanes[type];
    220     if ((freePlanes & (1 << index)) == 0)
    221         return false;
    222 
    223     return true;
    224 }
    225 
    226 int DisplayPlaneManager::getFreePlanes(int dsp, int type)
    227 {
    228     RETURN_NULL_IF_NOT_INIT();
    229 
    230     if (dsp < 0 || dsp > IDisplayDevice::DEVICE_EXTERNAL) {
    231         ELOGTRACE("Invalid display device %d", dsp);
    232         return 0;
    233     }
    234 
    235     if (type < 0 || type >= DisplayPlane::PLANE_MAX) {
    236         ELOGTRACE("Invalid plane type %d", type);
    237         return 0;
    238     }
    239 
    240 
    241     uint32_t freePlanes = mFreePlanes[type] | mReclaimedPlanes[type];
    242     if (type == DisplayPlane::PLANE_PRIMARY ||
    243         type == DisplayPlane::PLANE_CURSOR) {
    244         return ((freePlanes & (1 << dsp)) == 0) ? 0 : 1;
    245     } else {
    246         int count = 0;
    247         for (int i = 0; i < 32; i++) {
    248             if ((1 << i) & freePlanes) {
    249                 count++;
    250             }
    251         }
    252         return count;
    253     }
    254     return 0;
    255 }
    256 
    257 void DisplayPlaneManager::reclaimPlane(int /* dsp */, DisplayPlane& plane)
    258 {
    259     RETURN_VOID_IF_NOT_INIT();
    260 
    261     int index = plane.getIndex();
    262     int type = plane.getType();
    263 
    264     ALOGTRACE("reclaimPlane = %d, type = %d", index, plane.getType());
    265 
    266     if (type < 0 || type >= DisplayPlane::PLANE_MAX) {
    267         ELOGTRACE("Invalid plane type %d", type);
    268         return;
    269     }
    270 
    271     putPlane(index, mReclaimedPlanes[type]);
    272 
    273     // NOTE: don't invalidate plane's data cache here because the reclaimed
    274     // plane might be re-assigned to the same layer later
    275 }
    276 
    277 void DisplayPlaneManager::disableReclaimedPlanes()
    278 {
    279     int i, j;
    280     bool ret;
    281 
    282     RETURN_VOID_IF_NOT_INIT();
    283 
    284     for (i = 0; i < DisplayPlane::PLANE_MAX; i++) {
    285         // disable reclaimed planes
    286         if (mReclaimedPlanes[i]) {
    287             for (j = 0; j < mPlaneCount[i]; j++) {
    288                 int bit = (1 << j);
    289                 if (mReclaimedPlanes[i] & bit) {
    290                     DisplayPlane* plane = mPlanes[i].itemAt(j);
    291                     // check plane state first
    292                     ret = plane->isDisabled();
    293                     // reset plane
    294                     if (ret)
    295                         ret = plane->reset();
    296                     if (ret) {
    297                         // only merge into free bitmap if it is successfully disabled and reset
    298                         // otherwise, plane will be disabled and reset again.
    299                         mFreePlanes[i] |=bit;
    300                         mReclaimedPlanes[i] &= ~bit;
    301                     }
    302                 }
    303             }
    304         }
    305     }
    306 }
    307 
    308 bool DisplayPlaneManager::isOverlayPlanesDisabled()
    309 {
    310     for (int i = 0; i < DisplayPlane::PLANE_MAX; i++) {
    311         for (int j = 0; j < mPlaneCount[i]; j++) {
    312             DisplayPlane* plane = (DisplayPlane *)mPlanes[i][j];
    313             if (plane && plane->getType() == DisplayPlane::PLANE_OVERLAY) {
    314                 if (!plane->isDisabled())
    315                     return false;
    316             }
    317         }
    318     }
    319 
    320     return true;
    321 }
    322 
    323 void DisplayPlaneManager::dump(Dump& d)
    324 {
    325     d.append("Display Plane Manager state:\n");
    326     d.append("-------------------------------------------------------------\n");
    327     d.append(" PLANE TYPE | COUNT |   FREE   | RECLAIMED \n");
    328     d.append("------------+-------+----------+-----------\n");
    329     d.append("    SPRITE  |  %2d   | %08x | %08x\n",
    330              mPlaneCount[DisplayPlane::PLANE_SPRITE],
    331              mFreePlanes[DisplayPlane::PLANE_SPRITE],
    332              mReclaimedPlanes[DisplayPlane::PLANE_SPRITE]);
    333     d.append("   OVERLAY  |  %2d   | %08x | %08x\n",
    334              mPlaneCount[DisplayPlane::PLANE_OVERLAY],
    335              mFreePlanes[DisplayPlane::PLANE_OVERLAY],
    336              mReclaimedPlanes[DisplayPlane::PLANE_OVERLAY]);
    337     d.append("   PRIMARY  |  %2d   | %08x | %08x\n",
    338              mPlaneCount[DisplayPlane::PLANE_PRIMARY],
    339              mFreePlanes[DisplayPlane::PLANE_PRIMARY],
    340              mReclaimedPlanes[DisplayPlane::PLANE_PRIMARY]);
    341     d.append("   CURSOR   |  %2d   | %08x | %08x\n",
    342              mPlaneCount[DisplayPlane::PLANE_CURSOR],
    343              mFreePlanes[DisplayPlane::PLANE_CURSOR],
    344              mReclaimedPlanes[DisplayPlane::PLANE_CURSOR]);
    345 }
    346 
    347 } // namespace intel
    348 } // namespace android
    349 
    350 
    351