hwc_mdpcomp.cpp revision 513ddc2124abf90c63af41999201f0d2031af0c8
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 return true; 507} 508 509/* Checks for conditions where YUV layers cannot be bypassed */ 510bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) { 511 512 if(isSkipLayer(layer)) { 513 ALOGE("%s: Unable to bypass skipped YUV", __FUNCTION__); 514 return false; 515 } 516 517 if(ctx->mNeedsRotator && ctx->mDMAInUse) { 518 ALOGE("%s: No DMA for Rotator",__FUNCTION__); 519 return false; 520 } 521 522 if(isSecuring(ctx, layer)) { 523 ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__); 524 return false; 525 } 526 527 if(!isValidDimension(ctx, layer)) { 528 ALOGD_IF(isDebug(), "%s: Buffer is of invalid width", 529 __FUNCTION__); 530 return false; 531 } 532 533 return true; 534} 535 536void MDPComp::batchLayers() { 537 /* Idea is to keep as many contiguous non-updating(cached) layers in FB and 538 * send rest of them through MDP. NEVER mark an updating layer for caching. 539 * But cached ones can be marked for MDP*/ 540 541 int maxBatchStart = -1; 542 int maxBatchCount = 0; 543 544 /* All or Nothing is cached. No batching needed */ 545 if(!mCurrentFrame.fbCount) { 546 mCurrentFrame.fbZ = -1; 547 return; 548 } 549 if(!mCurrentFrame.mdpCount) { 550 mCurrentFrame.fbZ = 0; 551 return; 552 } 553 554 /* Search for max number of contiguous (cached) layers */ 555 int i = 0; 556 while (i < mCurrentFrame.layerCount) { 557 int count = 0; 558 while(mCurrentFrame.isFBComposed[i] && i < mCurrentFrame.layerCount) { 559 count++; i++; 560 } 561 if(count > maxBatchCount) { 562 maxBatchCount = count; 563 maxBatchStart = i - count; 564 mCurrentFrame.fbZ = maxBatchStart; 565 } 566 if(i < mCurrentFrame.layerCount) i++; 567 } 568 569 /* reset rest of the layers for MDP comp */ 570 for(int i = 0; i < mCurrentFrame.layerCount; i++) { 571 if(i != maxBatchStart){ 572 mCurrentFrame.isFBComposed[i] = false; 573 } else { 574 i += maxBatchCount; 575 } 576 } 577 578 mCurrentFrame.fbCount = maxBatchCount; 579 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - 580 mCurrentFrame.fbCount; 581 582 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__, 583 mCurrentFrame.fbCount); 584} 585 586void MDPComp::updateLayerCache(hwc_context_t* ctx, 587 hwc_display_contents_1_t* list) { 588 589 int numAppLayers = ctx->listStats[mDpy].numAppLayers; 590 int numCacheableLayers = 0; 591 592 for(int i = 0; i < numAppLayers; i++) { 593 if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) { 594 numCacheableLayers++; 595 mCurrentFrame.isFBComposed[i] = true; 596 } else { 597 mCurrentFrame.isFBComposed[i] = false; 598 mCachedFrame.hnd[i] = list->hwLayers[i].handle; 599 } 600 } 601 602 mCurrentFrame.fbCount = numCacheableLayers; 603 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - 604 mCurrentFrame.fbCount; 605 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__, numCacheableLayers); 606} 607 608int MDPComp::getAvailablePipes(hwc_context_t* ctx) { 609 int numDMAPipes = qdutils::MDPVersion::getInstance().getDMAPipes(); 610 overlay::Overlay& ov = *ctx->mOverlay; 611 612 int numAvailable = ov.availablePipes(mDpy); 613 614 //Reserve DMA for rotator 615 if(ctx->mNeedsRotator) 616 numAvailable -= numDMAPipes; 617 618 //Reserve pipe(s)for FB 619 if(mCurrentFrame.fbCount) 620 numAvailable -= pipesForFB(); 621 622 return numAvailable; 623} 624 625void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list) { 626 627 int nYuvCount = ctx->listStats[mDpy].yuvCount; 628 for(int index = 0;index < nYuvCount; index++){ 629 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index]; 630 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex]; 631 632 if(!isYUVDoable(ctx, layer)) { 633 if(!mCurrentFrame.isFBComposed[nYuvIndex]) { 634 mCurrentFrame.isFBComposed[nYuvIndex] = true; 635 mCurrentFrame.fbCount++; 636 } 637 } else { 638 if(mCurrentFrame.isFBComposed[nYuvIndex]) { 639 mCurrentFrame.isFBComposed[nYuvIndex] = false; 640 mCurrentFrame.fbCount--; 641 } 642 } 643 } 644 645 mCurrentFrame.mdpCount = mCurrentFrame.layerCount - 646 mCurrentFrame.fbCount; 647 ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__, 648 mCurrentFrame.fbCount); 649} 650 651bool MDPComp::programMDP(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 652 ctx->mDMAInUse = false; 653 if(!allocLayerPipes(ctx, list)) { 654 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__); 655 return false; 656 } 657 658 bool fbBatch = false; 659 for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount; 660 index++) { 661 if(!mCurrentFrame.isFBComposed[index]) { 662 int mdpIndex = mCurrentFrame.layerToMDP[index]; 663 hwc_layer_1_t* layer = &list->hwLayers[index]; 664 665 MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo; 666 cur_pipe->zOrder = mdpNextZOrder++; 667 668 if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){ 669 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \ 670 layer %d",__FUNCTION__, index); 671 return false; 672 } 673 } else if(fbBatch == false) { 674 mdpNextZOrder++; 675 fbBatch = true; 676 } 677 } 678 679 return true; 680} 681 682bool MDPComp::programYUV(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 683 if(!allocLayerPipes(ctx, list)) { 684 ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__); 685 return false; 686 } 687 //If we are in this block, it means we have yuv + rgb layers both 688 int mdpIdx = 0; 689 for (int index = 0; index < mCurrentFrame.layerCount; index++) { 690 if(!mCurrentFrame.isFBComposed[index]) { 691 hwc_layer_1_t* layer = &list->hwLayers[index]; 692 int mdpIndex = mCurrentFrame.layerToMDP[index]; 693 MdpPipeInfo* cur_pipe = 694 mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo; 695 cur_pipe->zOrder = mdpIdx++; 696 697 if(configure(ctx, layer, 698 mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){ 699 ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \ 700 layer %d",__FUNCTION__, index); 701 return false; 702 } 703 } 704 } 705 return true; 706} 707 708int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 709 710 //reset old data 711 const int numLayers = ctx->listStats[mDpy].numAppLayers; 712 mCurrentFrame.reset(numLayers); 713 714 //Hard conditions, if not met, cannot do MDP comp 715 if(!isFrameDoable(ctx)) { 716 ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame", 717 __FUNCTION__); 718 mCurrentFrame.reset(numLayers); 719 mCachedFrame.cacheAll(list); 720 mCachedFrame.updateCounts(mCurrentFrame); 721 return 0; 722 } 723 724 //Check whether layers marked for MDP Composition is actually doable. 725 if(isFullFrameDoable(ctx, list)){ 726 mCurrentFrame.map(); 727 //Acquire and Program MDP pipes 728 if(!programMDP(ctx, list)) { 729 mCurrentFrame.reset(numLayers); 730 mCachedFrame.cacheAll(list); 731 } else { //Success 732 //Any change in composition types needs an FB refresh 733 mCurrentFrame.needsRedraw = false; 734 if(mCurrentFrame.fbCount && 735 ((mCurrentFrame.mdpCount != mCachedFrame.mdpCount) || 736 (mCurrentFrame.fbCount != mCachedFrame.cacheCount) || 737 (mCurrentFrame.fbZ != mCachedFrame.fbZ) || 738 (!mCurrentFrame.mdpCount) || 739 (list->flags & HWC_GEOMETRY_CHANGED) || 740 isSkipPresent(ctx, mDpy) || 741 (mDpy > HWC_DISPLAY_PRIMARY))) { 742 mCurrentFrame.needsRedraw = true; 743 } 744 } 745 } else if(isOnlyVideoDoable(ctx, list)) { 746 //All layers marked for MDP comp cannot be bypassed. 747 //Try to compose atleast YUV layers through MDP comp and let 748 //all the RGB layers compose in FB 749 //Destination over 750 mCurrentFrame.fbZ = -1; 751 if(mCurrentFrame.fbCount) 752 mCurrentFrame.fbZ = ctx->listStats[mDpy].yuvCount; 753 754 mCurrentFrame.map(); 755 if(!programYUV(ctx, list)) { 756 mCurrentFrame.reset(numLayers); 757 mCachedFrame.cacheAll(list); 758 } 759 } else { 760 mCurrentFrame.reset(numLayers); 761 mCachedFrame.cacheAll(list); 762 } 763 764 //UpdateLayerFlags 765 setMDPCompLayerFlags(ctx, list); 766 mCachedFrame.updateCounts(mCurrentFrame); 767 768 if(isDebug()) { 769 ALOGD("GEOMETRY change: %d", (list->flags & HWC_GEOMETRY_CHANGED)); 770 android::String8 sDump(""); 771 dump(sDump); 772 ALOGE("%s",sDump.string()); 773 } 774 775 return mCurrentFrame.fbZ; 776} 777 778//=============MDPCompLowRes=================================================== 779 780/* 781 * Configures pipe(s) for MDP composition 782 */ 783int MDPCompLowRes::configure(hwc_context_t *ctx, hwc_layer_1_t *layer, 784 PipeLayerPair& PipeLayerPair) { 785 MdpPipeInfoLowRes& mdp_info = 786 *(static_cast<MdpPipeInfoLowRes*>(PipeLayerPair.pipeInfo)); 787 eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION; 788 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder); 789 eIsFg isFg = IS_FG_OFF; 790 eDest dest = mdp_info.index; 791 792 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d", 793 __FUNCTION__, layer, zOrder, dest); 794 795 return configureLowRes(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest, 796 &PipeLayerPair.rot); 797} 798 799int MDPCompLowRes::pipesNeeded(hwc_context_t *ctx, 800 hwc_display_contents_1_t* list) { 801 return mCurrentFrame.mdpCount; 802} 803 804bool MDPCompLowRes::allocLayerPipes(hwc_context_t *ctx, 805 hwc_display_contents_1_t* list) { 806 if(isYuvPresent(ctx, mDpy)) { 807 int nYuvCount = ctx->listStats[mDpy].yuvCount; 808 809 for(int index = 0; index < nYuvCount ; index ++) { 810 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index]; 811 812 if(mCurrentFrame.isFBComposed[nYuvIndex]) 813 continue; 814 815 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex]; 816 817 int mdpIndex = mCurrentFrame.layerToMDP[nYuvIndex]; 818 819 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex]; 820 info.pipeInfo = new MdpPipeInfoLowRes; 821 info.rot = NULL; 822 MdpPipeInfoLowRes& pipe_info = *(MdpPipeInfoLowRes*)info.pipeInfo; 823 824 pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_VG); 825 if(pipe_info.index == ovutils::OV_INVALID) { 826 ALOGD_IF(isDebug(), "%s: Unable to get pipe for Videos", 827 __FUNCTION__); 828 return false; 829 } 830 } 831 } 832 833 for(int index = 0 ; index < mCurrentFrame.layerCount; index++ ) { 834 if(mCurrentFrame.isFBComposed[index]) continue; 835 hwc_layer_1_t* layer = &list->hwLayers[index]; 836 private_handle_t *hnd = (private_handle_t *)layer->handle; 837 838 if(isYuvBuffer(hnd)) 839 continue; 840 841 int mdpIndex = mCurrentFrame.layerToMDP[index]; 842 843 PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex]; 844 info.pipeInfo = new MdpPipeInfoLowRes; 845 info.rot = NULL; 846 MdpPipeInfoLowRes& pipe_info = *(MdpPipeInfoLowRes*)info.pipeInfo; 847 848 ePipeType type = MDPCOMP_OV_ANY; 849 850 if(!qhwc::needsScaling(layer) && !ctx->mNeedsRotator 851 && ctx->mMDP.version >= qdutils::MDSS_V5) { 852 type = MDPCOMP_OV_DMA; 853 } 854 855 pipe_info.index = getMdpPipe(ctx, type); 856 if(pipe_info.index == ovutils::OV_INVALID) { 857 ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__); 858 return false; 859 } 860 } 861 return true; 862} 863 864bool MDPCompLowRes::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 865 866 if(!isEnabled()) { 867 ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__); 868 return true; 869 } 870 871 if(!ctx || !list) { 872 ALOGE("%s: invalid contxt or list",__FUNCTION__); 873 return false; 874 } 875 876 /* reset Invalidator */ 877 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) 878 idleInvalidator->markForSleep(); 879 880 overlay::Overlay& ov = *ctx->mOverlay; 881 LayerProp *layerProp = ctx->layerProp[mDpy]; 882 883 int numHwLayers = ctx->listStats[mDpy].numAppLayers; 884 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ ) 885 { 886 if(mCurrentFrame.isFBComposed[i]) continue; 887 888 hwc_layer_1_t *layer = &list->hwLayers[i]; 889 private_handle_t *hnd = (private_handle_t *)layer->handle; 890 if(!hnd) { 891 ALOGE("%s handle null", __FUNCTION__); 892 return false; 893 } 894 895 int mdpIndex = mCurrentFrame.layerToMDP[i]; 896 897 MdpPipeInfoLowRes& pipe_info = 898 *(MdpPipeInfoLowRes*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo; 899 ovutils::eDest dest = pipe_info.index; 900 if(dest == ovutils::OV_INVALID) { 901 ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest); 902 return false; 903 } 904 905 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) { 906 continue; 907 } 908 909 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \ 910 using pipe: %d", __FUNCTION__, layer, 911 hnd, dest ); 912 913 int fd = hnd->fd; 914 uint32_t offset = hnd->offset; 915 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot; 916 if(rot) { 917 if(!rot->queueBuffer(fd, offset)) 918 return false; 919 fd = rot->getDstMemId(); 920 offset = rot->getDstOffset(); 921 } 922 923 if (!ov.queueBuffer(fd, offset, dest)) { 924 ALOGE("%s: queueBuffer failed for external", __FUNCTION__); 925 return false; 926 } 927 928 layerProp[i].mFlags &= ~HWC_MDPCOMP; 929 } 930 return true; 931} 932 933//=============MDPCompHighRes=================================================== 934 935int MDPCompHighRes::pipesNeeded(hwc_context_t *ctx, 936 hwc_display_contents_1_t* list) { 937 int pipesNeeded = 0; 938 int hw_w = ctx->dpyAttr[mDpy].xres; 939 940 for(int i = 0; i < mCurrentFrame.layerCount; ++i) { 941 if(!mCurrentFrame.isFBComposed[i]) { 942 hwc_layer_1_t* layer = &list->hwLayers[i]; 943 hwc_rect_t dst = layer->displayFrame; 944 if(dst.left > hw_w/2) { 945 pipesNeeded++; 946 } else if(dst.right <= hw_w/2) { 947 pipesNeeded++; 948 } else { 949 pipesNeeded += 2; 950 } 951 } 952 } 953 return pipesNeeded; 954} 955 956bool MDPCompHighRes::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer, 957 MdpPipeInfoHighRes& pipe_info, 958 ePipeType type) { 959 int hw_w = ctx->dpyAttr[mDpy].xres; 960 961 hwc_rect_t dst = layer->displayFrame; 962 if(dst.left > hw_w/2) { 963 pipe_info.lIndex = ovutils::OV_INVALID; 964 pipe_info.rIndex = getMdpPipe(ctx, type); 965 if(pipe_info.rIndex == ovutils::OV_INVALID) 966 return false; 967 } else if (dst.right <= hw_w/2) { 968 pipe_info.rIndex = ovutils::OV_INVALID; 969 pipe_info.lIndex = getMdpPipe(ctx, type); 970 if(pipe_info.lIndex == ovutils::OV_INVALID) 971 return false; 972 } else { 973 pipe_info.rIndex = getMdpPipe(ctx, type); 974 pipe_info.lIndex = getMdpPipe(ctx, type); 975 if(pipe_info.rIndex == ovutils::OV_INVALID || 976 pipe_info.lIndex == ovutils::OV_INVALID) 977 return false; 978 } 979 return true; 980} 981 982bool MDPCompHighRes::allocLayerPipes(hwc_context_t *ctx, 983 hwc_display_contents_1_t* list) { 984 overlay::Overlay& ov = *ctx->mOverlay; 985 int layer_count = ctx->listStats[mDpy].numAppLayers; 986 987 if(isYuvPresent(ctx, mDpy)) { 988 int nYuvCount = ctx->listStats[mDpy].yuvCount; 989 990 for(int index = 0; index < nYuvCount; index ++) { 991 int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index]; 992 hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex]; 993 PipeLayerPair& info = mCurrentFrame.mdpToLayer[nYuvIndex]; 994 info.pipeInfo = new MdpPipeInfoHighRes; 995 info.rot = NULL; 996 MdpPipeInfoHighRes& pipe_info = *(MdpPipeInfoHighRes*)info.pipeInfo; 997 if(!acquireMDPPipes(ctx, layer, pipe_info,MDPCOMP_OV_VG)) { 998 ALOGD_IF(isDebug(),"%s: Unable to get pipe for videos", 999 __FUNCTION__); 1000 //TODO: windback pipebook data on fail 1001 return false; 1002 } 1003 pipe_info.zOrder = nYuvIndex; 1004 } 1005 } 1006 1007 for(int index = 0 ; index < layer_count ; index++ ) { 1008 hwc_layer_1_t* layer = &list->hwLayers[index]; 1009 private_handle_t *hnd = (private_handle_t *)layer->handle; 1010 1011 if(isYuvBuffer(hnd)) 1012 continue; 1013 1014 PipeLayerPair& info = mCurrentFrame.mdpToLayer[index]; 1015 info.pipeInfo = new MdpPipeInfoHighRes; 1016 info.rot = NULL; 1017 MdpPipeInfoHighRes& pipe_info = *(MdpPipeInfoHighRes*)info.pipeInfo; 1018 1019 ePipeType type = MDPCOMP_OV_ANY; 1020 1021 if(!qhwc::needsScaling(layer) && !ctx->mNeedsRotator 1022 && ctx->mMDP.version >= qdutils::MDSS_V5) 1023 type = MDPCOMP_OV_DMA; 1024 1025 if(!acquireMDPPipes(ctx, layer, pipe_info, type)) { 1026 ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__); 1027 //TODO: windback pipebook data on fail 1028 return false; 1029 } 1030 pipe_info.zOrder = index; 1031 } 1032 return true; 1033} 1034/* 1035 * Configures pipe(s) for MDP composition 1036 */ 1037int MDPCompHighRes::configure(hwc_context_t *ctx, hwc_layer_1_t *layer, 1038 PipeLayerPair& PipeLayerPair) { 1039 MdpPipeInfoHighRes& mdp_info = 1040 *(static_cast<MdpPipeInfoHighRes*>(PipeLayerPair.pipeInfo)); 1041 eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder); 1042 eIsFg isFg = IS_FG_OFF; 1043 eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION; 1044 eDest lDest = mdp_info.lIndex; 1045 eDest rDest = mdp_info.rIndex; 1046 1047 ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d" 1048 "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest); 1049 1050 return configureHighRes(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest, 1051 rDest, &PipeLayerPair.rot); 1052} 1053 1054bool MDPCompHighRes::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 1055 1056 if(!isEnabled()) { 1057 ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__); 1058 return true; 1059 } 1060 1061 if(!ctx || !list) { 1062 ALOGE("%s: invalid contxt or list",__FUNCTION__); 1063 return false; 1064 } 1065 1066 /* reset Invalidator */ 1067 if(idleInvalidator && !sIdleFallBack && mCurrentFrame.mdpCount) 1068 idleInvalidator->markForSleep(); 1069 1070 overlay::Overlay& ov = *ctx->mOverlay; 1071 LayerProp *layerProp = ctx->layerProp[mDpy]; 1072 1073 int numHwLayers = ctx->listStats[mDpy].numAppLayers; 1074 for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ ) 1075 { 1076 if(mCurrentFrame.isFBComposed[i]) continue; 1077 1078 hwc_layer_1_t *layer = &list->hwLayers[i]; 1079 private_handle_t *hnd = (private_handle_t *)layer->handle; 1080 if(!hnd) { 1081 ALOGE("%s handle null", __FUNCTION__); 1082 return false; 1083 } 1084 1085 if(!(layerProp[i].mFlags & HWC_MDPCOMP)) { 1086 continue; 1087 } 1088 1089 int mdpIndex = mCurrentFrame.layerToMDP[i]; 1090 1091 MdpPipeInfoHighRes& pipe_info = 1092 *(MdpPipeInfoHighRes*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo; 1093 Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot; 1094 1095 ovutils::eDest indexL = pipe_info.lIndex; 1096 ovutils::eDest indexR = pipe_info.rIndex; 1097 1098 int fd = hnd->fd; 1099 int offset = hnd->offset; 1100 1101 if(rot) { 1102 rot->queueBuffer(fd, offset); 1103 fd = rot->getDstMemId(); 1104 offset = rot->getDstOffset(); 1105 } 1106 1107 //************* play left mixer ********** 1108 if(indexL != ovutils::OV_INVALID) { 1109 ovutils::eDest destL = (ovutils::eDest)indexL; 1110 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \ 1111 using pipe: %d", __FUNCTION__, layer, hnd, indexL ); 1112 if (!ov.queueBuffer(fd, offset, destL)) { 1113 ALOGE("%s: queueBuffer failed for left mixer", __FUNCTION__); 1114 return false; 1115 } 1116 } 1117 1118 //************* play right mixer ********** 1119 if(indexR != ovutils::OV_INVALID) { 1120 ovutils::eDest destR = (ovutils::eDest)indexR; 1121 ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \ 1122 using pipe: %d", __FUNCTION__, layer, hnd, indexR ); 1123 if (!ov.queueBuffer(fd, offset, destR)) { 1124 ALOGE("%s: queueBuffer failed for right mixer", __FUNCTION__); 1125 return false; 1126 } 1127 } 1128 1129 layerProp[i].mFlags &= ~HWC_MDPCOMP; 1130 } 1131 1132 return true; 1133} 1134}; //namespace 1135 1136