1 /* 2 * Copyright (C) 2012-2013, 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 "qdMetaData.h" 23 #include "mdp_version.h" 24 #include "hwc_fbupdate.h" 25 #include "hwc_ad.h" 26 #include <overlayRotator.h> 27 28 using namespace overlay; 29 using namespace qdutils; 30 using namespace overlay::utils; 31 namespace ovutils = overlay::utils; 32 33 namespace qhwc { 34 35 //==============MDPComp======================================================== 36 37 IdleInvalidator *MDPComp::idleInvalidator = NULL; 38 bool MDPComp::sIdleFallBack = false; 39 bool MDPComp::sDebugLogs = false; 40 bool MDPComp::sEnabled = false; 41 bool MDPComp::sEnableMixedMode = true; 42 int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER; 43 44 MDPComp* MDPComp::getObject(const int& width, const int& rightSplit, 45 const int& dpy) { 46 if(width > MAX_DISPLAY_DIM || rightSplit) { 47 return new MDPCompHighRes(dpy); 48 } 49 return new MDPCompLowRes(dpy); 50 } 51 52 MDPComp::MDPComp(int dpy):mDpy(dpy){}; 53 54 void MDPComp::dump(android::String8& buf) 55 { 56 if(mCurrentFrame.layerCount > MAX_NUM_APP_LAYERS) 57 return; 58 59 dumpsys_log(buf,"HWC Map for Dpy: %s \n", 60 (mDpy == 0) ? "\"PRIMARY\"" : 61 (mDpy == 1) ? "\"EXTERNAL\"" : "\"VIRTUAL\""); 62 dumpsys_log(buf,"CURR_FRAME: layerCount:%2d mdpCount:%2d " 63 "fbCount:%2d \n", mCurrentFrame.layerCount, 64 mCurrentFrame.mdpCount, mCurrentFrame.fbCount); 65 dumpsys_log(buf,"needsFBRedraw:%3s pipesUsed:%2d MaxPipesPerMixer: %d \n", 66 (mCurrentFrame.needsRedraw? "YES" : "NO"), 67 mCurrentFrame.mdpCount, sMaxPipesPerMixer); 68 dumpsys_log(buf," --------------------------------------------- \n"); 69 dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype | Z \n"); 70 dumpsys_log(buf," --------------------------------------------- \n"); 71 for(int index = 0; index < mCurrentFrame.layerCount; index++ ) 72 dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n", 73 index, 74 (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"), 75 mCurrentFrame.layerToMDP[index], 76 (mCurrentFrame.isFBComposed[index] ? 77 (mCurrentFrame.needsRedraw ? "GLES" : "CACHE") : "MDP"), 78 (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ : 79 mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder)); 80 dumpsys_log(buf,"\n"); 81 } 82 83 bool MDPComp::init(hwc_context_t *ctx) { 84 85 if(!ctx) { 86 ALOGE("%s: Invalid hwc context!!",__FUNCTION__); 87 return false; 88 } 89 90 char property[PROPERTY_VALUE_MAX]; 91 92 sEnabled = false; 93 if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) && 94 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) || 95 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) { 96 sEnabled = true; 97 } 98 99 sEnableMixedMode = true; 100 if((property_get("debug.mdpcomp.mixedmode.disable", property, NULL) > 0) && 101 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) || 102 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) { 103 sEnableMixedMode = false; 104 } 105 106 sDebugLogs = false; 107 if(property_get("debug.mdpcomp.logs", property, NULL) > 0) { 108 if(atoi(property) != 0) 109 sDebugLogs = true; 110 } 111 112 sMaxPipesPerMixer = MAX_PIPES_PER_MIXER; 113 if(property_get("debug.mdpcomp.maxpermixer", property, "-1") > 0) { 114 int val = atoi(property); 115 if(val >= 0) 116 sMaxPipesPerMixer = min(val, MAX_PIPES_PER_MIXER); 117 } 118 119 if(ctx->mMDP.panel != MIPI_CMD_PANEL) { 120 // Idle invalidation is not necessary on command mode panels 121 long idle_timeout = DEFAULT_IDLE_TIME; 122 if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) { 123 if(atoi(property) != 0) 124 idle_timeout = atoi(property); 125 } 126 127 //create Idle Invalidator only when not disabled through property 128 if(idle_timeout != -1) 129 idleInvalidator = IdleInvalidator::getInstance(); 130 131 if(idleInvalidator == NULL) { 132 ALOGE("%s: failed to instantiate idleInvalidator object", 133 __FUNCTION__); 134 } else { 135 idleInvalidator->init(timeout_handler, ctx, idle_timeout); 136 } 137 } 138 return true; 139 } 140 141 void MDPComp::reset(const int& numLayers, hwc_display_contents_1_t* list) { 142 mCurrentFrame.reset(numLayers); 143 mCachedFrame.cacheAll(list); 144 mCachedFrame.updateCounts(mCurrentFrame); 145 } 146 147 void MDPComp::timeout_handler(void *udata) { 148 struct hwc_context_t* ctx = (struct hwc_context_t*)(udata); 149 150 if(!ctx) { 151 ALOGE("%s: received empty data in timer callback", __FUNCTION__); 152 return; 153 } 154 155 if(!ctx->proc) { 156 ALOGE("%s: HWC proc not registered", __FUNCTION__); 157 return; 158 } 159 sIdleFallBack = true; 160 /* Trigger SF to redraw the current frame */ 161 ctx->proc->invalidate(ctx->proc); 162 } 163 164 void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx, 165 hwc_display_contents_1_t* list) { 166 LayerProp *layerProp = ctx->layerProp[mDpy]; 167 168 for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; index++) { 169 hwc_layer_1_t* layer = &(list->hwLayers[index]); 170 if(!mCurrentFrame.isFBComposed[index]) { 171 layerProp[index].mFlags |= HWC_MDPCOMP; 172 layer->compositionType = HWC_OVERLAY; 173 layer->hints |= HWC_HINT_CLEAR_FB; 174 } else { 175 if(!mCurrentFrame.needsRedraw) 176 layer->compositionType = HWC_OVERLAY; 177 } 178 } 179 } 180 181 MDPComp::FrameInfo::FrameInfo() { 182 reset(0); 183 } 184 185 void MDPComp::FrameInfo::reset(const int& numLayers) { 186 for(int i = 0 ; i < MAX_PIPES_PER_MIXER && numLayers; i++ ) { 187 if(mdpToLayer[i].pipeInfo) { 188 delete mdpToLayer[i].pipeInfo; 189 mdpToLayer[i].pipeInfo = NULL; 190 //We dont own the rotator 191 mdpToLayer[i].rot = NULL; 192 } 193 } 194 195 memset(&mdpToLayer, 0, sizeof(mdpToLayer)); 196 memset(&layerToMDP, -1, sizeof(layerToMDP)); 197 memset(&isFBComposed, 1, sizeof(isFBComposed)); 198 199 layerCount = numLayers; 200 fbCount = numLayers; 201 mdpCount = 0; 202 needsRedraw = true; 203 fbZ = 0; 204 } 205 206 void MDPComp::FrameInfo::map() { 207 // populate layer and MDP maps 208 int mdpIdx = 0; 209 for(int idx = 0; idx < layerCount; idx++) { 210 if(!isFBComposed[idx]) { 211 mdpToLayer[mdpIdx].listIndex = idx; 212 layerToMDP[idx] = mdpIdx++; 213 } 214 } 215 } 216 217 MDPComp::LayerCache::LayerCache() { 218 reset(); 219 } 220 221 void MDPComp::LayerCache::reset() { 222 memset(&hnd, 0, sizeof(hnd)); 223 mdpCount = 0; 224 fbCount = 0; 225 layerCount = 0; 226 fbZ = -1; 227 } 228 229 void MDPComp::LayerCache::cacheAll(hwc_display_contents_1_t* list) { 230 const int numAppLayers = list->numHwLayers - 1; 231 for(int i = 0; i < numAppLayers; i++) { 232 hnd[i] = list->hwLayers[i].handle; 233 } 234 } 235 236 void MDPComp::LayerCache::updateCounts(const FrameInfo& curFrame) { 237 mdpCount = curFrame.mdpCount; 238 fbCount = curFrame.fbCount; 239 layerCount = curFrame.layerCount; 240 fbZ = curFrame.fbZ; 241 } 242 243 bool MDPComp::isSupportedForMDPComp(hwc_context_t *ctx, hwc_layer_1_t* layer) { 244 private_handle_t *hnd = (private_handle_t *)layer->handle; 245 if((not isYuvBuffer(hnd) and has90Transform(layer)) or 246 (not isValidDimension(ctx,layer)) 247 //More conditions here, SKIP, sRGB+Blend etc 248 ) { 249 return false; 250 } 251 return true; 252 } 253 254 bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) { 255 const int dpy = HWC_DISPLAY_PRIMARY; 256 private_handle_t *hnd = (private_handle_t *)layer->handle; 257 258 if(!hnd) { 259 ALOGE("%s: layer handle is NULL", __FUNCTION__); 260 return false; 261 } 262 263 //XXX: Investigate doing this with pixel phase on MDSS 264 if(!isSecureBuffer(hnd) && isNonIntegralSourceCrop(layer->sourceCropf)) 265 return false; 266 267 int hw_w = ctx->dpyAttr[mDpy].xres; 268 int hw_h = ctx->dpyAttr[mDpy].yres; 269 270 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf); 271 hwc_rect_t dst = layer->displayFrame; 272 273 if(dst.left < 0 || dst.top < 0 || dst.right > hw_w || dst.bottom > hw_h) { 274 hwc_rect_t scissor = {0, 0, hw_w, hw_h }; 275 qhwc::calculate_crop_rects(crop, dst, scissor, layer->transform); 276 } 277 278 int crop_w = crop.right - crop.left; 279 int crop_h = crop.bottom - crop.top; 280 int dst_w = dst.right - dst.left; 281 int dst_h = dst.bottom - dst.top; 282 float w_dscale = ceilf((float)crop_w / (float)dst_w); 283 float h_dscale = ceilf((float)crop_h / (float)dst_h); 284 285 //Workaround for MDP HW limitation in DSI command mode panels where 286 //FPS will not go beyond 30 if buffers on RGB pipes are of width < 5 287 288 if((crop_w < 5)||(crop_h < 5)) 289 return false; 290 291 const uint32_t downscale = 292 qdutils::MDPVersion::getInstance().getMaxMDPDownscale(); 293 if(ctx->mMDP.version >= qdutils::MDSS_V5) { 294 if(!qdutils::MDPVersion::getInstance().supportsDecimation()) { 295 if(crop_w > MAX_DISPLAY_DIM || w_dscale > downscale || 296 h_dscale > downscale) 297 return false; 298 } else if(w_dscale > 64 || h_dscale > 64) { 299 return false; 300 } 301 } else { //A-family 302 if(w_dscale > downscale || h_dscale > downscale) 303 return false; 304 } 305 306 return true; 307 } 308 309 ovutils::eDest MDPComp::getMdpPipe(hwc_context_t *ctx, ePipeType type, 310 int mixer) { 311 overlay::Overlay& ov = *ctx->mOverlay; 312 ovutils::eDest mdp_pipe = ovutils::OV_INVALID; 313 314 switch(type) { 315 case MDPCOMP_OV_DMA: 316 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_DMA, mDpy, mixer); 317 if(mdp_pipe != ovutils::OV_INVALID) { 318 return mdp_pipe; 319 } 320 case MDPCOMP_OV_ANY: 321 case MDPCOMP_OV_RGB: 322 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy, mixer); 323 if(mdp_pipe != ovutils::OV_INVALID) { 324 return mdp_pipe; 325 } 326 327 if(type == MDPCOMP_OV_RGB) { 328 //Requested only for RGB pipe 329 break; 330 } 331 case MDPCOMP_OV_VG: 332 return ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy, mixer); 333 default: 334 ALOGE("%s: Invalid pipe type",__FUNCTION__); 335 return ovutils::OV_INVALID; 336 }; 337 return ovutils::OV_INVALID; 338 } 339 340 bool MDPComp::isFrameDoable(hwc_context_t *ctx) { 341 bool ret = true; 342 const int numAppLayers = ctx->listStats[mDpy].numAppLayers; 343 344 if(!isEnabled()) { 345 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__); 346 ret = false; 347 } else if(qdutils::MDPVersion::getInstance().is8x26() && 348 ctx->mVideoTransFlag && 349 isSecondaryConnected(ctx)) { 350 //1 Padding round to shift pipes across mixers 351 ALOGD_IF(isDebug(),"%s: MDP Comp. video transition padding round", 352 __FUNCTION__); 353 ret = false; 354 } else if(isSecondaryConfiguring(ctx)) { 355 ALOGD_IF( isDebug(),"%s: External Display connection is pending", 356 __FUNCTION__); 357 ret = false; 358 } else if(ctx->isPaddingRound) { 359 ctx->isPaddingRound = false; 360 ALOGD_IF(isDebug(), "%s: padding round",__FUNCTION__); 361 ret = false; 362 } 363 return ret; 364 } 365 366 /* Checks for conditions where all the layers marked for MDP comp cannot be 367 * bypassed. On such conditions we try to bypass atleast YUV layers */ 368 bool MDPComp::isFullFrameDoable(hwc_context_t *ctx, 369 hwc_display_contents_1_t* list){ 370 371 const int numAppLayers = ctx->listStats[mDpy].numAppLayers; 372 373 if(sIdleFallBack) { 374 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy); 375 return false; 376 } 377 378 if(isSkipPresent(ctx, mDpy)) { 379 ALOGD_IF(isDebug(),"%s: SKIP present: %d", 380 __FUNCTION__, 381 isSkipPresent(ctx, mDpy)); 382 return false; 383 } 384 385 if(ctx->listStats[mDpy].needsAlphaScale 386 && ctx->mMDP.version < qdutils::MDSS_V5) { 387 ALOGD_IF(isDebug(), "%s: frame needs alpha downscaling",__FUNCTION__); 388 return false; 389 } 390 391 for(int i = 0; i < numAppLayers; ++i) { 392 hwc_layer_1_t* layer = &list->hwLayers[i]; 393 private_handle_t *hnd = (private_handle_t *)layer->handle; 394 395 if(isYuvBuffer(hnd) && has90Transform(layer)) { 396 if(!canUseRotator(ctx, mDpy)) { 397 ALOGD_IF(isDebug(), "%s: Can't use rotator for dpy %d", 398 __FUNCTION__, mDpy); 399 return false; 400 } 401 } 402 403 if(mDpy > HWC_DISPLAY_PRIMARY && isL3SecureBuffer(hnd)) { 404 return false; 405 } 406 407 //For 8x26 with panel width>1k, if RGB layer needs HFLIP fail mdp comp 408 // may not need it if Gfx pre-rotation can handle all flips & rotations 409 if(qdutils::MDPVersion::getInstance().is8x26() && 410 (ctx->dpyAttr[mDpy].xres > 1024) && 411 (layer->transform & HWC_TRANSFORM_FLIP_H) && 412 (!isYuvBuffer(hnd))) 413 return false; 414 } 415 416 if(ctx->mAD->isDoable()) { 417 return false; 418 } 419 420 //If all above hard conditions are met we can do full or partial MDP comp. 421 bool ret = false; 422 if(fullMDPComp(ctx, list)) { 423 ret = true; 424 } else if(partialMDPComp(ctx, list)) { 425 ret = true; 426 } 427 return ret; 428 } 429 430 bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 431 //Will benefit presentation / secondary-only layer. 432 if((mDpy > HWC_DISPLAY_PRIMARY) && 433 (list->numHwLayers - 1) > MAX_SEC_LAYERS) { 434 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__); 435 return false; 436 } 437 438 /* XXX: There is some flicker currently seen with partial 439 * MDP composition on the virtual display. 440 * Disable UI MDP comp on virtual until it is fixed*/ 441 442 if(mDpy > HWC_DISPLAY_EXTERNAL) { 443 return false; 444 } 445 446 const int numAppLayers = ctx->listStats[mDpy].numAppLayers; 447 for(int i = 0; i < numAppLayers; i++) { 448 hwc_layer_1_t* layer = &list->hwLayers[i]; 449 if(not isSupportedForMDPComp(ctx, layer)) { 450 ALOGD_IF(isDebug(), "%s: Unsupported layer in list",__FUNCTION__); 451 return false; 452 } 453 } 454 455 //Setup mCurrentFrame 456 mCurrentFrame.mdpCount = mCurrentFrame.layerCount; 457 mCurrentFrame.fbCount = 0; 458 mCurrentFrame.fbZ = -1; 459 memset(&mCurrentFrame.isFBComposed, 0, sizeof(mCurrentFrame.isFBComposed)); 460 461 int mdpCount = mCurrentFrame.mdpCount; 462 if(mdpCount > sMaxPipesPerMixer) { 463 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__); 464 return false; 465 } 466 467 if(!arePipesAvailable(ctx, list)) { 468 return false; 469 } 470 471 return true; 472 } 473 474 bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) 475 { 476 if(!sEnableMixedMode) { 477 //Mixed mode is disabled. No need to even try caching. 478 return false; 479 } 480 481 bool ret = false; 482 if(isLoadBasedCompDoable(ctx, list)) { 483 ret = loadBasedComp(ctx, list); 484 } 485 486 if(!ret) { 487 ret = cacheBasedComp(ctx, list); 488 } 489 490 return ret; 491 } 492 493 bool MDPComp::cacheBasedComp(hwc_context_t *ctx, 494 hwc_display_contents_1_t* list) { 495 int numAppLayers = ctx->listStats[mDpy].numAppLayers; 496 mCurrentFrame.reset(numAppLayers); 497 updateLayerCache(ctx, list); 498 499 //If an MDP marked layer is unsupported cannot do partial MDP Comp 500 for(int i = 0; i < numAppLayers; i++) { 501 if(!mCurrentFrame.isFBComposed[i]) { 502 hwc_layer_1_t* layer = &list->hwLayers[i]; 503 if(not isSupportedForMDPComp(ctx, layer)) { 504 ALOGD_IF(isDebug(), "%s: Unsupported layer in list", 505 __FUNCTION__); 506 return false; 507 } 508 } 509 } 510 511 updateYUV(ctx, list); 512 bool ret = batchLayers(ctx, list); //sets up fbZ also 513 if(!ret) { 514 ALOGD_IF(isDebug(),"%s: batching failed, dpy %d",__FUNCTION__, mDpy); 515 return false; 516 } 517 518 int mdpCount = mCurrentFrame.mdpCount; 519 520 //Will benefit cases where a video has non-updating background. 521 if((mDpy > HWC_DISPLAY_PRIMARY) and 522 (mdpCount > MAX_SEC_LAYERS)) { 523 ALOGD_IF(isDebug(), "%s: Exceeds max secondary pipes",__FUNCTION__); 524 return false; 525 } 526 527 /* XXX: There is some flicker currently seen with partial 528 * MDP composition on the virtual display. 529 * Disable UI MDP comp on virtual until it is fixed*/ 530 531 if(mDpy > HWC_DISPLAY_EXTERNAL) { 532 return false; 533 } 534 535 if(mdpCount > (sMaxPipesPerMixer - 1)) { // -1 since FB is used 536 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__); 537 return false; 538 } 539 540 if(!arePipesAvailable(ctx, list)) { 541 return false; 542 } 543 544 return true; 545 } 546 547 bool MDPComp::loadBasedComp(hwc_context_t *ctx, 548 hwc_display_contents_1_t* list) { 549 int numAppLayers = ctx->listStats[mDpy].numAppLayers; 550 mCurrentFrame.reset(numAppLayers); 551 552 //TODO BatchSize could be optimized further based on available pipes, split 553 //displays etc. 554 const int batchSize = numAppLayers - (sMaxPipesPerMixer - 1); 555 if(batchSize <= 0) { 556 ALOGD_IF(isDebug(), "%s: Not attempting", __FUNCTION__); 557 return false; 558 } 559 560 int minBatchStart = -1; 561 size_t minBatchPixelCount = SIZE_MAX; 562 563 for(int i = 0; i <= numAppLayers - batchSize; i++) { 564 uint32_t batchPixelCount = 0; 565 for(int j = i; j < i + batchSize; j++) { 566 hwc_layer_1_t* layer = &list->hwLayers[j]; 567 hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf); 568 batchPixelCount += (crop.right - crop.left) * 569 (crop.bottom - crop.top); 570 } 571 572 if(batchPixelCount < minBatchPixelCount) { 573 minBatchPixelCount = batchPixelCount; 574 minBatchStart = i; 575 } 576 } 577 578 if(minBatchStart < 0) { 579 ALOGD_IF(isDebug(), "%s: No batch found batchSize %d numAppLayers %d", 580 __FUNCTION__, batchSize, numAppLayers); 581 return false; 582 } 583 584 for(int i = 0; i < numAppLayers; i++) { 585 if(i < minBatchStart || i >= minBatchStart + batchSize) { 586 hwc_layer_1_t* layer = &list->hwLayers[i]; 587 if(not isSupportedForMDPComp(ctx, layer)) { 588 ALOGD_IF(isDebug(), "%s: MDP unsupported layer found at %d", 589 __FUNCTION__, i); 590 return false; 591 } 592 mCurrentFrame.isFBComposed[i] = false; 593 } 594 } 595 596 mCurrentFrame.fbZ = minBatchStart; 597 mCurrentFrame.fbCount = batchSize; 598 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - batchSize; 599 600 if(!arePipesAvailable(ctx, list)) { 601 return false; 602 } 603 604 ALOGD_IF(isDebug(), "%s: fbZ %d batchSize %d", 605 __FUNCTION__, mCurrentFrame.fbZ, batchSize); 606 return true; 607 } 608 609 bool MDPComp::isLoadBasedCompDoable(hwc_context_t *ctx, 610 hwc_display_contents_1_t* list) { 611 if(mDpy or isSecurePresent(ctx, mDpy) or 612 not (list->flags & HWC_GEOMETRY_CHANGED)) { 613 return false; 614 } 615 return true; 616 } 617 618 bool MDPComp::isOnlyVideoDoable(hwc_context_t *ctx, 619 hwc_display_contents_1_t* list){ 620 int numAppLayers = ctx->listStats[mDpy].numAppLayers; 621 mCurrentFrame.reset(numAppLayers); 622 updateYUV(ctx, list); 623 int mdpCount = mCurrentFrame.mdpCount; 624 int fbNeeded = int(mCurrentFrame.fbCount != 0); 625 626 if(!isYuvPresent(ctx, mDpy)) { 627 return false; 628 } 629 630 if(!mdpCount) 631 return false; 632 633 if(mdpCount > (sMaxPipesPerMixer - fbNeeded)) { 634 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__); 635 return false; 636 } 637 638 if(!arePipesAvailable(ctx, list)) { 639 return false; 640 } 641 642 int nYuvCount = ctx->listStats[mDpy].yuvCount; 643 for(int index = 0; index < nYuvCount ; index ++) { 644 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index]; 645 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex]; 646 if(layer->planeAlpha < 0xFF) { 647 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\ 648 in video only mode", 649 __FUNCTION__); 650 return false; 651 } 652 private_handle_t *hnd = (private_handle_t *)layer->handle; 653 if(mDpy > HWC_DISPLAY_PRIMARY && isL3SecureBuffer(hnd)) { 654 return false; 655 } 656 } 657 658 return true; 659 } 660 661 /* Checks for conditions where YUV layers cannot be bypassed */ 662 bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) { 663 if(isSkipLayer(layer)) { 664 ALOGE("%s: Unable to bypass skipped YUV", __FUNCTION__); 665 return false; 666 } 667 668 if(layer->transform & HWC_TRANSFORM_ROT_90 && !canUseRotator(ctx,mDpy)) { 669 ALOGD_IF(isDebug(), "%s: no free DMA pipe",__FUNCTION__); 670 return false; 671 } 672 673 if(isSecuring(ctx, layer)) { 674 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__); 675 return false; 676 } 677 678 if(!isValidDimension(ctx, layer)) { 679 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width", 680 __FUNCTION__); 681 return false; 682 } 683 684 return true; 685 } 686 687 bool MDPComp::batchLayers(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 688 /* Idea is to keep as many contiguous non-updating(cached) layers in FB and 689 * send rest of them through MDP. NEVER mark an updating layer for caching. 690 * But cached ones can be marked for MDP*/ 691 692 int maxBatchStart = -1; 693 int maxBatchCount = 0; 694 695 /* All or Nothing is cached. No batching needed */ 696 if(!mCurrentFrame.fbCount) { 697 mCurrentFrame.fbZ = -1; 698 return true; 699 } 700 if(!mCurrentFrame.mdpCount) { 701 mCurrentFrame.fbZ = 0; 702 return true; 703 } 704 705 /* Search for max number of contiguous (cached) layers */ 706 int i = 0; 707 while (i < mCurrentFrame.layerCount) { 708 int count = 0; 709 while(mCurrentFrame.isFBComposed[i] && i < mCurrentFrame.layerCount) { 710 count++; i++; 711 } 712 if(count > maxBatchCount) { 713 maxBatchCount = count; 714 maxBatchStart = i - count; 715 mCurrentFrame.fbZ = maxBatchStart; 716 } 717 if(i < mCurrentFrame.layerCount) i++; 718 } 719 720 /* reset rest of the layers for MDP comp */ 721 for(int i = 0; i < mCurrentFrame.layerCount; i++) { 722 hwc_layer_1_t* layer = &list->hwLayers[i]; 723 if(i != maxBatchStart) { 724 //If an unsupported layer is being attempted to be pulled out we 725 //should fail 726 if(not isSupportedForMDPComp(ctx, layer)) { 727 return false; 728 } 729 mCurrentFrame.isFBComposed[i] = false; 730 } else { 731 i += maxBatchCount; 732 } 733 } 734 735 mCurrentFrame.fbCount = maxBatchCount; 736 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - 737 mCurrentFrame.fbCount; 738 739 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__, 740 mCurrentFrame.fbCount); 741 742 return true; 743 } 744 745 void MDPComp::updateLayerCache(hwc_context_t* ctx, 746 hwc_display_contents_1_t* list) { 747 int numAppLayers = ctx->listStats[mDpy].numAppLayers; 748 int fbCount = 0; 749 750 for(int i = 0; i < numAppLayers; i++) { 751 hwc_layer_1_t* layer = &list->hwLayers[i]; 752 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) { 753 fbCount++; 754 mCurrentFrame.isFBComposed[i] = true; 755 } else { 756 mCurrentFrame.isFBComposed[i] = false; 757 mCachedFrame.hnd[i] = list->hwLayers[i].handle; 758 } 759 } 760 761 mCurrentFrame.fbCount = fbCount; 762 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount; 763 764 ALOGD_IF(isDebug(),"%s: MDP count: %d FB count %d",__FUNCTION__, 765 mCurrentFrame.mdpCount, mCurrentFrame.fbCount); 766 } 767 768 void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list) { 769 770 int nYuvCount = ctx->listStats[mDpy].yuvCount; 771 for(int index = 0;index < nYuvCount; index++){ 772 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index]; 773 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex]; 774 775 if(!isYUVDoable(ctx, layer)) { 776 if(!mCurrentFrame.isFBComposed[nYuvIndex]) { 777 mCurrentFrame.isFBComposed[nYuvIndex] = true; 778 mCurrentFrame.fbCount++; 779 } 780 } else { 781 if(mCurrentFrame.isFBComposed[nYuvIndex]) { 782 mCurrentFrame.isFBComposed[nYuvIndex] = false; 783 mCurrentFrame.fbCount--; 784 } 785 } 786 } 787 788 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - 789 mCurrentFrame.fbCount; 790 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__, 791 mCurrentFrame.fbCount); 792 } 793 794 bool MDPComp::programMDP(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 795 if(!allocLayerPipes(ctx, list)) { 796 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__); 797 return false; 798 } 799 800 bool fbBatch = false; 801 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount; 802 index++) { 803 if(!mCurrentFrame.isFBComposed[index]) { 804 int mdpIndex = mCurrentFrame.layerToMDP[index]; 805 hwc_layer_1_t* layer = &list->hwLayers[index]; 806 807 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo; 808 cur_pipe->zOrder = mdpNextZOrder++; 809 810 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){ 811 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \ 812 layer %d",__FUNCTION__, index); 813 return false; 814 } 815 } else if(fbBatch == false) { 816 mdpNextZOrder++; 817 fbBatch = true; 818 } 819 } 820 821 return true; 822 } 823 824 bool MDPComp::programYUV(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 825 if(!allocLayerPipes(ctx, list)) { 826 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__); 827 return false; 828 } 829 //If we are in this block, it means we have yuv + rgb layers both 830 int mdpIdx = 0; 831 for (int index = 0; index < mCurrentFrame.layerCount; index++) { 832 if(!mCurrentFrame.isFBComposed[index]) { 833 hwc_layer_1_t* layer = &list->hwLayers[index]; 834 int mdpIndex = mCurrentFrame.layerToMDP[index]; 835 MdpPipeInfo* cur_pipe = 836 mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo; 837 cur_pipe->zOrder = mdpIdx++; 838 839 if(configure(ctx, layer, 840 mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){ 841 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \ 842 layer %d",__FUNCTION__, index); 843 return false; 844 } 845 } 846 } 847 return true; 848 } 849 850 int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 851 const int numLayers = ctx->listStats[mDpy].numAppLayers; 852 853 //reset old data 854 mCurrentFrame.reset(numLayers); 855 856 //number of app layers exceeds MAX_NUM_APP_LAYERS fall back to GPU 857 //do not cache the information for next draw cycle. 858 if(numLayers > MAX_NUM_APP_LAYERS) { 859 mCachedFrame.updateCounts(mCurrentFrame); 860 ALOGD_IF(isDebug(), "%s: Number of App layers exceeded the limit ", 861 __FUNCTION__); 862 return -1; 863 } 864 865 //Hard conditions, if not met, cannot do MDP comp 866 if(!isFrameDoable(ctx)) { 867 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame", 868 __FUNCTION__); 869 reset(numLayers, list); 870 return -1; 871 } 872 873 //Check whether layers marked for MDP Composition is actually doable. 874 if(isFullFrameDoable(ctx, list)) { 875 mCurrentFrame.map(); 876 //Configure framebuffer first if applicable 877 if(mCurrentFrame.fbZ >= 0) { 878 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, 879 mCurrentFrame.fbZ)) { 880 ALOGE("%s configure framebuffer failed", __func__); 881 reset(numLayers, list); 882 return -1; 883 } 884 } 885 //Acquire and Program MDP pipes 886 if(!programMDP(ctx, list)) { 887 reset(numLayers, list); 888 return -1; 889 } else { //Success 890 //Any change in composition types needs an FB refresh 891 mCurrentFrame.needsRedraw = false; 892 if(mCurrentFrame.fbCount && 893 ((mCurrentFrame.mdpCount != mCachedFrame.mdpCount) || 894 (mCurrentFrame.fbCount != mCachedFrame.fbCount) || 895 (mCurrentFrame.fbZ != mCachedFrame.fbZ) || 896 (!mCurrentFrame.mdpCount) || 897 (list->flags & HWC_GEOMETRY_CHANGED) || 898 isSkipPresent(ctx, mDpy))) { 899 mCurrentFrame.needsRedraw = true; 900 } 901 } 902 } else if(isOnlyVideoDoable(ctx, list)) { 903 //All layers marked for MDP comp cannot be bypassed. 904 //Try to compose atleast YUV layers through MDP comp and let 905 //all the RGB layers compose in FB 906 //Destination over 907 mCurrentFrame.fbZ = -1; 908 if(mCurrentFrame.fbCount) 909 mCurrentFrame.fbZ = mCurrentFrame.mdpCount; 910 911 mCurrentFrame.map(); 912 913 //Configure framebuffer first if applicable 914 if(mCurrentFrame.fbZ >= 0) { 915 if(!ctx->mFBUpdate[mDpy]->prepare(ctx, list, mCurrentFrame.fbZ)) { 916 ALOGE("%s configure framebuffer failed", __func__); 917 reset(numLayers, list); 918 return -1; 919 } 920 } 921 if(!programYUV(ctx, list)) { 922 reset(numLayers, list); 923 return -1; 924 } 925 } else { 926 reset(numLayers, list); 927 return -1; 928 } 929 930 //UpdateLayerFlags 931 setMDPCompLayerFlags(ctx, list); 932 mCachedFrame.updateCounts(mCurrentFrame); 933 934 // unlock it before calling dump function to avoid deadlock 935 if(isDebug()) { 936 ALOGD("GEOMETRY change: %d", (list->flags & HWC_GEOMETRY_CHANGED)); 937 android::String8 sDump(""); 938 dump(sDump); 939 ALOGE("%s",sDump.string()); 940 } 941 942 return 0; 943 } 944 945 //=============MDPCompLowRes=================================================== 946 947 /* 948 * Configures pipe(s) for MDP composition 949 */ 950 int MDPCompLowRes::configure(hwc_context_t *ctx, hwc_layer_1_t *layer, 951 PipeLayerPair& PipeLayerPair) { 952 MdpPipeInfoLowRes& mdp_info = 953 *(static_cast<MdpPipeInfoLowRes*>(PipeLayerPair.pipeInfo)); 954 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION; 955 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder); 956 eIsFg isFg = IS_FG_OFF; 957 eDest dest = mdp_info.index; 958 959 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d", 960 __FUNCTION__, layer, zOrder, dest); 961 962 return configureLowRes(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest, 963 &PipeLayerPair.rot); 964 } 965 966 bool MDPCompLowRes::arePipesAvailable(hwc_context_t *ctx, 967 hwc_display_contents_1_t* list) { 968 overlay::Overlay& ov = *ctx->mOverlay; 969 int numPipesNeeded = mCurrentFrame.mdpCount; 970 int availPipes = ov.availablePipes(mDpy, Overlay::MIXER_DEFAULT); 971 972 //Reserve pipe for FB 973 if(mCurrentFrame.fbCount) 974 availPipes -= 1; 975 976 if(numPipesNeeded > availPipes) { 977 ALOGD_IF(isDebug(), "%s: Insufficient pipes, dpy %d needed %d, avail %d", 978 __FUNCTION__, mDpy, numPipesNeeded, availPipes); 979 return false; 980 } 981 982 return true; 983 } 984 985 bool MDPCompLowRes::allocLayerPipes(hwc_context_t *ctx, 986 hwc_display_contents_1_t* list) { 987 for(int index = 0; index < mCurrentFrame.layerCount; index++) { 988 989 if(mCurrentFrame.isFBComposed[index]) continue; 990 991 hwc_layer_1_t* layer = &list->hwLayers[index]; 992 private_handle_t *hnd = (private_handle_t *)layer->handle; 993 int mdpIndex = mCurrentFrame.layerToMDP[index]; 994 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex]; 995 info.pipeInfo = new MdpPipeInfoLowRes; 996 info.rot = NULL; 997 MdpPipeInfoLowRes& pipe_info = *(MdpPipeInfoLowRes*)info.pipeInfo; 998 ePipeType type = MDPCOMP_OV_ANY; 999 1000 if(isYuvBuffer(hnd)) { 1001 type = MDPCOMP_OV_VG; 1002 } else if(!qhwc::needsScaling(ctx, layer, mDpy) 1003 && Overlay::getDMAMode() != Overlay::DMA_BLOCK_MODE 1004 && ctx->mMDP.version >= qdutils::MDSS_V5) { 1005 type = MDPCOMP_OV_DMA; 1006 } 1007 1008 pipe_info.index = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT); 1009 if(pipe_info.index == ovutils::OV_INVALID) { 1010 ALOGD_IF(isDebug(), "%s: Unable to get pipe type = %d", 1011 __FUNCTION__, (int) type); 1012 return false; 1013 } 1014 } 1015 return true; 1016 } 1017 1018 bool MDPCompLowRes::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 1019 1020 if(!isEnabled()) { 1021 ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__); 1022 return true; 1023 } 1024 1025 if(!ctx || !list) { 1026 ALOGE("%s: invalid contxt or list",__FUNCTION__); 1027 return false; 1028 } 1029 1030 if(ctx->listStats[mDpy].numAppLayers > MAX_NUM_APP_LAYERS) { 1031 ALOGD_IF(isDebug(),"%s: Exceeding max layer count", __FUNCTION__); 1032 return true; 1033 } 1034 1035 /* reset Invalidator */ 1036 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) 1037 idleInvalidator->markForSleep(); 1038 1039 overlay::Overlay& ov = *ctx->mOverlay; 1040 LayerProp *layerProp = ctx->layerProp[mDpy]; 1041 1042 int numHwLayers = ctx->listStats[mDpy].numAppLayers; 1043 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ ) 1044 { 1045 if(mCurrentFrame.isFBComposed[i]) continue; 1046 1047 hwc_layer_1_t *layer = &list->hwLayers[i]; 1048 private_handle_t *hnd = (private_handle_t *)layer->handle; 1049 if(!hnd) { 1050 ALOGE("%s handle null", __FUNCTION__); 1051 return false; 1052 } 1053 1054 int mdpIndex = mCurrentFrame.layerToMDP[i]; 1055 1056 MdpPipeInfoLowRes& pipe_info = 1057 *(MdpPipeInfoLowRes*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo; 1058 ovutils::eDest dest = pipe_info.index; 1059 if(dest == ovutils::OV_INVALID) { 1060 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest); 1061 return false; 1062 } 1063 1064 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) { 1065 continue; 1066 } 1067 1068 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \ 1069 using pipe: %d", __FUNCTION__, layer, 1070 hnd, dest ); 1071 1072 int fd = hnd->fd; 1073 uint32_t offset = hnd->offset; 1074 1075 if(ctx->mAD->isModeOn()) { 1076 if(ctx->mAD->draw(ctx, fd, offset)) { 1077 fd = ctx->mAD->getDstFd(ctx); 1078 offset = ctx->mAD->getDstOffset(ctx); 1079 } 1080 } 1081 1082 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot; 1083 if(rot) { 1084 if(!rot->queueBuffer(fd, offset)) 1085 return false; 1086 fd = rot->getDstMemId(); 1087 offset = rot->getDstOffset(); 1088 } 1089 1090 if (!ov.queueBuffer(fd, offset, dest)) { 1091 ALOGE("%s: queueBuffer failed for display:%d ", __FUNCTION__, mDpy); 1092 return false; 1093 } 1094 1095 layerProp[i].mFlags &= ~HWC_MDPCOMP; 1096 } 1097 return true; 1098 } 1099 1100 //=============MDPCompHighRes=================================================== 1101 1102 int MDPCompHighRes::pipesNeeded(hwc_context_t *ctx, 1103 hwc_display_contents_1_t* list, 1104 int mixer) { 1105 int pipesNeeded = 0; 1106 const int xres = ctx->dpyAttr[mDpy].xres; 1107 1108 const int lSplit = getLeftSplit(ctx, mDpy); 1109 1110 for(int i = 0; i < mCurrentFrame.layerCount; ++i) { 1111 if(!mCurrentFrame.isFBComposed[i]) { 1112 hwc_layer_1_t* layer = &list->hwLayers[i]; 1113 hwc_rect_t dst = layer->displayFrame; 1114 if(mixer == Overlay::MIXER_LEFT && dst.left < lSplit) { 1115 pipesNeeded++; 1116 } else if(mixer == Overlay::MIXER_RIGHT && dst.right > lSplit) { 1117 pipesNeeded++; 1118 } 1119 } 1120 } 1121 return pipesNeeded; 1122 } 1123 1124 bool MDPCompHighRes::arePipesAvailable(hwc_context_t *ctx, 1125 hwc_display_contents_1_t* list) { 1126 overlay::Overlay& ov = *ctx->mOverlay; 1127 1128 for(int i = 0; i < Overlay::MIXER_MAX; i++) { 1129 int numPipesNeeded = pipesNeeded(ctx, list, i); 1130 int availPipes = ov.availablePipes(mDpy, i); 1131 1132 //Reserve pipe(s)for FB 1133 if(mCurrentFrame.fbCount) 1134 availPipes -= 1; 1135 1136 if(numPipesNeeded > availPipes) { 1137 ALOGD_IF(isDebug(), "%s: Insufficient pipes for " 1138 "dpy %d mixer %d needed %d, avail %d", 1139 __FUNCTION__, mDpy, i, numPipesNeeded, availPipes); 1140 return false; 1141 } 1142 } 1143 return true; 1144 } 1145 1146 bool MDPCompHighRes::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer, 1147 MdpPipeInfoHighRes& pipe_info, 1148 ePipeType type) { 1149 const int xres = ctx->dpyAttr[mDpy].xres; 1150 const int lSplit = getLeftSplit(ctx, mDpy); 1151 1152 hwc_rect_t dst = layer->displayFrame; 1153 pipe_info.lIndex = ovutils::OV_INVALID; 1154 pipe_info.rIndex = ovutils::OV_INVALID; 1155 1156 if (dst.left < lSplit) { 1157 pipe_info.lIndex = getMdpPipe(ctx, type, Overlay::MIXER_LEFT); 1158 if(pipe_info.lIndex == ovutils::OV_INVALID) 1159 return false; 1160 } 1161 1162 if(dst.right > lSplit) { 1163 pipe_info.rIndex = getMdpPipe(ctx, type, Overlay::MIXER_RIGHT); 1164 if(pipe_info.rIndex == ovutils::OV_INVALID) 1165 return false; 1166 } 1167 1168 return true; 1169 } 1170 1171 bool MDPCompHighRes::allocLayerPipes(hwc_context_t *ctx, 1172 hwc_display_contents_1_t* list) { 1173 for(int index = 0 ; index < mCurrentFrame.layerCount; index++) { 1174 1175 if(mCurrentFrame.isFBComposed[index]) continue; 1176 1177 hwc_layer_1_t* layer = &list->hwLayers[index]; 1178 private_handle_t *hnd = (private_handle_t *)layer->handle; 1179 int mdpIndex = mCurrentFrame.layerToMDP[index]; 1180 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex]; 1181 info.pipeInfo = new MdpPipeInfoHighRes; 1182 info.rot = NULL; 1183 MdpPipeInfoHighRes& pipe_info = *(MdpPipeInfoHighRes*)info.pipeInfo; 1184 ePipeType type = MDPCOMP_OV_ANY; 1185 1186 if(isYuvBuffer(hnd)) { 1187 type = MDPCOMP_OV_VG; 1188 } else if(!qhwc::needsScaling(ctx, layer, mDpy) 1189 && Overlay::getDMAMode() != Overlay::DMA_BLOCK_MODE 1190 && ctx->mMDP.version >= qdutils::MDSS_V5) { 1191 type = MDPCOMP_OV_DMA; 1192 } 1193 1194 if(!acquireMDPPipes(ctx, layer, pipe_info, type)) { 1195 ALOGD_IF(isDebug(), "%s: Unable to get pipe for type = %d", 1196 __FUNCTION__, (int) type); 1197 return false; 1198 } 1199 } 1200 return true; 1201 } 1202 1203 /* 1204 * Configures pipe(s) for MDP composition 1205 */ 1206 int MDPCompHighRes::configure(hwc_context_t *ctx, hwc_layer_1_t *layer, 1207 PipeLayerPair& PipeLayerPair) { 1208 MdpPipeInfoHighRes& mdp_info = 1209 *(static_cast<MdpPipeInfoHighRes*>(PipeLayerPair.pipeInfo)); 1210 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder); 1211 eIsFg isFg = IS_FG_OFF; 1212 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION; 1213 eDest lDest = mdp_info.lIndex; 1214 eDest rDest = mdp_info.rIndex; 1215 1216 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d" 1217 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest); 1218 1219 return configureHighRes(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest, 1220 rDest, &PipeLayerPair.rot); 1221 } 1222 1223 bool MDPCompHighRes::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 1224 1225 if(!isEnabled()) { 1226 ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__); 1227 return true; 1228 } 1229 1230 if(!ctx || !list) { 1231 ALOGE("%s: invalid contxt or list",__FUNCTION__); 1232 return false; 1233 } 1234 1235 if(ctx->listStats[mDpy].numAppLayers > MAX_NUM_APP_LAYERS) { 1236 ALOGD_IF(isDebug(),"%s: Exceeding max layer count", __FUNCTION__); 1237 return true; 1238 } 1239 1240 /* reset Invalidator */ 1241 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) 1242 idleInvalidator->markForSleep(); 1243 1244 overlay::Overlay& ov = *ctx->mOverlay; 1245 LayerProp *layerProp = ctx->layerProp[mDpy]; 1246 1247 int numHwLayers = ctx->listStats[mDpy].numAppLayers; 1248 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ ) 1249 { 1250 if(mCurrentFrame.isFBComposed[i]) continue; 1251 1252 hwc_layer_1_t *layer = &list->hwLayers[i]; 1253 private_handle_t *hnd = (private_handle_t *)layer->handle; 1254 if(!hnd) { 1255 ALOGE("%s handle null", __FUNCTION__); 1256 return false; 1257 } 1258 1259 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) { 1260 continue; 1261 } 1262 1263 int mdpIndex = mCurrentFrame.layerToMDP[i]; 1264 1265 MdpPipeInfoHighRes& pipe_info = 1266 *(MdpPipeInfoHighRes*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo; 1267 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot; 1268 1269 ovutils::eDest indexL = pipe_info.lIndex; 1270 ovutils::eDest indexR = pipe_info.rIndex; 1271 1272 int fd = hnd->fd; 1273 int offset = hnd->offset; 1274 1275 if(ctx->mAD->isModeOn()) { 1276 if(ctx->mAD->draw(ctx, fd, offset)) { 1277 fd = ctx->mAD->getDstFd(ctx); 1278 offset = ctx->mAD->getDstOffset(ctx); 1279 } 1280 } 1281 1282 if(rot) { 1283 rot->queueBuffer(fd, offset); 1284 fd = rot->getDstMemId(); 1285 offset = rot->getDstOffset(); 1286 } 1287 1288 //************* play left mixer ********** 1289 if(indexL != ovutils::OV_INVALID) { 1290 ovutils::eDest destL = (ovutils::eDest)indexL; 1291 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \ 1292 using pipe: %d", __FUNCTION__, layer, hnd, indexL ); 1293 if (!ov.queueBuffer(fd, offset, destL)) { 1294 ALOGE("%s: queueBuffer failed for left mixer", __FUNCTION__); 1295 return false; 1296 } 1297 } 1298 1299 //************* play right mixer ********** 1300 if(indexR != ovutils::OV_INVALID) { 1301 ovutils::eDest destR = (ovutils::eDest)indexR; 1302 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \ 1303 using pipe: %d", __FUNCTION__, layer, hnd, indexR ); 1304 if (!ov.queueBuffer(fd, offset, destR)) { 1305 ALOGE("%s: queueBuffer failed for right mixer", __FUNCTION__); 1306 return false; 1307 } 1308 } 1309 1310 layerProp[i].mFlags &= ~HWC_MDPCOMP; 1311 } 1312 1313 return true; 1314 } 1315 }; //namespace 1316 1317