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