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 // Skip the unsupported format in case that a new gralloc buffer was 221 // created and added into the mapped list, triggered by SoftwareRender 222 // with color conversion from known formats to YV12. 223 if (!mapper || mapper->getFormat() == HAL_PIXEL_FORMAT_YV12) { 224 ELOGTRACE("failed to map buffer %#x", handle); 225 bm->unlockDataBuffer(buffer); 226 return false; 227 } 228 } else { 229 VLOGTRACE("got mapper in saved data buffers and update source Crop"); 230 mapper = mDataBuffers.valueAt(index); 231 } 232 233 // always update source crop to mapper 234 mapper->setCrop(mSrcCrop.x, mSrcCrop.y, mSrcCrop.w, mSrcCrop.h); 235 236 mapper->setIsCompression(isCompression); 237 238 // unlock buffer after getting mapper 239 bm->unlockDataBuffer(buffer); 240 buffer = NULL; 241 242 ret = setDataBuffer(*mapper); 243 if (ret) { 244 mCurrentDataBuffer = handle; 245 // update active buffers 246 updateActiveBuffers(mapper); 247 } 248 return ret; 249 } 250 251 BufferMapper* DisplayPlane::mapBuffer(DataBuffer *buffer) 252 { 253 BufferManager *bm = Hwcomposer::getInstance().getBufferManager(); 254 255 // invalidate buffer cache if cache is full 256 if ((int)mDataBuffers.size() >= mCacheCapacity) { 257 invalidateBufferCache(); 258 } 259 260 BufferMapper *mapper = bm->map(*buffer); 261 if (!mapper) { 262 ELOGTRACE("failed to map buffer"); 263 return NULL; 264 } 265 266 // add it to data buffers 267 ssize_t index = mDataBuffers.add(buffer->getKey(), mapper); 268 if (index < 0) { 269 ELOGTRACE("failed to add mapper"); 270 bm->unmap(mapper); 271 return NULL; 272 } 273 274 return mapper; 275 } 276 277 bool DisplayPlane::isActiveBuffer(BufferMapper *mapper) 278 { 279 for (size_t i = 0; i < mActiveBuffers.size(); i++) { 280 BufferMapper *activeMapper = mActiveBuffers.itemAt(i); 281 if (!activeMapper) 282 continue; 283 if (activeMapper->getKey() == mapper->getKey()) 284 return true; 285 } 286 287 return false; 288 } 289 290 void DisplayPlane::updateActiveBuffers(BufferMapper *mapper) 291 { 292 BufferManager *bm = Hwcomposer::getInstance().getBufferManager(); 293 294 // unmap the first entry (oldest buffer) 295 if (mActiveBuffers.size() >= MIN_DATA_BUFFER_COUNT) { 296 BufferMapper *oldest = mActiveBuffers.itemAt(0); 297 bm->unmap(oldest); 298 mActiveBuffers.removeAt(0); 299 } 300 301 // queue it to active buffers 302 if (!isActiveBuffer(mapper)) { 303 mapper->incRef(); 304 mActiveBuffers.push_back(mapper); 305 } 306 } 307 308 void DisplayPlane::invalidateActiveBuffers() 309 { 310 BufferManager *bm = Hwcomposer::getInstance().getBufferManager(); 311 BufferMapper* mapper; 312 313 RETURN_VOID_IF_NOT_INIT(); 314 315 VLOGTRACE("invalidating active buffers"); 316 317 for (size_t i = 0; i < mActiveBuffers.size(); i++) { 318 mapper = mActiveBuffers.itemAt(i); 319 // unmap it 320 bm->unmap(mapper); 321 } 322 323 // clear recorded data buffers 324 mActiveBuffers.clear(); 325 } 326 327 void DisplayPlane::invalidateBufferCache() 328 { 329 BufferManager *bm = Hwcomposer::getInstance().getBufferManager(); 330 BufferMapper* mapper; 331 332 RETURN_VOID_IF_NOT_INIT(); 333 334 for (size_t i = 0; i < mDataBuffers.size(); i++) { 335 mapper = mDataBuffers.valueAt(i); 336 bm->unmap(mapper); 337 } 338 339 mDataBuffers.clear(); 340 // reset current buffer 341 mCurrentDataBuffer = 0; 342 } 343 344 bool DisplayPlane::assignToDevice(int disp) 345 { 346 RETURN_FALSE_IF_NOT_INIT(); 347 ALOGTRACE("disp = %d", disp); 348 349 mDevice = disp; 350 351 Drm *drm = Hwcomposer::getInstance().getDrm(); 352 if (!drm->getModeInfo(mDevice, mModeInfo)) { 353 ELOGTRACE("failed to get mode info"); 354 } 355 356 mPanelOrientation = drm->getPanelOrientation(mDevice); 357 358 mForceScaling = DisplayQuery::forceFbScaling(disp); 359 drm->getDisplayResolution(disp, mDisplayWidth, mDisplayHeight); 360 361 if (mForceScaling) { 362 mModeInfo.hdisplay = mDisplayWidth; 363 mModeInfo.vdisplay = mDisplayHeight; 364 365 } 366 367 return true; 368 } 369 370 bool DisplayPlane::flip(void * /* ctx */) 371 { 372 RETURN_FALSE_IF_NOT_INIT(); 373 374 // always flip 375 return true; 376 } 377 378 void DisplayPlane::postFlip() 379 { 380 mUpdateMasks = 0; 381 } 382 383 bool DisplayPlane::reset() 384 { 385 // reclaim all allocated resources 386 if (mDataBuffers.size() > 0) { 387 invalidateBufferCache(); 388 } 389 390 if (mActiveBuffers.size() > 0) { 391 invalidateActiveBuffers(); 392 } 393 394 return true; 395 } 396 397 void DisplayPlane::setZOrder(int zorder) 398 { 399 mZOrder = zorder; 400 } 401 402 int DisplayPlane::getZOrder() const 403 { 404 return mZOrder; 405 } 406 407 } // namespace intel 408 } // namespace android 409