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