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