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