1/* 2 * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved. 3 * Not a Contribution, Apache license notifications and license are retained 4 * for attribution purposes only. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19#include <math.h> 20#include "hwc_mdpcomp.h" 21#include <sys/ioctl.h> 22#include "external.h" 23#include "virtual.h" 24#include "qdMetaData.h" 25#include "mdp_version.h" 26#include "hwc_fbupdate.h" 27#include "hwc_ad.h" 28#include <overlayRotator.h> 29#include "hwc_copybit.h" 30 31using namespace overlay; 32using namespace qdutils; 33using namespace overlay::utils; 34namespace ovutils = overlay::utils; 35 36namespace qhwc { 37 38//==============MDPComp======================================================== 39 40IdleInvalidator *MDPComp::idleInvalidator = NULL; 41bool MDPComp::sIdleFallBack = false; 42bool MDPComp::sHandleTimeout = false; 43bool MDPComp::sDebugLogs = false; 44bool MDPComp::sEnabled = false; 45bool MDPComp::sEnableMixedMode = true; 46int MDPComp::sSimulationFlags = 0; 47int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER; 48bool MDPComp::sEnable4k2kYUVSplit = false; 49bool MDPComp::sSrcSplitEnabled = false; 50MDPComp* MDPComp::getObject(hwc_context_t *ctx, const int& dpy) { 51 if(qdutils::MDPVersion::getInstance().isSrcSplit()) { 52 sSrcSplitEnabled = true; 53 return new MDPCompSrcSplit(dpy); 54 } else if(isDisplaySplit(ctx, dpy)) { 55 return new MDPCompSplit(dpy); 56 } 57 return new MDPCompNonSplit(dpy); 58} 59 60MDPComp::MDPComp(int dpy):mDpy(dpy){}; 61 62void MDPComp::dump(android::String8& buf, hwc_context_t *ctx) 63{ 64 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS) 65 return; 66 67 dumpsys_log(buf,"HWC Map for Dpy: %s \n", 68 (mDpy == 0) ? "\"PRIMARY\"" : 69 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\""); 70 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d " 71 "fbCount:%2d \n", mCurrentFrame.layerCount, 72 mCurrentFrame.mdpCount, mCurrentFrame.fbCount); 73 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n", 74 (mCurrentFrame.needsRedraw? "YES" : "NO"), 75 mCurrentFrame.mdpCount, sMaxPipesPerMixer); 76 if(isDisplaySplit(ctx, mDpy)) { 77 dumpsys_log(buf, "Programmed ROI's: Left: [%d, %d, %d, %d] " 78 "Right: [%d, %d, %d, %d] \n", 79 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top, 80 ctx->listStats[mDpy].lRoi.right, 81 ctx->listStats[mDpy].lRoi.bottom, 82 ctx->listStats[mDpy].rRoi.left,ctx->listStats[mDpy].rRoi.top, 83 ctx->listStats[mDpy].rRoi.right, 84 ctx->listStats[mDpy].rRoi.bottom); 85 } else { 86 dumpsys_log(buf, "Programmed ROI: [%d, %d, %d, %d] \n", 87 ctx->listStats[mDpy].lRoi.left,ctx->listStats[mDpy].lRoi.top, 88 ctx->listStats[mDpy].lRoi.right, 89 ctx->listStats[mDpy].lRoi.bottom); 90 } 91 dumpsys_log(buf," --------------------------------------------- \n"); 92 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n"); 93 dumpsys_log(buf," --------------------------------------------- \n"); 94 for(int index = 0; index < mCurrentFrame.layerCount; index++ ) 95 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n", 96 index, 97 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"), 98 mCurrentFrame.layerToMDP[index], 99 (mCurrentFrame.isFBComposed[index] ? 100 (mCurrentFrame.drop[index] ? "DROP" : 101 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE")) : "MDP"), 102 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ : 103 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder)); 104 dumpsys_log(buf,"\n"); 105} 106 107bool MDPComp::init(hwc_context_t *ctx) { 108 109 if(!ctx) { 110 ALOGE("%s: Invalid hwc context!!",__FUNCTION__); 111 return false; 112 } 113 114 char property[PROPERTY_VALUE_MAX]; 115 116 sEnabled = false; 117 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) && 118 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) || 119 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) { 120 sEnabled = true; 121 } 122 123 sEnableMixedMode = true; 124 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) && 125 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) || 126 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) { 127 sEnableMixedMode = false; 128 } 129 130 sMaxPipesPerMixer = MAX_PIPES_PER_MIXER; 131 if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) { 132 int val = atoi(property); 133 if(val >= 0) 134 sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER); 135 } 136 137 if(ctx->mMDP.panel != MIPI_CMD_PANEL) { 138 // Idle invalidation is not necessary on command mode panels 139 long idle_timeout = DEFAULT_IDLE_TIME; 140 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) { 141 if(atoi(property) != 0) 142 idle_timeout = atoi(property); 143 } 144 145 //create Idle Invalidator only when not disabled through property 146 if(idle_timeout != -1) 147 idleInvalidator = IdleInvalidator::getInstance(); 148 149 if(idleInvalidator == NULL) { 150 ALOGE("%s: failed to instantiate idleInvalidator object", 151 __FUNCTION__); 152 } else { 153 idleInvalidator->init(timeout_handler, ctx, 154 (unsigned int)idle_timeout); 155 } 156 } 157 158 if(!qdutils::MDPVersion::getInstance().isSrcSplit() && 159 property_get("persist.mdpcomp.4k2kSplit", property, "0") > 0 && 160 (!strncmp(property, "1", PROPERTY_VALUE_MAX) || 161 !strncasecmp(property,"true", PROPERTY_VALUE_MAX))) { 162 sEnable4k2kYUVSplit = true; 163 } 164 165 if ((property_get("persist.hwc.ptor.enable", property, NULL) > 0) && 166 ((!strncasecmp(property, "true", PROPERTY_VALUE_MAX )) || 167 (!strncmp(property, "1", PROPERTY_VALUE_MAX )))) { 168 ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx, 169 HWC_DISPLAY_PRIMARY); 170 } 171 172 return true; 173} 174 175void MDPComp::reset(hwc_context_t *ctx) { 176 const int numLayers = ctx->listStats[mDpy].numAppLayers; 177 mCurrentFrame.reset(numLayers); 178 ctx->mOverlay->clear(mDpy); 179 ctx->mLayerRotMap[mDpy]->clear(); 180} 181 182void MDPComp::reset() { 183 sHandleTimeout = false; 184 mModeOn = false; 185} 186 187void MDPComp::timeout_handler(void *udata) { 188 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata); 189 190 if(!ctx) { 191 ALOGE("%s: received empty data in timer callback", __FUNCTION__); 192 return; 193 } 194 Locker::Autolock _l(ctx->mDrawLock); 195 // Handle timeout event only if the previous composition is MDP or MIXED. 196 if(!sHandleTimeout) { 197 ALOGD_IF(isDebug(), "%s:Do not handle this timeout", __FUNCTION__); 198 return; 199 } 200 if(!ctx->proc) { 201 ALOGE("%s: HWC proc not registered", __FUNCTION__); 202 return; 203 } 204 sIdleFallBack = true; 205 /* Trigger SF to redraw the current frame */ 206 ctx->proc->invalidate(ctx->proc); 207} 208 209void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx, 210 hwc_display_contents_1_t* list) { 211 LayerProp *layerProp = ctx->layerProp[mDpy]; 212 213 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) { 214 hwc_layer_1_t* layer = &(list->hwLayers[index]); 215 if(!mCurrentFrame.isFBComposed[index]) { 216 layerProp[index].mFlags |= HWC_MDPCOMP; 217 layer->compositionType = HWC_OVERLAY; 218 layer->hints |= HWC_HINT_CLEAR_FB; 219 } else { 220 /* Drop the layer when its already present in FB OR when it lies 221 * outside frame's ROI */ 222 if(!mCurrentFrame.needsRedraw || mCurrentFrame.drop[index]) { 223 layer->compositionType = HWC_OVERLAY; 224 } 225 } 226 } 227} 228 229void MDPComp::setRedraw(hwc_context_t *ctx, 230 hwc_display_contents_1_t* list) { 231 mCurrentFrame.needsRedraw = false; 232 if(!mCachedFrame.isSameFrame(mCurrentFrame, list) || 233 (list->flags & HWC_GEOMETRY_CHANGED) || 234 isSkipPresent(ctx, mDpy)) { 235 mCurrentFrame.needsRedraw = true; 236 } 237} 238 239MDPComp::FrameInfo::FrameInfo() { 240 memset(&mdpToLayer, 0, sizeof(mdpToLayer)); 241 reset(0); 242} 243 244void MDPComp::FrameInfo::reset(const int& numLayers) { 245 for(int i = 0 ; i < MAX_PIPES_PER_MIXER; i++ ) { 246 if(mdpToLayer[i].pipeInfo) { 247 delete mdpToLayer[i].pipeInfo; 248 mdpToLayer[i].pipeInfo = NULL; 249 //We dont own the rotator 250 mdpToLayer[i].rot = NULL; 251 } 252 } 253 254 memset(&mdpToLayer, 0, sizeof(mdpToLayer)); 255 memset(&layerToMDP, -1, sizeof(layerToMDP)); 256 memset(&isFBComposed, 1, sizeof(isFBComposed)); 257 258 layerCount = numLayers; 259 fbCount = numLayers; 260 mdpCount = 0; 261 needsRedraw = true; 262 fbZ = -1; 263} 264 265void MDPComp::FrameInfo::map() { 266 // populate layer and MDP maps 267 int mdpIdx = 0; 268 for(int idx = 0; idx < layerCount; idx++) { 269 if(!isFBComposed[idx]) { 270 mdpToLayer[mdpIdx].listIndex = idx; 271 layerToMDP[idx] = mdpIdx++; 272 } 273 } 274} 275 276MDPComp::LayerCache::LayerCache() { 277 reset(); 278} 279 280void MDPComp::LayerCache::reset() { 281 memset(&hnd, 0, sizeof(hnd)); 282 memset(&isFBComposed, true, sizeof(isFBComposed)); 283 memset(&drop, false, sizeof(drop)); 284 layerCount = 0; 285} 286 287void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) { 288 const int numAppLayers = (int)list->numHwLayers - 1; 289 for(int i = 0; i < numAppLayers; i++) { 290 hnd[i] = list->hwLayers[i].handle; 291 } 292} 293 294void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) { 295 layerCount = curFrame.layerCount; 296 memcpy(&isFBComposed, &curFrame.isFBComposed, sizeof(isFBComposed)); 297 memcpy(&drop, &curFrame.drop, sizeof(drop)); 298} 299 300bool MDPComp::LayerCache::isSameFrame(const FrameInfo& curFrame, 301 hwc_display_contents_1_t* list) { 302 if(layerCount != curFrame.layerCount) 303 return false; 304 for(int i = 0; i < curFrame.layerCount; i++) { 305 if((curFrame.isFBComposed[i] != isFBComposed[i]) || 306 (curFrame.drop[i] != drop[i])) { 307 return false; 308 } 309 if(curFrame.isFBComposed[i] && 310 (hnd[i] != list->hwLayers[i].handle)){ 311 return false; 312 } 313 } 314 return true; 315} 316 317bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) { 318 private_handle_t *hnd = (private_handle_t *)layer->handle; 319 if((has90Transform(layer) and (not isRotationDoable(ctx, hnd))) || 320 (not isValidDimension(ctx,layer)) 321 //More conditions here, SKIP, sRGB+Blend etc 322 ) { 323 return false; 324 } 325 return true; 326} 327 328bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) { 329 private_handle_t *hnd = (private_handle_t *)layer->handle; 330 331 if(!hnd) { 332 if (layer->flags & HWC_COLOR_FILL) { 333 // Color layer 334 return true; 335 } 336 ALOGE("%s: layer handle is NULL", __FUNCTION__); 337 return false; 338 } 339 340 //XXX: Investigate doing this with pixel phase on MDSS 341 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf)) 342 return false; 343 344 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf); 345 hwc_rect_t dst = layer->displayFrame; 346 bool rotated90 = (bool)(layer->transform & HAL_TRANSFORM_ROT_90); 347 int crop_w = rotated90 ? crop.bottom - crop.top : crop.right - crop.left; 348 int crop_h = rotated90 ? crop.right - crop.left : crop.bottom - crop.top; 349 int dst_w = dst.right - dst.left; 350 int dst_h = dst.bottom - dst.top; 351 float w_scale = ((float)crop_w / (float)dst_w); 352 float h_scale = ((float)crop_h / (float)dst_h); 353 354 /* Workaround for MDP HW limitation in DSI command mode panels where 355 * FPS will not go beyond 30 if buffers on RGB pipes are of width or height 356 * less than 5 pixels 357 * There also is a HW limilation in MDP, minimum block size is 2x2 358 * Fallback to GPU if height is less than 2. 359 */ 360 if((crop_w < 5)||(crop_h < 5)) 361 return false; 362 363 if((w_scale > 1.0f) || (h_scale > 1.0f)) { 364 const uint32_t maxMDPDownscale = 365 qdutils::MDPVersion::getInstance().getMaxMDPDownscale(); 366 const float w_dscale = w_scale; 367 const float h_dscale = h_scale; 368 369 if(ctx->mMDP.version >= qdutils::MDSS_V5) { 370 371 if(!qdutils::MDPVersion::getInstance().supportsDecimation()) { 372 /* On targets that doesnt support Decimation (eg.,8x26) 373 * maximum downscale support is overlay pipe downscale. 374 */ 375 if(crop_w > MAX_DISPLAY_DIM || w_dscale > maxMDPDownscale || 376 h_dscale > maxMDPDownscale) 377 return false; 378 } else { 379 // Decimation on macrotile format layers is not supported. 380 if(isTileRendered(hnd)) { 381 /* MDP can read maximum MAX_DISPLAY_DIM width. 382 * Bail out if 383 * 1. Src crop > MAX_DISPLAY_DIM on nonsplit MDPComp 384 * 2. exceeds maximum downscale limit 385 */ 386 if(((crop_w > MAX_DISPLAY_DIM) && !sSrcSplitEnabled) || 387 w_dscale > maxMDPDownscale || 388 h_dscale > maxMDPDownscale) { 389 return false; 390 } 391 } else if(w_dscale > 64 || h_dscale > 64) 392 return false; 393 } 394 } else { //A-family 395 if(w_dscale > maxMDPDownscale || h_dscale > maxMDPDownscale) 396 return false; 397 } 398 } 399 400 if((w_scale < 1.0f) || (h_scale < 1.0f)) { 401 const uint32_t upscale = 402 qdutils::MDPVersion::getInstance().getMaxMDPUpscale(); 403 const float w_uscale = 1.0f / w_scale; 404 const float h_uscale = 1.0f / h_scale; 405 406 if(w_uscale > upscale || h_uscale > upscale) 407 return false; 408 } 409 410 return true; 411} 412 413bool MDPComp::isFrameDoable(hwc_context_t *ctx) { 414 bool ret = true; 415 416 if(!isEnabled()) { 417 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__); 418 ret = false; 419 } else if((qdutils::MDPVersion::getInstance().is8x26() || 420 qdutils::MDPVersion::getInstance().is8x16() || 421 qdutils::MDPVersion::getInstance().is8x39()) && 422 ctx->mVideoTransFlag && 423 isSecondaryConnected(ctx)) { 424 //1 Padding round to shift pipes across mixers 425 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round", 426 __FUNCTION__); 427 ret = false; 428 } else if(isSecondaryConfiguring(ctx)) { 429 ALOGD_IF( isDebug(),"%s: External Display connection is pending", 430 __FUNCTION__); 431 ret = false; 432 } else if(ctx->isPaddingRound) { 433 ALOGD_IF(isDebug(), "%s: padding round invoked for dpy %d", 434 __FUNCTION__,mDpy); 435 ret = false; 436 } 437 return ret; 438} 439 440void MDPCompNonSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) { 441 hwc_rect_t roi = ctx->listStats[mDpy].lRoi; 442 fbRect = getIntersection(fbRect, roi); 443} 444 445/* 1) Identify layers that are not visible or lying outside the updating ROI and 446 * drop them from composition. 447 * 2) If we have a scaling layer which needs cropping against generated 448 * ROI, reset ROI to full resolution. */ 449bool MDPCompNonSplit::validateAndApplyROI(hwc_context_t *ctx, 450 hwc_display_contents_1_t* list) { 451 int numAppLayers = ctx->listStats[mDpy].numAppLayers; 452 hwc_rect_t visibleRect = ctx->listStats[mDpy].lRoi; 453 454 for(int i = numAppLayers - 1; i >= 0; i--){ 455 if(!isValidRect(visibleRect)) { 456 mCurrentFrame.drop[i] = true; 457 mCurrentFrame.dropCount++; 458 continue; 459 } 460 461 const hwc_layer_1_t* layer = &list->hwLayers[i]; 462 hwc_rect_t dstRect = layer->displayFrame; 463 hwc_rect_t res = getIntersection(visibleRect, dstRect); 464 465 if(!isValidRect(res)) { 466 mCurrentFrame.drop[i] = true; 467 mCurrentFrame.dropCount++; 468 } else { 469 /* Reset frame ROI when any layer which needs scaling also needs ROI 470 * cropping */ 471 if(!isSameRect(res, dstRect) && needsScaling (layer)) { 472 ALOGI("%s: Resetting ROI due to scaling", __FUNCTION__); 473 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop)); 474 mCurrentFrame.dropCount = 0; 475 return false; 476 } 477 478 /* deduct any opaque region from visibleRect */ 479 if (layer->blending == HWC_BLENDING_NONE) 480 visibleRect = deductRect(visibleRect, res); 481 } 482 } 483 return true; 484} 485 486/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which 487 * are updating. If DirtyRegion is applicable, calculate it by accounting all 488 * the changing layer's dirtyRegion. */ 489void MDPCompNonSplit::generateROI(hwc_context_t *ctx, 490 hwc_display_contents_1_t* list) { 491 int numAppLayers = ctx->listStats[mDpy].numAppLayers; 492 if(!canPartialUpdate(ctx, list)) 493 return; 494 495 struct hwc_rect roi = (struct hwc_rect){0, 0, 0, 0}; 496 hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[mDpy].xres, 497 (int)ctx->dpyAttr[mDpy].yres}; 498 499 for(int index = 0; index < numAppLayers; index++ ) { 500 hwc_layer_1_t* layer = &list->hwLayers[index]; 501 if ((mCachedFrame.hnd[index] != layer->handle) || 502 isYuvBuffer((private_handle_t *)layer->handle)) { 503 hwc_rect_t dst = layer->displayFrame; 504 hwc_rect_t updatingRect = dst; 505 506#ifdef QCOM_BSP 507 if(!needsScaling(layer) && !layer->transform) 508 { 509 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf); 510 int x_off = dst.left - src.left; 511 int y_off = dst.top - src.top; 512 updatingRect = moveRect(layer->dirtyRect, x_off, y_off); 513 } 514#endif 515 516 roi = getUnion(roi, updatingRect); 517 } 518 } 519 520 /* No layer is updating. Still SF wants a refresh.*/ 521 if(!isValidRect(roi)) 522 return; 523 524 // Align ROI coordinates to panel restrictions 525 roi = getSanitizeROI(roi, fullFrame); 526 527 ctx->listStats[mDpy].lRoi = roi; 528 if(!validateAndApplyROI(ctx, list)) 529 resetROI(ctx, mDpy); 530 531 ALOGD_IF(isDebug(),"%s: generated ROI: [%d, %d, %d, %d]", __FUNCTION__, 532 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top, 533 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom); 534} 535 536void MDPCompSplit::trimAgainstROI(hwc_context_t *ctx, hwc_rect_t& fbRect) { 537 hwc_rect l_roi = ctx->listStats[mDpy].lRoi; 538 hwc_rect r_roi = ctx->listStats[mDpy].rRoi; 539 540 hwc_rect_t l_fbRect = getIntersection(fbRect, l_roi); 541 hwc_rect_t r_fbRect = getIntersection(fbRect, r_roi); 542 fbRect = getUnion(l_fbRect, r_fbRect); 543} 544/* 1) Identify layers that are not visible or lying outside BOTH the updating 545 * ROI's and drop them from composition. If a layer is spanning across both 546 * the halves of the screen but needed by only ROI, the non-contributing 547 * half will not be programmed for MDP. 548 * 2) If we have a scaling layer which needs cropping against generated 549 * ROI, reset ROI to full resolution. */ 550bool MDPCompSplit::validateAndApplyROI(hwc_context_t *ctx, 551 hwc_display_contents_1_t* list) { 552 553 int numAppLayers = ctx->listStats[mDpy].numAppLayers; 554 555 hwc_rect_t visibleRectL = ctx->listStats[mDpy].lRoi; 556 hwc_rect_t visibleRectR = ctx->listStats[mDpy].rRoi; 557 558 for(int i = numAppLayers - 1; i >= 0; i--){ 559 if(!isValidRect(visibleRectL) && !isValidRect(visibleRectR)) 560 { 561 mCurrentFrame.drop[i] = true; 562 mCurrentFrame.dropCount++; 563 continue; 564 } 565 566 const hwc_layer_1_t* layer = &list->hwLayers[i]; 567 hwc_rect_t dstRect = layer->displayFrame; 568 569 hwc_rect_t l_res = getIntersection(visibleRectL, dstRect); 570 hwc_rect_t r_res = getIntersection(visibleRectR, dstRect); 571 hwc_rect_t res = getUnion(l_res, r_res); 572 573 if(!isValidRect(l_res) && !isValidRect(r_res)) { 574 mCurrentFrame.drop[i] = true; 575 mCurrentFrame.dropCount++; 576 } else { 577 /* Reset frame ROI when any layer which needs scaling also needs ROI 578 * cropping */ 579 if(!isSameRect(res, dstRect) && needsScaling (layer)) { 580 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop)); 581 mCurrentFrame.dropCount = 0; 582 return false; 583 } 584 585 if (layer->blending == HWC_BLENDING_NONE) { 586 visibleRectL = deductRect(visibleRectL, l_res); 587 visibleRectR = deductRect(visibleRectR, r_res); 588 } 589 } 590 } 591 return true; 592} 593/* Calculate ROI for the frame by accounting all the layer's dispalyFrame which 594 * are updating. If DirtyRegion is applicable, calculate it by accounting all 595 * the changing layer's dirtyRegion. */ 596void MDPCompSplit::generateROI(hwc_context_t *ctx, 597 hwc_display_contents_1_t* list) { 598 if(!canPartialUpdate(ctx, list)) 599 return; 600 601 int numAppLayers = ctx->listStats[mDpy].numAppLayers; 602 int lSplit = getLeftSplit(ctx, mDpy); 603 604 int hw_h = (int)ctx->dpyAttr[mDpy].yres; 605 int hw_w = (int)ctx->dpyAttr[mDpy].xres; 606 607 struct hwc_rect l_frame = (struct hwc_rect){0, 0, lSplit, hw_h}; 608 struct hwc_rect r_frame = (struct hwc_rect){lSplit, 0, hw_w, hw_h}; 609 610 struct hwc_rect l_roi = (struct hwc_rect){0, 0, 0, 0}; 611 struct hwc_rect r_roi = (struct hwc_rect){0, 0, 0, 0}; 612 613 for(int index = 0; index < numAppLayers; index++ ) { 614 hwc_layer_1_t* layer = &list->hwLayers[index]; 615 private_handle_t *hnd = (private_handle_t *)layer->handle; 616 if ((mCachedFrame.hnd[index] != layer->handle) || 617 isYuvBuffer(hnd)) { 618 hwc_rect_t dst = layer->displayFrame; 619 hwc_rect_t updatingRect = dst; 620 621#ifdef QCOM_BSP 622 if(!needsScaling(layer) && !layer->transform) 623 { 624 hwc_rect_t src = integerizeSourceCrop(layer->sourceCropf); 625 int x_off = dst.left - src.left; 626 int y_off = dst.top - src.top; 627 updatingRect = moveRect(layer->dirtyRect, x_off, y_off); 628 } 629#endif 630 631 hwc_rect_t l_dst = getIntersection(l_frame, updatingRect); 632 if(isValidRect(l_dst)) 633 l_roi = getUnion(l_roi, l_dst); 634 635 hwc_rect_t r_dst = getIntersection(r_frame, updatingRect); 636 if(isValidRect(r_dst)) 637 r_roi = getUnion(r_roi, r_dst); 638 } 639 } 640 641 /* For panels that cannot accept commands in both the interfaces, we cannot 642 * send two ROI's (for each half). We merge them into single ROI and split 643 * them across lSplit for MDP mixer use. The ROI's will be merged again 644 * finally before udpating the panel in the driver. */ 645 if(qdutils::MDPVersion::getInstance().needsROIMerge()) { 646 hwc_rect_t temp_roi = getUnion(l_roi, r_roi); 647 l_roi = getIntersection(temp_roi, l_frame); 648 r_roi = getIntersection(temp_roi, r_frame); 649 } 650 651 /* No layer is updating. Still SF wants a refresh. */ 652 if(!isValidRect(l_roi) && !isValidRect(r_roi)) 653 return; 654 655 l_roi = getSanitizeROI(l_roi, l_frame); 656 r_roi = getSanitizeROI(r_roi, r_frame); 657 658 ctx->listStats[mDpy].lRoi = l_roi; 659 ctx->listStats[mDpy].rRoi = r_roi; 660 661 if(!validateAndApplyROI(ctx, list)) 662 resetROI(ctx, mDpy); 663 664 ALOGD_IF(isDebug(),"%s: generated L_ROI: [%d, %d, %d, %d]" 665 "R_ROI: [%d, %d, %d, %d]", __FUNCTION__, 666 ctx->listStats[mDpy].lRoi.left, ctx->listStats[mDpy].lRoi.top, 667 ctx->listStats[mDpy].lRoi.right, ctx->listStats[mDpy].lRoi.bottom, 668 ctx->listStats[mDpy].rRoi.left, ctx->listStats[mDpy].rRoi.top, 669 ctx->listStats[mDpy].rRoi.right, ctx->listStats[mDpy].rRoi.bottom); 670} 671 672/* Checks for conditions where all the layers marked for MDP comp cannot be 673 * bypassed. On such conditions we try to bypass atleast YUV layers */ 674bool MDPComp::tryFullFrame(hwc_context_t *ctx, 675 hwc_display_contents_1_t* list){ 676 677 const int numAppLayers = ctx->listStats[mDpy].numAppLayers; 678 int priDispW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres; 679 680 if(sIdleFallBack && !ctx->listStats[mDpy].secureUI) { 681 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy); 682 return false; 683 } 684 685 if(isSkipPresent(ctx, mDpy)) { 686 ALOGD_IF(isDebug(),"%s: SKIP present: %d", 687 __FUNCTION__, 688 isSkipPresent(ctx, mDpy)); 689 return false; 690 } 691 692 if(mDpy > HWC_DISPLAY_PRIMARY && (priDispW > MAX_DISPLAY_DIM) && 693 (ctx->dpyAttr[mDpy].xres < MAX_DISPLAY_DIM)) { 694 // Disable MDP comp on Secondary when the primary is highres panel and 695 // the secondary is a normal 1080p, because, MDP comp on secondary under 696 // in such usecase, decimation gets used for downscale and there will be 697 // a quality mismatch when there will be a fallback to GPU comp 698 ALOGD_IF(isDebug(), "%s: Disable MDP Compositon for Secondary Disp", 699 __FUNCTION__); 700 return false; 701 } 702 703 // check for action safe flag and downscale mode which requires scaling. 704 if(ctx->dpyAttr[mDpy].mActionSafePresent 705 || ctx->dpyAttr[mDpy].mDownScaleMode) { 706 ALOGD_IF(isDebug(), "%s: Scaling needed for this frame",__FUNCTION__); 707 return false; 708 } 709 710 for(int i = 0; i < numAppLayers; ++i) { 711 hwc_layer_1_t* layer = &list->hwLayers[i]; 712 private_handle_t *hnd = (private_handle_t *)layer->handle; 713 714 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) { 715 if(!canUseRotator(ctx, mDpy)) { 716 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d", 717 __FUNCTION__, mDpy); 718 return false; 719 } 720 } 721 722 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp 723 // may not need it if Gfx pre-rotation can handle all flips & rotations 724 if(qdutils::MDPVersion::getInstance().is8x26() && 725 (ctx->dpyAttr[mDpy].xres > 1024) && 726 (layer->transform & HWC_TRANSFORM_FLIP_H) && 727 (!isYuvBuffer(hnd))) 728 return false; 729 } 730 731 if(ctx->mAD->isDoable()) { 732 return false; 733 } 734 735 //If all above hard conditions are met we can do full or partial MDP comp. 736 bool ret = false; 737 if(fullMDPComp(ctx, list)) { 738 ret = true; 739 } else if(fullMDPCompWithPTOR(ctx, list)) { 740 ret = true; 741 } else if(partialMDPComp(ctx, list)) { 742 ret = true; 743 } 744 745 return ret; 746} 747 748bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 749 750 if(sSimulationFlags & MDPCOMP_AVOID_FULL_MDP) 751 return false; 752 753 //Will benefit presentation / secondary-only layer. 754 if((mDpy > HWC_DISPLAY_PRIMARY) && 755 (list->numHwLayers - 1) > MAX_SEC_LAYERS) { 756 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__); 757 return false; 758 } 759 760 const int numAppLayers = ctx->listStats[mDpy].numAppLayers; 761 for(int i = 0; i < numAppLayers; i++) { 762 hwc_layer_1_t* layer = &list->hwLayers[i]; 763 if(not mCurrentFrame.drop[i] and 764 not isSupportedForMDPComp(ctx, layer)) { 765 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__); 766 return false; 767 } 768 } 769 770 mCurrentFrame.fbCount = 0; 771 memcpy(&mCurrentFrame.isFBComposed, &mCurrentFrame.drop, 772 sizeof(mCurrentFrame.isFBComposed)); 773 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount - 774 mCurrentFrame.dropCount; 775 776 if(sEnable4k2kYUVSplit){ 777 adjustForSourceSplit(ctx, list); 778 } 779 780 if(!postHeuristicsHandling(ctx, list)) { 781 ALOGD_IF(isDebug(), "post heuristic handling failed"); 782 reset(ctx); 783 return false; 784 } 785 ALOGD_IF(sSimulationFlags,"%s: FULL_MDP_COMP SUCCEEDED", 786 __FUNCTION__); 787 return true; 788} 789 790/* Full MDP Composition with Peripheral Tiny Overlap Removal. 791 * MDP bandwidth limitations can be avoided, if the overlap region 792 * covered by the smallest layer at a higher z-order, gets composed 793 * by Copybit on a render buffer, which can be queued to MDP. 794 */ 795bool MDPComp::fullMDPCompWithPTOR(hwc_context_t *ctx, 796 hwc_display_contents_1_t* list) { 797 798 const int numAppLayers = ctx->listStats[mDpy].numAppLayers; 799 const int stagesForMDP = min(sMaxPipesPerMixer, 800 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT)); 801 802 // Hard checks where we cannot use this mode 803 if (mDpy || !ctx->mCopyBit[mDpy] || isDisplaySplit(ctx, mDpy)) { 804 ALOGD_IF(isDebug(), "%s: Feature not supported!", __FUNCTION__); 805 return false; 806 } 807 808 // Frame level checks 809 if ((numAppLayers > stagesForMDP) || isSkipPresent(ctx, mDpy) || 810 isYuvPresent(ctx, mDpy) || mCurrentFrame.dropCount || 811 isSecurePresent(ctx, mDpy)) { 812 ALOGD_IF(isDebug(), "%s: Frame not supported!", __FUNCTION__); 813 return false; 814 } 815 // MDP comp checks 816 for(int i = 0; i < numAppLayers; i++) { 817 hwc_layer_1_t* layer = &list->hwLayers[i]; 818 if(not isSupportedForMDPComp(ctx, layer)) { 819 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__); 820 return false; 821 } 822 } 823 824 /* We cannot use this composition mode, if: 825 1. A below layer needs scaling. 826 2. Overlap is not peripheral to display. 827 3. Overlap or a below layer has 90 degree transform. 828 4. Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs. 829 */ 830 831 int minLayerIndex[MAX_PTOR_LAYERS] = { -1, -1}; 832 hwc_rect_t overlapRect[MAX_PTOR_LAYERS]; 833 memset(overlapRect, 0, sizeof(overlapRect)); 834 int layerPixelCount, minPixelCount = 0; 835 int numPTORLayersFound = 0; 836 for (int i = numAppLayers-1; (i >= 0 && 837 numPTORLayersFound < MAX_PTOR_LAYERS); i--) { 838 hwc_layer_1_t* layer = &list->hwLayers[i]; 839 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf); 840 hwc_rect_t dispFrame = layer->displayFrame; 841 layerPixelCount = (crop.right - crop.left) * (crop.bottom - crop.top); 842 // PTOR layer should be peripheral and cannot have transform 843 if (!isPeripheral(dispFrame, ctx->mViewFrame[mDpy]) || 844 has90Transform(layer)) { 845 continue; 846 } 847 if((3 * (layerPixelCount + minPixelCount)) > 848 ((int)ctx->dpyAttr[mDpy].xres * (int)ctx->dpyAttr[mDpy].yres)) { 849 // Overlap area > (1/3 * FrameBuffer) area, based on Perf inputs. 850 continue; 851 } 852 // Found the PTOR layer 853 bool found = true; 854 for (int j = i-1; j >= 0; j--) { 855 // Check if the layers below this layer qualifies for PTOR comp 856 hwc_layer_1_t* layer = &list->hwLayers[j]; 857 hwc_rect_t disFrame = layer->displayFrame; 858 //layer below PTOR is intersecting and has 90 degree transform or 859 // needs scaling cannot be supported. 860 if ((isValidRect(getIntersection(dispFrame, disFrame))) 861 && (has90Transform(layer) || needsScaling(layer))) { 862 found = false; 863 break; 864 } 865 } 866 // Store the minLayer Index 867 if(found) { 868 minLayerIndex[numPTORLayersFound] = i; 869 overlapRect[numPTORLayersFound] = list->hwLayers[i].displayFrame; 870 minPixelCount += layerPixelCount; 871 numPTORLayersFound++; 872 } 873 } 874 875 if(isValidRect(getIntersection(overlapRect[0], overlapRect[1]))) { 876 ALOGD_IF(isDebug(), "%s: Ignore Rect2 its intersects with Rect1", 877 __FUNCTION__); 878 // reset second minLayerIndex[1]; 879 minLayerIndex[1] = -1; 880 numPTORLayersFound--; 881 } 882 883 // No overlap layers 884 if (!numPTORLayersFound) 885 return false; 886 887 ctx->mPtorInfo.count = numPTORLayersFound; 888 for(int i = 0; i < MAX_PTOR_LAYERS; i++) { 889 ctx->mPtorInfo.layerIndex[i] = minLayerIndex[i]; 890 } 891 892 if (!ctx->mCopyBit[mDpy]->prepareOverlap(ctx, list)) { 893 // reset PTOR 894 ctx->mPtorInfo.count = 0; 895 return false; 896 } 897 // Store the displayFrame and the sourceCrops of the layers 898 hwc_rect_t displayFrame[numAppLayers]; 899 hwc_rect_t sourceCrop[numAppLayers]; 900 for(int i = 0; i < numAppLayers; i++) { 901 hwc_layer_1_t* layer = &list->hwLayers[i]; 902 displayFrame[i] = layer->displayFrame; 903 sourceCrop[i] = integerizeSourceCrop(layer->sourceCropf); 904 } 905 906 for(int j = 0; j < numPTORLayersFound; j++) { 907 int index = ctx->mPtorInfo.layerIndex[j]; 908 // Remove overlap from crop & displayFrame of below layers 909 for (int i = 0; i < index && index !=-1; i++) { 910 hwc_layer_1_t* layer = &list->hwLayers[i]; 911 if(!isValidRect(getIntersection(layer->displayFrame, 912 overlapRect[j]))) { 913 continue; 914 } 915 // Update layer attributes 916 hwc_rect_t srcCrop = integerizeSourceCrop(layer->sourceCropf); 917 hwc_rect_t destRect = deductRect(layer->displayFrame, 918 overlapRect[j]); 919 qhwc::calculate_crop_rects(srcCrop, layer->displayFrame, destRect, 920 layer->transform); 921 layer->sourceCropf.left = (float)srcCrop.left; 922 layer->sourceCropf.top = (float)srcCrop.top; 923 layer->sourceCropf.right = (float)srcCrop.right; 924 layer->sourceCropf.bottom = (float)srcCrop.bottom; 925 } 926 } 927 928 mCurrentFrame.mdpCount = numAppLayers; 929 mCurrentFrame.fbCount = 0; 930 mCurrentFrame.fbZ = -1; 931 932 for (int j = 0; j < numAppLayers; j++) 933 mCurrentFrame.isFBComposed[j] = false; 934 935 bool result = postHeuristicsHandling(ctx, list); 936 937 // Restore layer attributes 938 for(int i = 0; i < numAppLayers; i++) { 939 hwc_layer_1_t* layer = &list->hwLayers[i]; 940 layer->displayFrame = displayFrame[i]; 941 layer->sourceCropf.left = (float)sourceCrop[i].left; 942 layer->sourceCropf.top = (float)sourceCrop[i].top; 943 layer->sourceCropf.right = (float)sourceCrop[i].right; 944 layer->sourceCropf.bottom = (float)sourceCrop[i].bottom; 945 } 946 947 if (!result) { 948 // reset PTOR 949 ctx->mPtorInfo.count = 0; 950 reset(ctx); 951 } else { 952 ALOGD_IF(isDebug(), "%s: PTOR Indexes: %d and %d", __FUNCTION__, 953 ctx->mPtorInfo.layerIndex[0], ctx->mPtorInfo.layerIndex[1]); 954 } 955 956 ALOGD_IF(isDebug(), "%s: Postheuristics %s!", __FUNCTION__, 957 (result ? "successful" : "failed")); 958 return result; 959} 960 961bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) 962{ 963 if(!sEnableMixedMode) { 964 //Mixed mode is disabled. No need to even try caching. 965 return false; 966 } 967 968 bool ret = false; 969 if(list->flags & HWC_GEOMETRY_CHANGED) { //Try load based first 970 ret = loadBasedComp(ctx, list) or 971 cacheBasedComp(ctx, list); 972 } else { 973 ret = cacheBasedComp(ctx, list) or 974 loadBasedComp(ctx, list); 975 } 976 977 return ret; 978} 979 980bool MDPComp::cacheBasedComp(hwc_context_t *ctx, 981 hwc_display_contents_1_t* list) { 982 if(sSimulationFlags & MDPCOMP_AVOID_CACHE_MDP) 983 return false; 984 985 int numAppLayers = ctx->listStats[mDpy].numAppLayers; 986 mCurrentFrame.reset(numAppLayers); 987 updateLayerCache(ctx, list); 988 989 //If an MDP marked layer is unsupported cannot do partial MDP Comp 990 for(int i = 0; i < numAppLayers; i++) { 991 if(!mCurrentFrame.isFBComposed[i]) { 992 hwc_layer_1_t* layer = &list->hwLayers[i]; 993 if(not isSupportedForMDPComp(ctx, layer)) { 994 ALOGD_IF(isDebug(), "%s: Unsupported layer in list", 995 __FUNCTION__); 996 reset(ctx); 997 return false; 998 } 999 } 1000 } 1001 1002 updateYUV(ctx, list, false /*secure only*/); 1003 bool ret = markLayersForCaching(ctx, list); //sets up fbZ also 1004 if(!ret) { 1005 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy); 1006 reset(ctx); 1007 return false; 1008 } 1009 1010 int mdpCount = mCurrentFrame.mdpCount; 1011 1012 if(sEnable4k2kYUVSplit){ 1013 adjustForSourceSplit(ctx, list); 1014 } 1015 1016 //Will benefit cases where a video has non-updating background. 1017 if((mDpy > HWC_DISPLAY_PRIMARY) and 1018 (mdpCount > MAX_SEC_LAYERS)) { 1019 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__); 1020 reset(ctx); 1021 return false; 1022 } 1023 1024 if(!postHeuristicsHandling(ctx, list)) { 1025 ALOGD_IF(isDebug(), "post heuristic handling failed"); 1026 reset(ctx); 1027 return false; 1028 } 1029 ALOGD_IF(sSimulationFlags,"%s: CACHE_MDP_COMP SUCCEEDED", 1030 __FUNCTION__); 1031 1032 return true; 1033} 1034 1035bool MDPComp::loadBasedComp(hwc_context_t *ctx, 1036 hwc_display_contents_1_t* list) { 1037 if(sSimulationFlags & MDPCOMP_AVOID_LOAD_MDP) 1038 return false; 1039 1040 if(not isLoadBasedCompDoable(ctx)) { 1041 return false; 1042 } 1043 1044 const int numAppLayers = ctx->listStats[mDpy].numAppLayers; 1045 const int numNonDroppedLayers = numAppLayers - mCurrentFrame.dropCount; 1046 const int stagesForMDP = min(sMaxPipesPerMixer, 1047 ctx->mOverlay->availablePipes(mDpy, Overlay::MIXER_DEFAULT)); 1048 1049 int mdpBatchSize = stagesForMDP - 1; //1 stage for FB 1050 int fbBatchSize = numNonDroppedLayers - mdpBatchSize; 1051 int lastMDPSupportedIndex = numAppLayers; 1052 int dropCount = 0; 1053 1054 //Find the minimum MDP batch size 1055 for(int i = 0; i < numAppLayers;i++) { 1056 if(mCurrentFrame.drop[i]) { 1057 dropCount++; 1058 continue; 1059 } 1060 hwc_layer_1_t* layer = &list->hwLayers[i]; 1061 if(not isSupportedForMDPComp(ctx, layer)) { 1062 lastMDPSupportedIndex = i; 1063 mdpBatchSize = min(i - dropCount, stagesForMDP - 1); 1064 fbBatchSize = numNonDroppedLayers - mdpBatchSize; 1065 break; 1066 } 1067 } 1068 1069 ALOGD_IF(isDebug(), "%s:Before optimizing fbBatch, mdpbatch %d, fbbatch %d " 1070 "dropped %d", __FUNCTION__, mdpBatchSize, fbBatchSize, 1071 mCurrentFrame.dropCount); 1072 1073 //Start at a point where the fb batch should at least have 2 layers, for 1074 //this mode to be justified. 1075 while(fbBatchSize < 2) { 1076 ++fbBatchSize; 1077 --mdpBatchSize; 1078 } 1079 1080 //If there are no layers for MDP, this mode doesnt make sense. 1081 if(mdpBatchSize < 1) { 1082 ALOGD_IF(isDebug(), "%s: No MDP layers after optimizing for fbBatch", 1083 __FUNCTION__); 1084 return false; 1085 } 1086 1087 mCurrentFrame.reset(numAppLayers); 1088 1089 //Try with successively smaller mdp batch sizes until we succeed or reach 1 1090 while(mdpBatchSize > 0) { 1091 //Mark layers for MDP comp 1092 int mdpBatchLeft = mdpBatchSize; 1093 for(int i = 0; i < lastMDPSupportedIndex and mdpBatchLeft; i++) { 1094 if(mCurrentFrame.drop[i]) { 1095 continue; 1096 } 1097 mCurrentFrame.isFBComposed[i] = false; 1098 --mdpBatchLeft; 1099 } 1100 1101 mCurrentFrame.fbZ = mdpBatchSize; 1102 mCurrentFrame.fbCount = fbBatchSize; 1103 mCurrentFrame.mdpCount = mdpBatchSize; 1104 1105 ALOGD_IF(isDebug(), "%s:Trying with: mdpbatch %d fbbatch %d dropped %d", 1106 __FUNCTION__, mdpBatchSize, fbBatchSize, 1107 mCurrentFrame.dropCount); 1108 1109 if(postHeuristicsHandling(ctx, list)) { 1110 ALOGD_IF(isDebug(), "%s: Postheuristics handling succeeded", 1111 __FUNCTION__); 1112 ALOGD_IF(sSimulationFlags,"%s: LOAD_MDP_COMP SUCCEEDED", 1113 __FUNCTION__); 1114 return true; 1115 } 1116 1117 reset(ctx); 1118 --mdpBatchSize; 1119 ++fbBatchSize; 1120 } 1121 1122 return false; 1123} 1124 1125bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx) { 1126 if(mDpy or isSecurePresent(ctx, mDpy) or 1127 isYuvPresent(ctx, mDpy)) { 1128 return false; 1129 } 1130 return true; 1131} 1132 1133bool MDPComp::canPartialUpdate(hwc_context_t *ctx, 1134 hwc_display_contents_1_t* list){ 1135 if(!qdutils::MDPVersion::getInstance().isPartialUpdateEnabled() || 1136 isSkipPresent(ctx, mDpy) || (list->flags & HWC_GEOMETRY_CHANGED) || 1137 mDpy ) { 1138 return false; 1139 } 1140 if(ctx->listStats[mDpy].secureUI) 1141 return false; 1142 return true; 1143} 1144 1145bool MDPComp::tryVideoOnly(hwc_context_t *ctx, 1146 hwc_display_contents_1_t* list) { 1147 const bool secureOnly = true; 1148 return videoOnlyComp(ctx, list, not secureOnly) or 1149 videoOnlyComp(ctx, list, secureOnly); 1150} 1151 1152bool MDPComp::videoOnlyComp(hwc_context_t *ctx, 1153 hwc_display_contents_1_t* list, bool secureOnly) { 1154 if(sSimulationFlags & MDPCOMP_AVOID_VIDEO_ONLY) 1155 return false; 1156 int numAppLayers = ctx->listStats[mDpy].numAppLayers; 1157 1158 mCurrentFrame.reset(numAppLayers); 1159 mCurrentFrame.fbCount -= mCurrentFrame.dropCount; 1160 updateYUV(ctx, list, secureOnly); 1161 int mdpCount = mCurrentFrame.mdpCount; 1162 1163 if(!isYuvPresent(ctx, mDpy) or (mdpCount == 0)) { 1164 reset(ctx); 1165 return false; 1166 } 1167 1168 /* Bail out if we are processing only secured video layers 1169 * and we dont have any */ 1170 if(!isSecurePresent(ctx, mDpy) && secureOnly){ 1171 reset(ctx); 1172 return false; 1173 } 1174 1175 if(mCurrentFrame.fbCount) 1176 mCurrentFrame.fbZ = mCurrentFrame.mdpCount; 1177 1178 if(sEnable4k2kYUVSplit){ 1179 adjustForSourceSplit(ctx, list); 1180 } 1181 1182 if(!postHeuristicsHandling(ctx, list)) { 1183 ALOGD_IF(isDebug(), "post heuristic handling failed"); 1184 reset(ctx); 1185 return false; 1186 } 1187 1188 ALOGD_IF(sSimulationFlags,"%s: VIDEO_ONLY_COMP SUCCEEDED", 1189 __FUNCTION__); 1190 return true; 1191} 1192 1193/* Checks for conditions where YUV layers cannot be bypassed */ 1194bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) { 1195 if(isSkipLayer(layer)) { 1196 ALOGD_IF(isDebug(), "%s: Video marked SKIP dpy %d", __FUNCTION__, mDpy); 1197 return false; 1198 } 1199 1200 if(has90Transform(layer) && !canUseRotator(ctx, mDpy)) { 1201 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__); 1202 return false; 1203 } 1204 1205 if(isSecuring(ctx, layer)) { 1206 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__); 1207 return false; 1208 } 1209 1210 if(!isValidDimension(ctx, layer)) { 1211 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width", 1212 __FUNCTION__); 1213 return false; 1214 } 1215 1216 if(layer->planeAlpha < 0xFF) { 1217 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\ 1218 in video only mode", 1219 __FUNCTION__); 1220 return false; 1221 } 1222 1223 return true; 1224} 1225 1226/* starts at fromIndex and check for each layer to find 1227 * if it it has overlapping with any Updating layer above it in zorder 1228 * till the end of the batch. returns true if it finds any intersection */ 1229bool MDPComp::canPushBatchToTop(const hwc_display_contents_1_t* list, 1230 int fromIndex, int toIndex) { 1231 for(int i = fromIndex; i < toIndex; i++) { 1232 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) { 1233 if(intersectingUpdatingLayers(list, i+1, toIndex, i)) { 1234 return false; 1235 } 1236 } 1237 } 1238 return true; 1239} 1240 1241/* Checks if given layer at targetLayerIndex has any 1242 * intersection with all the updating layers in beween 1243 * fromIndex and toIndex. Returns true if it finds intersectiion */ 1244bool MDPComp::intersectingUpdatingLayers(const hwc_display_contents_1_t* list, 1245 int fromIndex, int toIndex, int targetLayerIndex) { 1246 for(int i = fromIndex; i <= toIndex; i++) { 1247 if(!mCurrentFrame.isFBComposed[i]) { 1248 if(areLayersIntersecting(&list->hwLayers[i], 1249 &list->hwLayers[targetLayerIndex])) { 1250 return true; 1251 } 1252 } 1253 } 1254 return false; 1255} 1256 1257int MDPComp::getBatch(hwc_display_contents_1_t* list, 1258 int& maxBatchStart, int& maxBatchEnd, 1259 int& maxBatchCount) { 1260 int i = 0; 1261 int fbZOrder =-1; 1262 int droppedLayerCt = 0; 1263 while (i < mCurrentFrame.layerCount) { 1264 int batchCount = 0; 1265 int batchStart = i; 1266 int batchEnd = i; 1267 /* Adjust batch Z order with the dropped layers so far */ 1268 int fbZ = batchStart - droppedLayerCt; 1269 int firstZReverseIndex = -1; 1270 int updatingLayersAbove = 0;//Updating layer count in middle of batch 1271 while(i < mCurrentFrame.layerCount) { 1272 if(!mCurrentFrame.isFBComposed[i]) { 1273 if(!batchCount) { 1274 i++; 1275 break; 1276 } 1277 updatingLayersAbove++; 1278 i++; 1279 continue; 1280 } else { 1281 if(mCurrentFrame.drop[i]) { 1282 i++; 1283 droppedLayerCt++; 1284 continue; 1285 } else if(updatingLayersAbove <= 0) { 1286 batchCount++; 1287 batchEnd = i; 1288 i++; 1289 continue; 1290 } else { //Layer is FBComposed, not a drop & updatingLayer > 0 1291 1292 // We have a valid updating layer already. If layer-i not 1293 // have overlapping with all updating layers in between 1294 // batch-start and i, then we can add layer i to batch. 1295 if(!intersectingUpdatingLayers(list, batchStart, i-1, i)) { 1296 batchCount++; 1297 batchEnd = i; 1298 i++; 1299 continue; 1300 } else if(canPushBatchToTop(list, batchStart, i)) { 1301 //If All the non-updating layers with in this batch 1302 //does not have intersection with the updating layers 1303 //above in z-order, then we can safely move the batch to 1304 //higher z-order. Increment fbZ as it is moving up. 1305 if( firstZReverseIndex < 0) { 1306 firstZReverseIndex = i; 1307 } 1308 batchCount++; 1309 batchEnd = i; 1310 fbZ += updatingLayersAbove; 1311 i++; 1312 updatingLayersAbove = 0; 1313 continue; 1314 } else { 1315 //both failed.start the loop again from here. 1316 if(firstZReverseIndex >= 0) { 1317 i = firstZReverseIndex; 1318 } 1319 break; 1320 } 1321 } 1322 } 1323 } 1324 if(batchCount > maxBatchCount) { 1325 maxBatchCount = batchCount; 1326 maxBatchStart = batchStart; 1327 maxBatchEnd = batchEnd; 1328 fbZOrder = fbZ; 1329 } 1330 } 1331 return fbZOrder; 1332} 1333 1334bool MDPComp::markLayersForCaching(hwc_context_t* ctx, 1335 hwc_display_contents_1_t* list) { 1336 /* Idea is to keep as many non-updating(cached) layers in FB and 1337 * send rest of them through MDP. This is done in 2 steps. 1338 * 1. Find the maximum contiguous batch of non-updating layers. 1339 * 2. See if we can improve this batch size for caching by adding 1340 * opaque layers around the batch, if they don't have 1341 * any overlapping with the updating layers in between. 1342 * NEVER mark an updating layer for caching. 1343 * But cached ones can be marked for MDP */ 1344 1345 int maxBatchStart = -1; 1346 int maxBatchEnd = -1; 1347 int maxBatchCount = 0; 1348 int fbZ = -1; 1349 1350 /* Nothing is cached. No batching needed */ 1351 if(mCurrentFrame.fbCount == 0) { 1352 return true; 1353 } 1354 1355 /* No MDP comp layers, try to use other comp modes */ 1356 if(mCurrentFrame.mdpCount == 0) { 1357 return false; 1358 } 1359 1360 fbZ = getBatch(list, maxBatchStart, maxBatchEnd, maxBatchCount); 1361 1362 /* reset rest of the layers lying inside ROI for MDP comp */ 1363 for(int i = 0; i < mCurrentFrame.layerCount; i++) { 1364 hwc_layer_1_t* layer = &list->hwLayers[i]; 1365 if((i < maxBatchStart || i > maxBatchEnd) && 1366 mCurrentFrame.isFBComposed[i]){ 1367 if(!mCurrentFrame.drop[i]){ 1368 //If an unsupported layer is being attempted to 1369 //be pulled out we should fail 1370 if(not isSupportedForMDPComp(ctx, layer)) { 1371 return false; 1372 } 1373 mCurrentFrame.isFBComposed[i] = false; 1374 } 1375 } 1376 } 1377 1378 // update the frame data 1379 mCurrentFrame.fbZ = fbZ; 1380 mCurrentFrame.fbCount = maxBatchCount; 1381 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - 1382 mCurrentFrame.fbCount - mCurrentFrame.dropCount; 1383 1384 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__, 1385 mCurrentFrame.fbCount); 1386 1387 return true; 1388} 1389 1390void MDPComp::updateLayerCache(hwc_context_t* ctx, 1391 hwc_display_contents_1_t* list) { 1392 int numAppLayers = ctx->listStats[mDpy].numAppLayers; 1393 int fbCount = 0; 1394 1395 for(int i = 0; i < numAppLayers; i++) { 1396 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) { 1397 if(!mCurrentFrame.drop[i]) 1398 fbCount++; 1399 mCurrentFrame.isFBComposed[i] = true; 1400 } else { 1401 mCurrentFrame.isFBComposed[i] = false; 1402 } 1403 } 1404 1405 mCurrentFrame.fbCount = fbCount; 1406 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount 1407 - mCurrentFrame.dropCount; 1408 1409 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d drop count: %d" 1410 ,__FUNCTION__, mCurrentFrame.mdpCount, mCurrentFrame.fbCount, 1411 mCurrentFrame.dropCount); 1412} 1413 1414void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list, 1415 bool secureOnly) { 1416 int nYuvCount = ctx->listStats[mDpy].yuvCount; 1417 for(int index = 0;index < nYuvCount; index++){ 1418 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index]; 1419 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex]; 1420 1421 if(!isYUVDoable(ctx, layer)) { 1422 if(!mCurrentFrame.isFBComposed[nYuvIndex]) { 1423 mCurrentFrame.isFBComposed[nYuvIndex] = true; 1424 mCurrentFrame.fbCount++; 1425 } 1426 } else { 1427 if(mCurrentFrame.isFBComposed[nYuvIndex]) { 1428 private_handle_t *hnd = (private_handle_t *)layer->handle; 1429 if(!secureOnly || isSecureBuffer(hnd)) { 1430 mCurrentFrame.isFBComposed[nYuvIndex] = false; 1431 mCurrentFrame.fbCount--; 1432 } 1433 } 1434 } 1435 } 1436 1437 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - 1438 mCurrentFrame.fbCount - mCurrentFrame.dropCount; 1439 ALOGD_IF(isDebug(),"%s: fb count: %d",__FUNCTION__, 1440 mCurrentFrame.fbCount); 1441} 1442 1443hwc_rect_t MDPComp::getUpdatingFBRect(hwc_context_t *ctx, 1444 hwc_display_contents_1_t* list){ 1445 hwc_rect_t fbRect = (struct hwc_rect){0, 0, 0, 0}; 1446 1447 /* Update only the region of FB needed for composition */ 1448 for(int i = 0; i < mCurrentFrame.layerCount; i++ ) { 1449 if(mCurrentFrame.isFBComposed[i] && !mCurrentFrame.drop[i]) { 1450 hwc_layer_1_t* layer = &list->hwLayers[i]; 1451 hwc_rect_t dst = layer->displayFrame; 1452 fbRect = getUnion(fbRect, dst); 1453 } 1454 } 1455 trimAgainstROI(ctx, fbRect); 1456 return fbRect; 1457} 1458 1459bool MDPComp::postHeuristicsHandling(hwc_context_t *ctx, 1460 hwc_display_contents_1_t* list) { 1461 1462 //Capability checks 1463 if(!resourceCheck(ctx, list)) { 1464 ALOGD_IF(isDebug(), "%s: resource check failed", __FUNCTION__); 1465 return false; 1466 } 1467 1468 //Limitations checks 1469 if(!hwLimitationsCheck(ctx, list)) { 1470 ALOGD_IF(isDebug(), "%s: HW limitations",__FUNCTION__); 1471 return false; 1472 } 1473 1474 //Configure framebuffer first if applicable 1475 if(mCurrentFrame.fbZ >= 0) { 1476 hwc_rect_t fbRect = getUpdatingFBRect(ctx, list); 1477 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, fbRect, mCurrentFrame.fbZ)) 1478 { 1479 ALOGD_IF(isDebug(), "%s configure framebuffer failed", 1480 __FUNCTION__); 1481 return false; 1482 } 1483 } 1484 1485 mCurrentFrame.map(); 1486 1487 if(!allocLayerPipes(ctx, list)) { 1488 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__); 1489 return false; 1490 } 1491 1492 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount; 1493 index++) { 1494 if(!mCurrentFrame.isFBComposed[index]) { 1495 int mdpIndex = mCurrentFrame.layerToMDP[index]; 1496 hwc_layer_1_t* layer = &list->hwLayers[index]; 1497 1498 //Leave fbZ for framebuffer. CACHE/GLES layers go here. 1499 if(mdpNextZOrder == mCurrentFrame.fbZ) { 1500 mdpNextZOrder++; 1501 } 1502 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo; 1503 cur_pipe->zOrder = mdpNextZOrder++; 1504 1505 private_handle_t *hnd = (private_handle_t *)layer->handle; 1506 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){ 1507 if(configure4k2kYuv(ctx, layer, 1508 mCurrentFrame.mdpToLayer[mdpIndex]) 1509 != 0 ){ 1510 ALOGD_IF(isDebug(), "%s: Failed to configure split pipes \ 1511 for layer %d",__FUNCTION__, index); 1512 return false; 1513 } 1514 else{ 1515 mdpNextZOrder++; 1516 } 1517 continue; 1518 } 1519 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){ 1520 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \ 1521 layer %d",__FUNCTION__, index); 1522 return false; 1523 } 1524 } 1525 } 1526 1527 if(!ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd)) { 1528 ALOGD_IF(isDebug(), "%s: Failed to validate and set overlay for dpy %d" 1529 ,__FUNCTION__, mDpy); 1530 return false; 1531 } 1532 1533 setRedraw(ctx, list); 1534 return true; 1535} 1536 1537bool MDPComp::resourceCheck(hwc_context_t* ctx, 1538 hwc_display_contents_1_t* list) { 1539 const bool fbUsed = mCurrentFrame.fbCount; 1540 if(mCurrentFrame.mdpCount > sMaxPipesPerMixer - fbUsed) { 1541 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__); 1542 return false; 1543 } 1544 // Init rotCount to number of rotate sessions used by other displays 1545 int rotCount = ctx->mRotMgr->getNumActiveSessions(); 1546 // Count the number of rotator sessions required for current display 1547 for (int index = 0; index < mCurrentFrame.layerCount; index++) { 1548 if(!mCurrentFrame.isFBComposed[index]) { 1549 hwc_layer_1_t* layer = &list->hwLayers[index]; 1550 private_handle_t *hnd = (private_handle_t *)layer->handle; 1551 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) { 1552 rotCount++; 1553 } 1554 } 1555 } 1556 // if number of layers to rotate exceeds max rotator sessions, bail out. 1557 if(rotCount > RotMgr::MAX_ROT_SESS) { 1558 ALOGD_IF(isDebug(), "%s: Exceeds max rotator sessions %d", 1559 __FUNCTION__, mDpy); 1560 return false; 1561 } 1562 return true; 1563} 1564 1565bool MDPComp::hwLimitationsCheck(hwc_context_t* ctx, 1566 hwc_display_contents_1_t* list) { 1567 1568 //A-family hw limitation: 1569 //If a layer need alpha scaling, MDP can not support. 1570 if(ctx->mMDP.version < qdutils::MDSS_V5) { 1571 for(int i = 0; i < mCurrentFrame.layerCount; ++i) { 1572 if(!mCurrentFrame.isFBComposed[i] && 1573 isAlphaScaled( &list->hwLayers[i])) { 1574 ALOGD_IF(isDebug(), "%s:frame needs alphaScaling",__FUNCTION__); 1575 return false; 1576 } 1577 } 1578 } 1579 1580 // On 8x26 & 8974 hw, we have a limitation of downscaling+blending. 1581 //If multiple layers requires downscaling and also they are overlapping 1582 //fall back to GPU since MDSS can not handle it. 1583 if(qdutils::MDPVersion::getInstance().is8x74v2() || 1584 qdutils::MDPVersion::getInstance().is8x26()) { 1585 for(int i = 0; i < mCurrentFrame.layerCount-1; ++i) { 1586 hwc_layer_1_t* botLayer = &list->hwLayers[i]; 1587 if(!mCurrentFrame.isFBComposed[i] && 1588 isDownscaleRequired(botLayer)) { 1589 //if layer-i is marked for MDP and needs downscaling 1590 //check if any MDP layer on top of i & overlaps with layer-i 1591 for(int j = i+1; j < mCurrentFrame.layerCount; ++j) { 1592 hwc_layer_1_t* topLayer = &list->hwLayers[j]; 1593 if(!mCurrentFrame.isFBComposed[j] && 1594 isDownscaleRequired(topLayer)) { 1595 hwc_rect_t r = getIntersection(botLayer->displayFrame, 1596 topLayer->displayFrame); 1597 if(isValidRect(r)) 1598 return false; 1599 } 1600 } 1601 } 1602 } 1603 } 1604 return true; 1605} 1606 1607int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 1608 int ret = 0; 1609 char property[PROPERTY_VALUE_MAX]; 1610 1611 if(!ctx || !list) { 1612 ALOGE("%s: Invalid context or list",__FUNCTION__); 1613 mCachedFrame.reset(); 1614 return -1; 1615 } 1616 1617 const int numLayers = ctx->listStats[mDpy].numAppLayers; 1618 1619 if(property_get("debug.hwc.simulate", property, NULL) > 0) { 1620 int currentFlags = atoi(property); 1621 if(currentFlags != sSimulationFlags) { 1622 sSimulationFlags = currentFlags; 1623 ALOGE("%s: Simulation Flag read: 0x%x (%d)", __FUNCTION__, 1624 sSimulationFlags, sSimulationFlags); 1625 } 1626 } 1627 // reset PTOR 1628 if(!mDpy) 1629 memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo)); 1630 1631 //Do not cache the information for next draw cycle. 1632 if(numLayers > MAX_NUM_APP_LAYERS or (!numLayers)) { 1633 ALOGI("%s: Unsupported layer count for mdp composition", 1634 __FUNCTION__); 1635 mCachedFrame.reset(); 1636 return -1; 1637 } 1638 1639 //reset old data 1640 mCurrentFrame.reset(numLayers); 1641 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop)); 1642 mCurrentFrame.dropCount = 0; 1643 1644 // Detect the start of animation and fall back to GPU only once to cache 1645 // all the layers in FB and display FB content untill animation completes. 1646 if(ctx->listStats[mDpy].isDisplayAnimating) { 1647 mCurrentFrame.needsRedraw = false; 1648 if(ctx->mAnimationState[mDpy] == ANIMATION_STOPPED) { 1649 mCurrentFrame.needsRedraw = true; 1650 ctx->mAnimationState[mDpy] = ANIMATION_STARTED; 1651 } 1652 setMDPCompLayerFlags(ctx, list); 1653 mCachedFrame.updateCounts(mCurrentFrame); 1654 ret = -1; 1655 return ret; 1656 } else { 1657 ctx->mAnimationState[mDpy] = ANIMATION_STOPPED; 1658 } 1659 1660 //Hard conditions, if not met, cannot do MDP comp 1661 if(isFrameDoable(ctx)) { 1662 generateROI(ctx, list); 1663 1664 mModeOn = tryFullFrame(ctx, list) || tryVideoOnly(ctx, list); 1665 if(mModeOn) { 1666 setMDPCompLayerFlags(ctx, list); 1667 } else { 1668 resetROI(ctx, mDpy); 1669 reset(ctx); 1670 memset(&mCurrentFrame.drop, 0, sizeof(mCurrentFrame.drop)); 1671 mCurrentFrame.dropCount = 0; 1672 ret = -1; 1673 } 1674 } else { 1675 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame", 1676 __FUNCTION__); 1677 ret = -1; 1678 } 1679 1680 if(isDebug()) { 1681 ALOGD("GEOMETRY change: %d", 1682 (list->flags & HWC_GEOMETRY_CHANGED)); 1683 android::String8 sDump(""); 1684 dump(sDump, ctx); 1685 ALOGD("%s",sDump.string()); 1686 } 1687 1688 mCachedFrame.cacheAll(list); 1689 mCachedFrame.updateCounts(mCurrentFrame); 1690 return ret; 1691} 1692 1693bool MDPComp::allocSplitVGPipesfor4k2k(hwc_context_t *ctx, int index) { 1694 1695 bool bRet = true; 1696 int mdpIndex = mCurrentFrame.layerToMDP[index]; 1697 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex]; 1698 info.pipeInfo = new MdpYUVPipeInfo; 1699 info.rot = NULL; 1700 MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo; 1701 1702 pipe_info.lIndex = ovutils::OV_INVALID; 1703 pipe_info.rIndex = ovutils::OV_INVALID; 1704 1705 Overlay::PipeSpecs pipeSpecs; 1706 pipeSpecs.formatClass = Overlay::FORMAT_YUV; 1707 pipeSpecs.needsScaling = true; 1708 pipeSpecs.dpy = mDpy; 1709 pipeSpecs.fb = false; 1710 1711 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs); 1712 if(pipe_info.lIndex == ovutils::OV_INVALID){ 1713 bRet = false; 1714 ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed", 1715 __FUNCTION__); 1716 } 1717 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs); 1718 if(pipe_info.rIndex == ovutils::OV_INVALID){ 1719 bRet = false; 1720 ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed", 1721 __FUNCTION__); 1722 } 1723 return bRet; 1724} 1725 1726int MDPComp::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 1727 int fd = -1; 1728 if (ctx->mPtorInfo.isActive()) { 1729 fd = ctx->mCopyBit[mDpy]->drawOverlap(ctx, list); 1730 if (fd < 0) { 1731 ALOGD_IF(isDebug(),"%s: failed", __FUNCTION__); 1732 } 1733 } 1734 return fd; 1735} 1736//=============MDPCompNonSplit================================================== 1737 1738void MDPCompNonSplit::adjustForSourceSplit(hwc_context_t *ctx, 1739 hwc_display_contents_1_t* list) { 1740 //If 4k2k Yuv layer split is possible, and if 1741 //fbz is above 4k2k layer, increment fb zorder by 1 1742 //as we split 4k2k layer and increment zorder for right half 1743 //of the layer 1744 if(!ctx) 1745 return; 1746 if(mCurrentFrame.fbZ >= 0) { 1747 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount; 1748 index++) { 1749 if(!mCurrentFrame.isFBComposed[index]) { 1750 if(mdpNextZOrder == mCurrentFrame.fbZ) { 1751 mdpNextZOrder++; 1752 } 1753 mdpNextZOrder++; 1754 hwc_layer_1_t* layer = &list->hwLayers[index]; 1755 private_handle_t *hnd = (private_handle_t *)layer->handle; 1756 if(is4kx2kYuvBuffer(hnd)) { 1757 if(mdpNextZOrder <= mCurrentFrame.fbZ) 1758 mCurrentFrame.fbZ += 1; 1759 mdpNextZOrder++; 1760 //As we split 4kx2k yuv layer and program to 2 VG pipes 1761 //(if available) increase mdpcount by 1. 1762 mCurrentFrame.mdpCount++; 1763 } 1764 } 1765 } 1766 } 1767} 1768 1769/* 1770 * Configures pipe(s) for MDP composition 1771 */ 1772int MDPCompNonSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer, 1773 PipeLayerPair& PipeLayerPair) { 1774 MdpPipeInfoNonSplit& mdp_info = 1775 *(static_cast<MdpPipeInfoNonSplit*>(PipeLayerPair.pipeInfo)); 1776 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION; 1777 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder); 1778 eIsFg isFg = IS_FG_OFF; 1779 eDest dest = mdp_info.index; 1780 1781 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d", 1782 __FUNCTION__, layer, zOrder, dest); 1783 1784 return configureNonSplit(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest, 1785 &PipeLayerPair.rot); 1786} 1787 1788bool MDPCompNonSplit::allocLayerPipes(hwc_context_t *ctx, 1789 hwc_display_contents_1_t* list) { 1790 for(int index = 0; index < mCurrentFrame.layerCount; index++) { 1791 1792 if(mCurrentFrame.isFBComposed[index]) continue; 1793 1794 hwc_layer_1_t* layer = &list->hwLayers[index]; 1795 private_handle_t *hnd = (private_handle_t *)layer->handle; 1796 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){ 1797 if(allocSplitVGPipesfor4k2k(ctx, index)){ 1798 continue; 1799 } 1800 } 1801 1802 int mdpIndex = mCurrentFrame.layerToMDP[index]; 1803 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex]; 1804 info.pipeInfo = new MdpPipeInfoNonSplit; 1805 info.rot = NULL; 1806 MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo; 1807 1808 Overlay::PipeSpecs pipeSpecs; 1809 pipeSpecs.formatClass = isYuvBuffer(hnd) ? 1810 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB; 1811 pipeSpecs.needsScaling = qhwc::needsScaling(layer) or 1812 (qdutils::MDPVersion::getInstance().is8x26() and 1813 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024); 1814 pipeSpecs.dpy = mDpy; 1815 pipeSpecs.fb = false; 1816 pipeSpecs.numActiveDisplays = ctx->numActiveDisplays; 1817 1818 pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs); 1819 1820 if(pipe_info.index == ovutils::OV_INVALID) { 1821 ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__); 1822 return false; 1823 } 1824 } 1825 return true; 1826} 1827 1828int MDPCompNonSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer, 1829 PipeLayerPair& PipeLayerPair) { 1830 MdpYUVPipeInfo& mdp_info = 1831 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo)); 1832 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder); 1833 eIsFg isFg = IS_FG_OFF; 1834 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION; 1835 eDest lDest = mdp_info.lIndex; 1836 eDest rDest = mdp_info.rIndex; 1837 1838 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, 1839 lDest, rDest, &PipeLayerPair.rot); 1840} 1841 1842bool MDPCompNonSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 1843 1844 if(!isEnabled() or !mModeOn) { 1845 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__); 1846 return true; 1847 } 1848 1849 // Set the Handle timeout to true for MDP or MIXED composition. 1850 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) { 1851 sHandleTimeout = true; 1852 } 1853 1854 overlay::Overlay& ov = *ctx->mOverlay; 1855 LayerProp *layerProp = ctx->layerProp[mDpy]; 1856 1857 int numHwLayers = ctx->listStats[mDpy].numAppLayers; 1858 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ ) 1859 { 1860 if(mCurrentFrame.isFBComposed[i]) continue; 1861 1862 hwc_layer_1_t *layer = &list->hwLayers[i]; 1863 private_handle_t *hnd = (private_handle_t *)layer->handle; 1864 if(!hnd) { 1865 if (!(layer->flags & HWC_COLOR_FILL)) { 1866 ALOGE("%s handle null", __FUNCTION__); 1867 return false; 1868 } 1869 // No PLAY for Color layer 1870 layerProp[i].mFlags &= ~HWC_MDPCOMP; 1871 continue; 1872 } 1873 1874 int mdpIndex = mCurrentFrame.layerToMDP[i]; 1875 1876 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit) 1877 { 1878 MdpYUVPipeInfo& pipe_info = 1879 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo; 1880 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot; 1881 ovutils::eDest indexL = pipe_info.lIndex; 1882 ovutils::eDest indexR = pipe_info.rIndex; 1883 int fd = hnd->fd; 1884 uint32_t offset = (uint32_t)hnd->offset; 1885 if(rot) { 1886 rot->queueBuffer(fd, offset); 1887 fd = rot->getDstMemId(); 1888 offset = rot->getDstOffset(); 1889 } 1890 if(indexL != ovutils::OV_INVALID) { 1891 ovutils::eDest destL = (ovutils::eDest)indexL; 1892 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \ 1893 using pipe: %d", __FUNCTION__, layer, hnd, indexL ); 1894 if (!ov.queueBuffer(fd, offset, destL)) { 1895 ALOGE("%s: queueBuffer failed for display:%d", 1896 __FUNCTION__, mDpy); 1897 return false; 1898 } 1899 } 1900 1901 if(indexR != ovutils::OV_INVALID) { 1902 ovutils::eDest destR = (ovutils::eDest)indexR; 1903 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \ 1904 using pipe: %d", __FUNCTION__, layer, hnd, indexR ); 1905 if (!ov.queueBuffer(fd, offset, destR)) { 1906 ALOGE("%s: queueBuffer failed for display:%d", 1907 __FUNCTION__, mDpy); 1908 return false; 1909 } 1910 } 1911 } 1912 else{ 1913 MdpPipeInfoNonSplit& pipe_info = 1914 *(MdpPipeInfoNonSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo; 1915 ovutils::eDest dest = pipe_info.index; 1916 if(dest == ovutils::OV_INVALID) { 1917 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest); 1918 return false; 1919 } 1920 1921 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) { 1922 continue; 1923 } 1924 1925 int fd = hnd->fd; 1926 uint32_t offset = (uint32_t)hnd->offset; 1927 int index = ctx->mPtorInfo.getPTORArrayIndex(i); 1928 if (!mDpy && (index != -1)) { 1929 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer(); 1930 fd = hnd->fd; 1931 // Use the offset of the RenderBuffer 1932 offset = ctx->mPtorInfo.mRenderBuffOffset[index]; 1933 } 1934 1935 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \ 1936 using pipe: %d", __FUNCTION__, layer, 1937 hnd, dest ); 1938 1939 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot; 1940 if(rot) { 1941 if(!rot->queueBuffer(fd, offset)) 1942 return false; 1943 fd = rot->getDstMemId(); 1944 offset = rot->getDstOffset(); 1945 } 1946 1947 if (!ov.queueBuffer(fd, offset, dest)) { 1948 ALOGE("%s: queueBuffer failed for display:%d ", 1949 __FUNCTION__, mDpy); 1950 return false; 1951 } 1952 } 1953 1954 layerProp[i].mFlags &= ~HWC_MDPCOMP; 1955 } 1956 return true; 1957} 1958 1959//=============MDPCompSplit=================================================== 1960 1961void MDPCompSplit::adjustForSourceSplit(hwc_context_t *ctx, 1962 hwc_display_contents_1_t* list){ 1963 //if 4kx2k yuv layer is totally present in either in left half 1964 //or right half then try splitting the yuv layer to avoid decimation 1965 const int lSplit = getLeftSplit(ctx, mDpy); 1966 if(mCurrentFrame.fbZ >= 0) { 1967 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount; 1968 index++) { 1969 if(!mCurrentFrame.isFBComposed[index]) { 1970 if(mdpNextZOrder == mCurrentFrame.fbZ) { 1971 mdpNextZOrder++; 1972 } 1973 mdpNextZOrder++; 1974 hwc_layer_1_t* layer = &list->hwLayers[index]; 1975 private_handle_t *hnd = (private_handle_t *)layer->handle; 1976 if(is4kx2kYuvBuffer(hnd)) { 1977 hwc_rect_t dst = layer->displayFrame; 1978 if((dst.left > lSplit) || (dst.right < lSplit)) { 1979 mCurrentFrame.mdpCount += 1; 1980 } 1981 if(mdpNextZOrder <= mCurrentFrame.fbZ) 1982 mCurrentFrame.fbZ += 1; 1983 mdpNextZOrder++; 1984 } 1985 } 1986 } 1987 } 1988} 1989 1990bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer, 1991 MdpPipeInfoSplit& pipe_info) { 1992 1993 const int lSplit = getLeftSplit(ctx, mDpy); 1994 private_handle_t *hnd = (private_handle_t *)layer->handle; 1995 hwc_rect_t dst = layer->displayFrame; 1996 pipe_info.lIndex = ovutils::OV_INVALID; 1997 pipe_info.rIndex = ovutils::OV_INVALID; 1998 1999 Overlay::PipeSpecs pipeSpecs; 2000 pipeSpecs.formatClass = isYuvBuffer(hnd) ? 2001 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB; 2002 pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy); 2003 pipeSpecs.dpy = mDpy; 2004 pipeSpecs.mixer = Overlay::MIXER_LEFT; 2005 pipeSpecs.fb = false; 2006 2007 // Acquire pipe only for the updating half 2008 hwc_rect_t l_roi = ctx->listStats[mDpy].lRoi; 2009 hwc_rect_t r_roi = ctx->listStats[mDpy].rRoi; 2010 2011 if (dst.left < lSplit && isValidRect(getIntersection(dst, l_roi))) { 2012 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs); 2013 if(pipe_info.lIndex == ovutils::OV_INVALID) 2014 return false; 2015 } 2016 2017 if(dst.right > lSplit && isValidRect(getIntersection(dst, r_roi))) { 2018 pipeSpecs.mixer = Overlay::MIXER_RIGHT; 2019 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs); 2020 if(pipe_info.rIndex == ovutils::OV_INVALID) 2021 return false; 2022 } 2023 2024 return true; 2025} 2026 2027bool MDPCompSplit::allocLayerPipes(hwc_context_t *ctx, 2028 hwc_display_contents_1_t* list) { 2029 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) { 2030 2031 if(mCurrentFrame.isFBComposed[index]) continue; 2032 2033 hwc_layer_1_t* layer = &list->hwLayers[index]; 2034 private_handle_t *hnd = (private_handle_t *)layer->handle; 2035 hwc_rect_t dst = layer->displayFrame; 2036 const int lSplit = getLeftSplit(ctx, mDpy); 2037 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit){ 2038 if((dst.left > lSplit)||(dst.right < lSplit)){ 2039 if(allocSplitVGPipesfor4k2k(ctx, index)){ 2040 continue; 2041 } 2042 } 2043 } 2044 int mdpIndex = mCurrentFrame.layerToMDP[index]; 2045 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex]; 2046 info.pipeInfo = new MdpPipeInfoSplit; 2047 info.rot = NULL; 2048 MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo; 2049 2050 if(!acquireMDPPipes(ctx, layer, pipe_info)) { 2051 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type", 2052 __FUNCTION__); 2053 return false; 2054 } 2055 } 2056 return true; 2057} 2058 2059int MDPCompSplit::configure4k2kYuv(hwc_context_t *ctx, hwc_layer_1_t *layer, 2060 PipeLayerPair& PipeLayerPair) { 2061 const int lSplit = getLeftSplit(ctx, mDpy); 2062 hwc_rect_t dst = layer->displayFrame; 2063 if((dst.left > lSplit)||(dst.right < lSplit)){ 2064 MdpYUVPipeInfo& mdp_info = 2065 *(static_cast<MdpYUVPipeInfo*>(PipeLayerPair.pipeInfo)); 2066 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder); 2067 eIsFg isFg = IS_FG_OFF; 2068 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION; 2069 eDest lDest = mdp_info.lIndex; 2070 eDest rDest = mdp_info.rIndex; 2071 2072 return configureSourceSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, 2073 lDest, rDest, &PipeLayerPair.rot); 2074 } 2075 else{ 2076 return configure(ctx, layer, PipeLayerPair); 2077 } 2078} 2079 2080/* 2081 * Configures pipe(s) for MDP composition 2082 */ 2083int MDPCompSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer, 2084 PipeLayerPair& PipeLayerPair) { 2085 MdpPipeInfoSplit& mdp_info = 2086 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo)); 2087 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder); 2088 eIsFg isFg = IS_FG_OFF; 2089 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION; 2090 eDest lDest = mdp_info.lIndex; 2091 eDest rDest = mdp_info.rIndex; 2092 2093 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d" 2094 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest); 2095 2096 return configureSplit(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest, 2097 rDest, &PipeLayerPair.rot); 2098} 2099 2100bool MDPCompSplit::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 2101 2102 if(!isEnabled() or !mModeOn) { 2103 ALOGD_IF(isDebug(),"%s: MDP Comp not enabled/configured", __FUNCTION__); 2104 return true; 2105 } 2106 2107 // Set the Handle timeout to true for MDP or MIXED composition. 2108 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) { 2109 sHandleTimeout = true; 2110 } 2111 2112 overlay::Overlay& ov = *ctx->mOverlay; 2113 LayerProp *layerProp = ctx->layerProp[mDpy]; 2114 2115 int numHwLayers = ctx->listStats[mDpy].numAppLayers; 2116 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ ) 2117 { 2118 if(mCurrentFrame.isFBComposed[i]) continue; 2119 2120 hwc_layer_1_t *layer = &list->hwLayers[i]; 2121 private_handle_t *hnd = (private_handle_t *)layer->handle; 2122 if(!hnd) { 2123 ALOGE("%s handle null", __FUNCTION__); 2124 return false; 2125 } 2126 2127 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) { 2128 continue; 2129 } 2130 2131 int mdpIndex = mCurrentFrame.layerToMDP[i]; 2132 2133 if(is4kx2kYuvBuffer(hnd) && sEnable4k2kYUVSplit) 2134 { 2135 MdpYUVPipeInfo& pipe_info = 2136 *(MdpYUVPipeInfo*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo; 2137 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot; 2138 ovutils::eDest indexL = pipe_info.lIndex; 2139 ovutils::eDest indexR = pipe_info.rIndex; 2140 int fd = hnd->fd; 2141 uint32_t offset = (uint32_t)hnd->offset; 2142 if(rot) { 2143 rot->queueBuffer(fd, offset); 2144 fd = rot->getDstMemId(); 2145 offset = rot->getDstOffset(); 2146 } 2147 if(indexL != ovutils::OV_INVALID) { 2148 ovutils::eDest destL = (ovutils::eDest)indexL; 2149 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \ 2150 using pipe: %d", __FUNCTION__, layer, hnd, indexL ); 2151 if (!ov.queueBuffer(fd, offset, destL)) { 2152 ALOGE("%s: queueBuffer failed for display:%d", 2153 __FUNCTION__, mDpy); 2154 return false; 2155 } 2156 } 2157 2158 if(indexR != ovutils::OV_INVALID) { 2159 ovutils::eDest destR = (ovutils::eDest)indexR; 2160 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \ 2161 using pipe: %d", __FUNCTION__, layer, hnd, indexR ); 2162 if (!ov.queueBuffer(fd, offset, destR)) { 2163 ALOGE("%s: queueBuffer failed for display:%d", 2164 __FUNCTION__, mDpy); 2165 return false; 2166 } 2167 } 2168 } 2169 else{ 2170 MdpPipeInfoSplit& pipe_info = 2171 *(MdpPipeInfoSplit*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo; 2172 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot; 2173 2174 ovutils::eDest indexL = pipe_info.lIndex; 2175 ovutils::eDest indexR = pipe_info.rIndex; 2176 2177 int fd = hnd->fd; 2178 uint32_t offset = (uint32_t)hnd->offset; 2179 int index = ctx->mPtorInfo.getPTORArrayIndex(i); 2180 if (!mDpy && (index != -1)) { 2181 hnd = ctx->mCopyBit[mDpy]->getCurrentRenderBuffer(); 2182 fd = hnd->fd; 2183 offset = ctx->mPtorInfo.mRenderBuffOffset[index]; 2184 } 2185 2186 if(ctx->mAD->draw(ctx, fd, offset)) { 2187 fd = ctx->mAD->getDstFd(); 2188 offset = ctx->mAD->getDstOffset(); 2189 } 2190 2191 if(rot) { 2192 rot->queueBuffer(fd, offset); 2193 fd = rot->getDstMemId(); 2194 offset = rot->getDstOffset(); 2195 } 2196 2197 //************* play left mixer ********** 2198 if(indexL != ovutils::OV_INVALID) { 2199 ovutils::eDest destL = (ovutils::eDest)indexL; 2200 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \ 2201 using pipe: %d", __FUNCTION__, layer, hnd, indexL ); 2202 if (!ov.queueBuffer(fd, offset, destL)) { 2203 ALOGE("%s: queueBuffer failed for left mixer", 2204 __FUNCTION__); 2205 return false; 2206 } 2207 } 2208 2209 //************* play right mixer ********** 2210 if(indexR != ovutils::OV_INVALID) { 2211 ovutils::eDest destR = (ovutils::eDest)indexR; 2212 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \ 2213 using pipe: %d", __FUNCTION__, layer, hnd, indexR ); 2214 if (!ov.queueBuffer(fd, offset, destR)) { 2215 ALOGE("%s: queueBuffer failed for right mixer", 2216 __FUNCTION__); 2217 return false; 2218 } 2219 } 2220 } 2221 2222 layerProp[i].mFlags &= ~HWC_MDPCOMP; 2223 } 2224 2225 return true; 2226} 2227 2228//================MDPCompSrcSplit============================================== 2229bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer, 2230 MdpPipeInfoSplit& pipe_info) { 2231 private_handle_t *hnd = (private_handle_t *)layer->handle; 2232 hwc_rect_t dst = layer->displayFrame; 2233 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf); 2234 pipe_info.lIndex = ovutils::OV_INVALID; 2235 pipe_info.rIndex = ovutils::OV_INVALID; 2236 2237 //If 2 pipes are staged on a single stage of a mixer, then the left pipe 2238 //should have a higher priority than the right one. Pipe priorities are 2239 //starting with VG0, VG1 ... , RGB0 ..., DMA1 2240 2241 Overlay::PipeSpecs pipeSpecs; 2242 pipeSpecs.formatClass = isYuvBuffer(hnd) ? 2243 Overlay::FORMAT_YUV : Overlay::FORMAT_RGB; 2244 pipeSpecs.needsScaling = qhwc::needsScaling(layer); 2245 pipeSpecs.dpy = mDpy; 2246 pipeSpecs.fb = false; 2247 2248 //1 pipe by default for a layer 2249 pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs); 2250 if(pipe_info.lIndex == ovutils::OV_INVALID) { 2251 return false; 2252 } 2253 2254 /* Use 2 pipes IF 2255 a) Layer's crop width is > 2048 or 2256 b) Layer's dest width > 2048 or 2257 c) On primary, driver has indicated with caps to split always. This is 2258 based on an empirically derived value of panel height. Applied only 2259 if the layer's width is > mixer's width 2260 */ 2261 2262 bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and 2263 qdutils::MDPVersion::getInstance().isSrcSplitAlways(); 2264 int lSplit = getLeftSplit(ctx, mDpy); 2265 int dstWidth = dst.right - dst.left; 2266 int cropWidth = crop.right - crop.left; 2267 2268 if(dstWidth > qdutils::MAX_DISPLAY_DIM or 2269 cropWidth > qdutils::MAX_DISPLAY_DIM or 2270 (primarySplitAlways and (cropWidth > lSplit))) { 2271 pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs); 2272 if(pipe_info.rIndex == ovutils::OV_INVALID) { 2273 return false; 2274 } 2275 2276 // Return values 2277 // 1 Left pipe is higher priority, do nothing. 2278 // 0 Pipes of same priority. 2279 //-1 Right pipe is of higher priority, needs swap. 2280 if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex, 2281 pipe_info.rIndex) == -1) { 2282 qhwc::swap(pipe_info.lIndex, pipe_info.rIndex); 2283 } 2284 } 2285 2286 return true; 2287} 2288 2289int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer, 2290 PipeLayerPair& PipeLayerPair) { 2291 private_handle_t *hnd = (private_handle_t *)layer->handle; 2292 if(!hnd) { 2293 ALOGE("%s: layer handle is NULL", __FUNCTION__); 2294 return -1; 2295 } 2296 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata; 2297 MdpPipeInfoSplit& mdp_info = 2298 *(static_cast<MdpPipeInfoSplit*>(PipeLayerPair.pipeInfo)); 2299 Rotator **rot = &PipeLayerPair.rot; 2300 eZorder z = static_cast<eZorder>(mdp_info.zOrder); 2301 eIsFg isFg = IS_FG_OFF; 2302 eDest lDest = mdp_info.lIndex; 2303 eDest rDest = mdp_info.rIndex; 2304 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf); 2305 hwc_rect_t dst = layer->displayFrame; 2306 int transform = layer->transform; 2307 eTransform orient = static_cast<eTransform>(transform); 2308 const int downscale = 0; 2309 int rotFlags = ROT_FLAGS_NONE; 2310 uint32_t format = ovutils::getMdpFormat(hnd->format, isTileRendered(hnd)); 2311 Whf whf(getWidth(hnd), getHeight(hnd), format, hnd->size); 2312 2313 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d" 2314 "dest_pipeR: %d",__FUNCTION__, layer, z, lDest, rDest); 2315 2316 // Handle R/B swap 2317 if (layer->flags & HWC_FORMAT_RB_SWAP) { 2318 if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888) 2319 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888); 2320 else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888) 2321 whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888); 2322 } 2323 2324 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION; 2325 setMdpFlags(ctx, layer, mdpFlags, 0, transform); 2326 2327 if(lDest != OV_INVALID && rDest != OV_INVALID) { 2328 //Enable overfetch 2329 setMdpFlags(mdpFlags, OV_MDSS_MDP_DUAL_PIPE); 2330 } 2331 2332 if(has90Transform(layer) && isRotationDoable(ctx, hnd)) { 2333 (*rot) = ctx->mRotMgr->getNext(); 2334 if((*rot) == NULL) return -1; 2335 ctx->mLayerRotMap[mDpy]->add(layer, *rot); 2336 //If the video is using a single pipe, enable BWC 2337 if(rDest == OV_INVALID) { 2338 BwcPM::setBwc(crop, dst, transform, mdpFlags); 2339 } 2340 //Configure rotator for pre-rotation 2341 if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) { 2342 ALOGE("%s: configRotator failed!", __FUNCTION__); 2343 return -1; 2344 } 2345 updateSource(orient, whf, crop, *rot); 2346 rotFlags |= ROT_PREROTATED; 2347 } 2348 2349 //If 2 pipes being used, divide layer into half, crop and dst 2350 hwc_rect_t cropL = crop; 2351 hwc_rect_t cropR = crop; 2352 hwc_rect_t dstL = dst; 2353 hwc_rect_t dstR = dst; 2354 if(lDest != OV_INVALID && rDest != OV_INVALID) { 2355 cropL.right = (crop.right + crop.left) / 2; 2356 cropR.left = cropL.right; 2357 sanitizeSourceCrop(cropL, cropR, hnd); 2358 2359 //Swap crops on H flip since 2 pipes are being used 2360 if((orient & OVERLAY_TRANSFORM_FLIP_H) && (*rot) == NULL) { 2361 hwc_rect_t tmp = cropL; 2362 cropL = cropR; 2363 cropR = tmp; 2364 } 2365 2366 dstL.right = (dst.right + dst.left) / 2; 2367 dstR.left = dstL.right; 2368 } 2369 2370 //For the mdp, since either we are pre-rotating or MDP does flips 2371 orient = OVERLAY_TRANSFORM_0; 2372 transform = 0; 2373 2374 //configure left pipe 2375 if(lDest != OV_INVALID) { 2376 PipeArgs pargL(mdpFlags, whf, z, isFg, 2377 static_cast<eRotFlags>(rotFlags), layer->planeAlpha, 2378 (ovutils::eBlending) getBlending(layer->blending)); 2379 2380 if(configMdp(ctx->mOverlay, pargL, orient, 2381 cropL, dstL, metadata, lDest) < 0) { 2382 ALOGE("%s: commit failed for left mixer config", __FUNCTION__); 2383 return -1; 2384 } 2385 } 2386 2387 //configure right pipe 2388 if(rDest != OV_INVALID) { 2389 PipeArgs pargR(mdpFlags, whf, z, isFg, 2390 static_cast<eRotFlags>(rotFlags), 2391 layer->planeAlpha, 2392 (ovutils::eBlending) getBlending(layer->blending)); 2393 if(configMdp(ctx->mOverlay, pargR, orient, 2394 cropR, dstR, metadata, rDest) < 0) { 2395 ALOGE("%s: commit failed for right mixer config", __FUNCTION__); 2396 return -1; 2397 } 2398 } 2399 2400 return 0; 2401} 2402 2403}; //namespace 2404 2405