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_stride = ctx->dpyAttr[dpy].stride; 171 int fb_width = ctx->dpyAttr[dpy].xres; 172 int fb_height = ctx->dpyAttr[dpy].yres; 173 int fb_fd = ctx->dpyAttr[dpy].fd; 174 175 mdp_overlay ovInfo; 176 msmfb_overlay_data ovData; 177 memset(&ovInfo, 0, sizeof(mdp_overlay)); 178 memset(&ovData, 0, sizeof(msmfb_overlay_data)); 179 180 ovInfo.src.format = MDP_RGB_BORDERFILL; 181 ovInfo.src.width = fb_width; 182 ovInfo.src.height = fb_height; 183 ovInfo.src_rect.w = fb_width; 184 ovInfo.src_rect.h = fb_height; 185 ovInfo.dst_rect.w = fb_width; 186 ovInfo.dst_rect.h = fb_height; 187 ovInfo.id = MSMFB_NEW_REQUEST; 188 189 if (ioctl(fb_fd, MSMFB_OVERLAY_SET, &ovInfo) < 0) { 190 ALOGE("Failed to call ioctl MSMFB_OVERLAY_SET err=%s", 191 strerror(errno)); 192 return false; 193 } 194 195 ovData.id = ovInfo.id; 196 if (ioctl(fb_fd, MSMFB_OVERLAY_PLAY, &ovData) < 0) { 197 ALOGE("Failed to call ioctl MSMFB_OVERLAY_PLAY err=%s", 198 strerror(errno)); 199 return false; 200 } 201 return true; 202 } 203 204 MDPComp::FrameInfo::FrameInfo() { 205 reset(0); 206 } 207 208 void MDPComp::FrameInfo::reset(const int& numLayers) { 209 for(int i = 0 ; i < MAX_PIPES_PER_MIXER && numLayers; 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 const int dpy = HWC_DISPLAY_PRIMARY; 268 private_handle_t *hnd = (private_handle_t *)layer->handle; 269 270 if(!hnd) { 271 ALOGE("%s: layer handle is NULL", __FUNCTION__); 272 return false; 273 } 274 275 int hw_w = ctx->dpyAttr[mDpy].xres; 276 int hw_h = ctx->dpyAttr[mDpy].yres; 277 278 hwc_rect_t crop = layer->sourceCrop; 279 hwc_rect_t dst = layer->displayFrame; 280 281 if(dst.left < 0 || dst.top < 0 || dst.right > hw_w || dst.bottom > hw_h) { 282 hwc_rect_t scissor = {0, 0, hw_w, hw_h }; 283 qhwc::calculate_crop_rects(crop, dst, scissor, layer->transform); 284 } 285 286 int crop_w = crop.right - crop.left; 287 int crop_h = crop.bottom - crop.top; 288 int dst_w = dst.right - dst.left; 289 int dst_h = dst.bottom - dst.top; 290 float w_dscale = ceilf((float)crop_w / (float)dst_w); 291 float h_dscale = ceilf((float)crop_h / (float)dst_h); 292 293 //Workaround for MDP HW limitation in DSI command mode panels where 294 //FPS will not go beyond 30 if buffers on RGB pipes are of width < 5 295 296 if((crop_w < 5)||(crop_h < 5)) 297 return false; 298 299 if(ctx->mMDP.version >= qdutils::MDSS_V5) { 300 /* Workaround for downscales larger than 4x. 301 * Will be removed once decimator block is enabled for MDSS 302 */ 303 if(w_dscale > 4.0f || h_dscale > 4.0f) 304 return false; 305 } else { 306 if(w_dscale > 8.0f || h_dscale > 8.0f) 307 // MDP 4 supports 1/8 downscale 308 return false; 309 } 310 311 return true; 312 } 313 314 ovutils::eDest MDPComp::getMdpPipe(hwc_context_t *ctx, ePipeType type) { 315 overlay::Overlay& ov = *ctx->mOverlay; 316 ovutils::eDest mdp_pipe = ovutils::OV_INVALID; 317 318 switch(type) { 319 case MDPCOMP_OV_DMA: 320 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_DMA, mDpy); 321 if(mdp_pipe != ovutils::OV_INVALID) { 322 ctx->mDMAInUse = true; 323 return mdp_pipe; 324 } 325 case MDPCOMP_OV_ANY: 326 case MDPCOMP_OV_RGB: 327 mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy); 328 if(mdp_pipe != ovutils::OV_INVALID) { 329 return mdp_pipe; 330 } 331 332 if(type == MDPCOMP_OV_RGB) { 333 //Requested only for RGB pipe 334 break; 335 } 336 case MDPCOMP_OV_VG: 337 return ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy); 338 default: 339 ALOGE("%s: Invalid pipe type",__FUNCTION__); 340 return ovutils::OV_INVALID; 341 }; 342 return ovutils::OV_INVALID; 343 } 344 345 bool MDPComp::isFrameDoable(hwc_context_t *ctx) { 346 int numAppLayers = ctx->listStats[mDpy].numAppLayers; 347 bool ret = true; 348 349 if(!isEnabled()) { 350 ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__); 351 ret = false; 352 } else if(ctx->mExtDispConfiguring) { 353 ALOGD_IF( isDebug(),"%s: External Display connection is pending", 354 __FUNCTION__); 355 ret = false; 356 } 357 return ret; 358 } 359 360 /* Checks for conditions where all the layers marked for MDP comp cannot be 361 * bypassed. On such conditions we try to bypass atleast YUV layers */ 362 bool MDPComp::isFullFrameDoable(hwc_context_t *ctx, 363 hwc_display_contents_1_t* list){ 364 365 const int numAppLayers = ctx->listStats[mDpy].numAppLayers; 366 367 if(sIdleFallBack) { 368 ALOGD_IF(isDebug(), "%s: Idle fallback dpy %d",__FUNCTION__, mDpy); 369 return false; 370 } 371 372 if(mDpy > HWC_DISPLAY_PRIMARY){ 373 ALOGD_IF(isDebug(), "%s: Cannot support External display(s)", 374 __FUNCTION__); 375 return false; 376 } 377 378 if(isSkipPresent(ctx, mDpy)) { 379 ALOGD_IF(isDebug(),"%s: SKIP present: %d", 380 __FUNCTION__, 381 isSkipPresent(ctx, mDpy)); 382 return false; 383 } 384 385 if(ctx->listStats[mDpy].planeAlpha 386 && ctx->mMDP.version >= qdutils::MDSS_V5) { 387 ALOGD_IF(isDebug(), "%s: plane alpha not implemented on MDSS", 388 __FUNCTION__); 389 return false; 390 } 391 392 if(ctx->listStats[mDpy].needsAlphaScale 393 && ctx->mMDP.version < qdutils::MDSS_V5) { 394 ALOGD_IF(isDebug(), "%s: frame needs alpha downscaling",__FUNCTION__); 395 return false; 396 } 397 398 //MDP composition is not efficient if layer needs rotator. 399 for(int i = 0; i < numAppLayers; ++i) { 400 // As MDP h/w supports flip operation, use MDP comp only for 401 // 180 transforms. Fail for any transform involving 90 (90, 270). 402 hwc_layer_1_t* layer = &list->hwLayers[i]; 403 private_handle_t *hnd = (private_handle_t *)layer->handle; 404 if(isYuvBuffer(hnd) ) { 405 if(isSecuring(ctx, layer)) { 406 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__); 407 return false; 408 } 409 } else if(layer->transform & HWC_TRANSFORM_ROT_90) { 410 ALOGD_IF(isDebug(), "%s: orientation involved",__FUNCTION__); 411 return false; 412 } 413 414 if(!isValidDimension(ctx,layer)) { 415 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width", 416 __FUNCTION__); 417 return false; 418 } 419 } 420 421 //If all above hard conditions are met we can do full or partial MDP comp. 422 bool ret = false; 423 if(fullMDPComp(ctx, list)) { 424 ret = true; 425 } else if (partialMDPComp(ctx, list)) { 426 ret = true; 427 } 428 return ret; 429 } 430 431 bool MDPComp::fullMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 432 //Setup mCurrentFrame 433 mCurrentFrame.mdpCount = mCurrentFrame.layerCount; 434 mCurrentFrame.fbCount = 0; 435 mCurrentFrame.fbZ = -1; 436 memset(&mCurrentFrame.isFBComposed, 0, sizeof(mCurrentFrame.isFBComposed)); 437 438 int mdpCount = mCurrentFrame.mdpCount; 439 if(mdpCount > sMaxPipesPerMixer) { 440 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__); 441 return false; 442 } 443 444 int numPipesNeeded = pipesNeeded(ctx, list); 445 int availPipes = getAvailablePipes(ctx); 446 447 if(numPipesNeeded > availPipes) { 448 ALOGD_IF(isDebug(), "%s: Insufficient MDP pipes, needed %d, avail %d", 449 __FUNCTION__, numPipesNeeded, availPipes); 450 return false; 451 } 452 453 return true; 454 } 455 456 bool MDPComp::partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list) 457 { 458 int numAppLayers = ctx->listStats[mDpy].numAppLayers; 459 //Setup mCurrentFrame 460 mCurrentFrame.reset(numAppLayers); 461 updateLayerCache(ctx, list); 462 updateYUV(ctx, list); 463 batchLayers(); //sets up fbZ also 464 465 int mdpCount = mCurrentFrame.mdpCount; 466 if(mdpCount > (sMaxPipesPerMixer - 1)) { // -1 since FB is used 467 ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__); 468 return false; 469 } 470 471 int numPipesNeeded = pipesNeeded(ctx, list); 472 int availPipes = getAvailablePipes(ctx); 473 474 if(numPipesNeeded > availPipes) { 475 ALOGD_IF(isDebug(), "%s: Insufficient MDP pipes, needed %d, avail %d", 476 __FUNCTION__, numPipesNeeded, availPipes); 477 return false; 478 } 479 480 return true; 481 } 482 483 bool 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 int numPipesNeeded = pipesNeeded(ctx, list); 504 int availPipes = getAvailablePipes(ctx); 505 if(numPipesNeeded > availPipes) { 506 ALOGD_IF(isDebug(), "%s: Insufficient MDP pipes, needed %d, avail %d", 507 __FUNCTION__, numPipesNeeded, availPipes); 508 return false; 509 } 510 511 int nYuvCount = ctx->listStats[mDpy].yuvCount; 512 for(int index = 0; index < nYuvCount ; index ++) { 513 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index]; 514 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex]; 515 if(layer->planeAlpha < 0xFF) { 516 ALOGD_IF(isDebug(), "%s: Cannot handle YUV layer with plane alpha\ 517 when sandwiched", 518 __FUNCTION__); 519 return false; 520 } 521 } 522 523 return true; 524 } 525 526 /* Checks for conditions where YUV layers cannot be bypassed */ 527 bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) { 528 529 if(isSkipLayer(layer)) { 530 ALOGE("%s: Unable to bypass skipped YUV", __FUNCTION__); 531 return false; 532 } 533 534 if(ctx->mNeedsRotator && ctx->mDMAInUse) { 535 ALOGE("%s: No DMA for Rotator",__FUNCTION__); 536 return false; 537 } 538 539 if(isSecuring(ctx, layer)) { 540 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__); 541 return false; 542 } 543 544 if(!isValidDimension(ctx, layer)) { 545 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width", 546 __FUNCTION__); 547 return false; 548 } 549 550 return true; 551 } 552 553 void MDPComp::batchLayers() { 554 /* Idea is to keep as many contiguous non-updating(cached) layers in FB and 555 * send rest of them through MDP. NEVER mark an updating layer for caching. 556 * But cached ones can be marked for MDP*/ 557 558 int maxBatchStart = -1; 559 int maxBatchCount = 0; 560 561 /* All or Nothing is cached. No batching needed */ 562 if(!mCurrentFrame.fbCount) { 563 mCurrentFrame.fbZ = -1; 564 return; 565 } 566 if(!mCurrentFrame.mdpCount) { 567 mCurrentFrame.fbZ = 0; 568 return; 569 } 570 571 /* Search for max number of contiguous (cached) layers */ 572 int i = 0; 573 while (i < mCurrentFrame.layerCount) { 574 int count = 0; 575 while(mCurrentFrame.isFBComposed[i] && i < mCurrentFrame.layerCount) { 576 count++; i++; 577 } 578 if(count > maxBatchCount) { 579 maxBatchCount = count; 580 maxBatchStart = i - count; 581 mCurrentFrame.fbZ = maxBatchStart; 582 } 583 if(i < mCurrentFrame.layerCount) i++; 584 } 585 586 /* reset rest of the layers for MDP comp */ 587 for(int i = 0; i < mCurrentFrame.layerCount; i++) { 588 if(i != maxBatchStart){ 589 mCurrentFrame.isFBComposed[i] = false; 590 } else { 591 i += maxBatchCount; 592 } 593 } 594 595 mCurrentFrame.fbCount = maxBatchCount; 596 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - 597 mCurrentFrame.fbCount; 598 599 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__, 600 mCurrentFrame.fbCount); 601 } 602 603 void MDPComp::updateLayerCache(hwc_context_t* ctx, 604 hwc_display_contents_1_t* list) { 605 606 int numAppLayers = ctx->listStats[mDpy].numAppLayers; 607 int numCacheableLayers = 0; 608 609 for(int i = 0; i < numAppLayers; i++) { 610 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) { 611 numCacheableLayers++; 612 mCurrentFrame.isFBComposed[i] = true; 613 } else { 614 mCurrentFrame.isFBComposed[i] = false; 615 mCachedFrame.hnd[i] = list->hwLayers[i].handle; 616 } 617 } 618 619 mCurrentFrame.fbCount = numCacheableLayers; 620 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - 621 mCurrentFrame.fbCount; 622 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__, numCacheableLayers); 623 } 624 625 int MDPComp::getAvailablePipes(hwc_context_t* ctx) { 626 int numDMAPipes = qdutils::MDPVersion::getInstance().getDMAPipes(); 627 overlay::Overlay& ov = *ctx->mOverlay; 628 629 int numAvailable = ov.availablePipes(mDpy); 630 631 //Reserve DMA for rotator 632 if(ctx->mNeedsRotator) 633 numAvailable -= numDMAPipes; 634 635 //Reserve pipe(s)for FB 636 if(mCurrentFrame.fbCount) 637 numAvailable -= pipesForFB(); 638 639 return numAvailable; 640 } 641 642 void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list) { 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 649 if(!isYUVDoable(ctx, layer)) { 650 if(!mCurrentFrame.isFBComposed[nYuvIndex]) { 651 mCurrentFrame.isFBComposed[nYuvIndex] = true; 652 mCurrentFrame.fbCount++; 653 } 654 } else { 655 if(mCurrentFrame.isFBComposed[nYuvIndex]) { 656 mCurrentFrame.isFBComposed[nYuvIndex] = false; 657 mCurrentFrame.fbCount--; 658 } 659 } 660 } 661 662 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - 663 mCurrentFrame.fbCount; 664 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__, 665 mCurrentFrame.fbCount); 666 } 667 668 bool MDPComp::programMDP(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 669 ctx->mDMAInUse = false; 670 if(!allocLayerPipes(ctx, list)) { 671 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__); 672 return false; 673 } 674 675 bool fbBatch = false; 676 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount; 677 index++) { 678 if(!mCurrentFrame.isFBComposed[index]) { 679 int mdpIndex = mCurrentFrame.layerToMDP[index]; 680 hwc_layer_1_t* layer = &list->hwLayers[index]; 681 682 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo; 683 cur_pipe->zOrder = mdpNextZOrder++; 684 685 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){ 686 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \ 687 layer %d",__FUNCTION__, index); 688 return false; 689 } 690 } else if(fbBatch == false) { 691 mdpNextZOrder++; 692 fbBatch = true; 693 } 694 } 695 696 return true; 697 } 698 699 bool MDPComp::programYUV(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 700 if(!allocLayerPipes(ctx, list)) { 701 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__); 702 return false; 703 } 704 //If we are in this block, it means we have yuv + rgb layers both 705 int mdpIdx = 0; 706 for (int index = 0; index < mCurrentFrame.layerCount; index++) { 707 if(!mCurrentFrame.isFBComposed[index]) { 708 hwc_layer_1_t* layer = &list->hwLayers[index]; 709 int mdpIndex = mCurrentFrame.layerToMDP[index]; 710 MdpPipeInfo* cur_pipe = 711 mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo; 712 cur_pipe->zOrder = mdpIdx++; 713 714 if(configure(ctx, layer, 715 mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){ 716 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \ 717 layer %d",__FUNCTION__, index); 718 return false; 719 } 720 } 721 } 722 return true; 723 } 724 725 int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 726 727 //reset old data 728 const int numLayers = ctx->listStats[mDpy].numAppLayers; 729 mCurrentFrame.reset(numLayers); 730 731 //Hard conditions, if not met, cannot do MDP comp 732 if(!isFrameDoable(ctx)) { 733 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame", 734 __FUNCTION__); 735 mCurrentFrame.reset(numLayers); 736 mCachedFrame.cacheAll(list); 737 mCachedFrame.updateCounts(mCurrentFrame); 738 return 0; 739 } 740 741 //Check whether layers marked for MDP Composition is actually doable. 742 if(isFullFrameDoable(ctx, list)){ 743 mCurrentFrame.map(); 744 //Acquire and Program MDP pipes 745 if(!programMDP(ctx, list)) { 746 mCurrentFrame.reset(numLayers); 747 mCachedFrame.cacheAll(list); 748 } else { //Success 749 //Any change in composition types needs an FB refresh 750 mCurrentFrame.needsRedraw = false; 751 if(mCurrentFrame.fbCount && 752 ((mCurrentFrame.mdpCount != mCachedFrame.mdpCount) || 753 (mCurrentFrame.fbCount != mCachedFrame.cacheCount) || 754 (mCurrentFrame.fbZ != mCachedFrame.fbZ) || 755 (!mCurrentFrame.mdpCount) || 756 (list->flags & HWC_GEOMETRY_CHANGED) || 757 isSkipPresent(ctx, mDpy) || 758 (mDpy > HWC_DISPLAY_PRIMARY))) { 759 mCurrentFrame.needsRedraw = true; 760 } 761 } 762 } else if(isOnlyVideoDoable(ctx, list)) { 763 //All layers marked for MDP comp cannot be bypassed. 764 //Try to compose atleast YUV layers through MDP comp and let 765 //all the RGB layers compose in FB 766 //Destination over 767 mCurrentFrame.fbZ = -1; 768 if(mCurrentFrame.fbCount) 769 mCurrentFrame.fbZ = ctx->listStats[mDpy].yuvCount; 770 771 mCurrentFrame.map(); 772 if(!programYUV(ctx, list)) { 773 mCurrentFrame.reset(numLayers); 774 mCachedFrame.cacheAll(list); 775 } 776 } else { 777 mCurrentFrame.reset(numLayers); 778 mCachedFrame.cacheAll(list); 779 } 780 781 //UpdateLayerFlags 782 setMDPCompLayerFlags(ctx, list); 783 mCachedFrame.updateCounts(mCurrentFrame); 784 785 if(isDebug()) { 786 ALOGD("GEOMETRY change: %d", (list->flags & HWC_GEOMETRY_CHANGED)); 787 android::String8 sDump(""); 788 dump(sDump); 789 ALOGE("%s",sDump.string()); 790 } 791 792 return mCurrentFrame.fbZ; 793 } 794 795 //=============MDPCompLowRes=================================================== 796 797 /* 798 * Configures pipe(s) for MDP composition 799 */ 800 int MDPCompLowRes::configure(hwc_context_t *ctx, hwc_layer_1_t *layer, 801 PipeLayerPair& PipeLayerPair) { 802 MdpPipeInfoLowRes& mdp_info = 803 *(static_cast<MdpPipeInfoLowRes*>(PipeLayerPair.pipeInfo)); 804 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION; 805 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder); 806 eIsFg isFg = IS_FG_OFF; 807 eDest dest = mdp_info.index; 808 809 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d", 810 __FUNCTION__, layer, zOrder, dest); 811 812 return configureLowRes(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest, 813 &PipeLayerPair.rot); 814 } 815 816 int MDPCompLowRes::pipesNeeded(hwc_context_t *ctx, 817 hwc_display_contents_1_t* list) { 818 return mCurrentFrame.mdpCount; 819 } 820 821 bool MDPCompLowRes::allocLayerPipes(hwc_context_t *ctx, 822 hwc_display_contents_1_t* list) { 823 if(isYuvPresent(ctx, mDpy)) { 824 int nYuvCount = ctx->listStats[mDpy].yuvCount; 825 826 for(int index = 0; index < nYuvCount ; index ++) { 827 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index]; 828 829 if(mCurrentFrame.isFBComposed[nYuvIndex]) 830 continue; 831 832 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex]; 833 834 int mdpIndex = mCurrentFrame.layerToMDP[nYuvIndex]; 835 836 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex]; 837 info.pipeInfo = new MdpPipeInfoLowRes; 838 info.rot = NULL; 839 MdpPipeInfoLowRes& pipe_info = *(MdpPipeInfoLowRes*)info.pipeInfo; 840 841 pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_VG); 842 if(pipe_info.index == ovutils::OV_INVALID) { 843 ALOGD_IF(isDebug(), "%s: Unable to get pipe for Videos", 844 __FUNCTION__); 845 return false; 846 } 847 } 848 } 849 850 for(int index = 0 ; index < mCurrentFrame.layerCount; index++ ) { 851 if(mCurrentFrame.isFBComposed[index]) continue; 852 hwc_layer_1_t* layer = &list->hwLayers[index]; 853 private_handle_t *hnd = (private_handle_t *)layer->handle; 854 855 if(isYuvBuffer(hnd)) 856 continue; 857 858 int mdpIndex = mCurrentFrame.layerToMDP[index]; 859 860 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex]; 861 info.pipeInfo = new MdpPipeInfoLowRes; 862 info.rot = NULL; 863 MdpPipeInfoLowRes& pipe_info = *(MdpPipeInfoLowRes*)info.pipeInfo; 864 865 ePipeType type = MDPCOMP_OV_ANY; 866 867 if(!qhwc::needsScaling(layer) && !ctx->mNeedsRotator 868 && ctx->mMDP.version >= qdutils::MDSS_V5) { 869 type = MDPCOMP_OV_DMA; 870 } 871 872 pipe_info.index = getMdpPipe(ctx, type); 873 if(pipe_info.index == ovutils::OV_INVALID) { 874 ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__); 875 return false; 876 } 877 } 878 return true; 879 } 880 881 bool MDPCompLowRes::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 882 883 if(!isEnabled()) { 884 ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__); 885 return true; 886 } 887 888 if(!ctx || !list) { 889 ALOGE("%s: invalid contxt or list",__FUNCTION__); 890 return false; 891 } 892 893 /* reset Invalidator */ 894 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) 895 idleInvalidator->markForSleep(); 896 897 overlay::Overlay& ov = *ctx->mOverlay; 898 LayerProp *layerProp = ctx->layerProp[mDpy]; 899 900 int numHwLayers = ctx->listStats[mDpy].numAppLayers; 901 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ ) 902 { 903 if(mCurrentFrame.isFBComposed[i]) continue; 904 905 hwc_layer_1_t *layer = &list->hwLayers[i]; 906 private_handle_t *hnd = (private_handle_t *)layer->handle; 907 if(!hnd) { 908 ALOGE("%s handle null", __FUNCTION__); 909 return false; 910 } 911 912 int mdpIndex = mCurrentFrame.layerToMDP[i]; 913 914 MdpPipeInfoLowRes& pipe_info = 915 *(MdpPipeInfoLowRes*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo; 916 ovutils::eDest dest = pipe_info.index; 917 if(dest == ovutils::OV_INVALID) { 918 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest); 919 return false; 920 } 921 922 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) { 923 continue; 924 } 925 926 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \ 927 using pipe: %d", __FUNCTION__, layer, 928 hnd, dest ); 929 930 int fd = hnd->fd; 931 uint32_t offset = hnd->offset; 932 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot; 933 if(rot) { 934 if(!rot->queueBuffer(fd, offset)) 935 return false; 936 fd = rot->getDstMemId(); 937 offset = rot->getDstOffset(); 938 } 939 940 if (!ov.queueBuffer(fd, offset, dest)) { 941 ALOGE("%s: queueBuffer failed for external", __FUNCTION__); 942 return false; 943 } 944 945 layerProp[i].mFlags &= ~HWC_MDPCOMP; 946 } 947 return true; 948 } 949 950 //=============MDPCompHighRes=================================================== 951 952 int MDPCompHighRes::pipesNeeded(hwc_context_t *ctx, 953 hwc_display_contents_1_t* list) { 954 int pipesNeeded = 0; 955 int hw_w = ctx->dpyAttr[mDpy].xres; 956 957 for(int i = 0; i < mCurrentFrame.layerCount; ++i) { 958 if(!mCurrentFrame.isFBComposed[i]) { 959 hwc_layer_1_t* layer = &list->hwLayers[i]; 960 hwc_rect_t dst = layer->displayFrame; 961 if(dst.left > hw_w/2) { 962 pipesNeeded++; 963 } else if(dst.right <= hw_w/2) { 964 pipesNeeded++; 965 } else { 966 pipesNeeded += 2; 967 } 968 } 969 } 970 return pipesNeeded; 971 } 972 973 bool MDPCompHighRes::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer, 974 MdpPipeInfoHighRes& pipe_info, 975 ePipeType type) { 976 int hw_w = ctx->dpyAttr[mDpy].xres; 977 978 hwc_rect_t dst = layer->displayFrame; 979 if(dst.left > hw_w/2) { 980 pipe_info.lIndex = ovutils::OV_INVALID; 981 pipe_info.rIndex = getMdpPipe(ctx, type); 982 if(pipe_info.rIndex == ovutils::OV_INVALID) 983 return false; 984 } else if (dst.right <= hw_w/2) { 985 pipe_info.rIndex = ovutils::OV_INVALID; 986 pipe_info.lIndex = getMdpPipe(ctx, type); 987 if(pipe_info.lIndex == ovutils::OV_INVALID) 988 return false; 989 } else { 990 pipe_info.rIndex = getMdpPipe(ctx, type); 991 pipe_info.lIndex = getMdpPipe(ctx, type); 992 if(pipe_info.rIndex == ovutils::OV_INVALID || 993 pipe_info.lIndex == ovutils::OV_INVALID) 994 return false; 995 } 996 return true; 997 } 998 999 bool MDPCompHighRes::allocLayerPipes(hwc_context_t *ctx, 1000 hwc_display_contents_1_t* list) { 1001 overlay::Overlay& ov = *ctx->mOverlay; 1002 int layer_count = ctx->listStats[mDpy].numAppLayers; 1003 1004 if(isYuvPresent(ctx, mDpy)) { 1005 int nYuvCount = ctx->listStats[mDpy].yuvCount; 1006 1007 for(int index = 0; index < nYuvCount; index ++) { 1008 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index]; 1009 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex]; 1010 PipeLayerPair& info = mCurrentFrame.mdpToLayer[nYuvIndex]; 1011 info.pipeInfo = new MdpPipeInfoHighRes; 1012 info.rot = NULL; 1013 MdpPipeInfoHighRes& pipe_info = *(MdpPipeInfoHighRes*)info.pipeInfo; 1014 if(!acquireMDPPipes(ctx, layer, pipe_info,MDPCOMP_OV_VG)) { 1015 ALOGD_IF(isDebug(),"%s: Unable to get pipe for videos", 1016 __FUNCTION__); 1017 //TODO: windback pipebook data on fail 1018 return false; 1019 } 1020 pipe_info.zOrder = nYuvIndex; 1021 } 1022 } 1023 1024 for(int index = 0 ; index < layer_count ; index++ ) { 1025 hwc_layer_1_t* layer = &list->hwLayers[index]; 1026 private_handle_t *hnd = (private_handle_t *)layer->handle; 1027 1028 if(isYuvBuffer(hnd)) 1029 continue; 1030 1031 PipeLayerPair& info = mCurrentFrame.mdpToLayer[index]; 1032 info.pipeInfo = new MdpPipeInfoHighRes; 1033 info.rot = NULL; 1034 MdpPipeInfoHighRes& pipe_info = *(MdpPipeInfoHighRes*)info.pipeInfo; 1035 1036 ePipeType type = MDPCOMP_OV_ANY; 1037 1038 if(!qhwc::needsScaling(layer) && !ctx->mNeedsRotator 1039 && ctx->mMDP.version >= qdutils::MDSS_V5) 1040 type = MDPCOMP_OV_DMA; 1041 1042 if(!acquireMDPPipes(ctx, layer, pipe_info, type)) { 1043 ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__); 1044 //TODO: windback pipebook data on fail 1045 return false; 1046 } 1047 pipe_info.zOrder = index; 1048 } 1049 return true; 1050 } 1051 /* 1052 * Configures pipe(s) for MDP composition 1053 */ 1054 int 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 1071 bool 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 /* reset Invalidator */ 1084 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) 1085 idleInvalidator->markForSleep(); 1086 1087 overlay::Overlay& ov = *ctx->mOverlay; 1088 LayerProp *layerProp = ctx->layerProp[mDpy]; 1089 1090 int numHwLayers = ctx->listStats[mDpy].numAppLayers; 1091 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ ) 1092 { 1093 if(mCurrentFrame.isFBComposed[i]) continue; 1094 1095 hwc_layer_1_t *layer = &list->hwLayers[i]; 1096 private_handle_t *hnd = (private_handle_t *)layer->handle; 1097 if(!hnd) { 1098 ALOGE("%s handle null", __FUNCTION__); 1099 return false; 1100 } 1101 1102 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) { 1103 continue; 1104 } 1105 1106 int mdpIndex = mCurrentFrame.layerToMDP[i]; 1107 1108 MdpPipeInfoHighRes& pipe_info = 1109 *(MdpPipeInfoHighRes*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo; 1110 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot; 1111 1112 ovutils::eDest indexL = pipe_info.lIndex; 1113 ovutils::eDest indexR = pipe_info.rIndex; 1114 1115 int fd = hnd->fd; 1116 int offset = hnd->offset; 1117 1118 if(rot) { 1119 rot->queueBuffer(fd, offset); 1120 fd = rot->getDstMemId(); 1121 offset = rot->getDstOffset(); 1122 } 1123 1124 //************* play left mixer ********** 1125 if(indexL != ovutils::OV_INVALID) { 1126 ovutils::eDest destL = (ovutils::eDest)indexL; 1127 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \ 1128 using pipe: %d", __FUNCTION__, layer, hnd, indexL ); 1129 if (!ov.queueBuffer(fd, offset, destL)) { 1130 ALOGE("%s: queueBuffer failed for left mixer", __FUNCTION__); 1131 return false; 1132 } 1133 } 1134 1135 //************* play right mixer ********** 1136 if(indexR != ovutils::OV_INVALID) { 1137 ovutils::eDest destR = (ovutils::eDest)indexR; 1138 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \ 1139 using pipe: %d", __FUNCTION__, layer, hnd, indexR ); 1140 if (!ov.queueBuffer(fd, offset, destR)) { 1141 ALOGE("%s: queueBuffer failed for right mixer", __FUNCTION__); 1142 return false; 1143 } 1144 } 1145 1146 layerProp[i].mFlags &= ~HWC_MDPCOMP; 1147 } 1148 1149 return true; 1150 } 1151 }; //namespace 1152 1153