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