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