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