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