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