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