1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved. 4 * 5 * Not a Contribution, Apache license notifications and license are retained 6 * for attribution purposes only. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 #define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL) 21 #include <fcntl.h> 22 #include <errno.h> 23 24 #include <cutils/log.h> 25 #include <cutils/atomic.h> 26 #include <EGL/egl.h> 27 #include <utils/Trace.h> 28 #include <sys/ioctl.h> 29 #include <overlay.h> 30 #include <overlayRotator.h> 31 #include <overlayWriteback.h> 32 #include <mdp_version.h> 33 #include "hwc_utils.h" 34 #include "hwc_fbupdate.h" 35 #include "hwc_mdpcomp.h" 36 #include "hwc_dump_layers.h" 37 #include "external.h" 38 #include "hwc_copybit.h" 39 #include "hwc_ad.h" 40 #include "profiler.h" 41 #include "hwc_virtual.h" 42 43 using namespace qhwc; 44 using namespace overlay; 45 46 #define VSYNC_DEBUG 0 47 #define POWER_MODE_DEBUG 1 48 49 static int hwc_device_open(const struct hw_module_t* module, 50 const char* name, 51 struct hw_device_t** device); 52 53 static struct hw_module_methods_t hwc_module_methods = { 54 open: hwc_device_open 55 }; 56 57 static void reset_panel(struct hwc_composer_device_1* dev); 58 59 hwc_module_t HAL_MODULE_INFO_SYM = { 60 common: { 61 tag: HARDWARE_MODULE_TAG, 62 version_major: 2, 63 version_minor: 0, 64 id: HWC_HARDWARE_MODULE_ID, 65 name: "Qualcomm Hardware Composer Module", 66 author: "CodeAurora Forum", 67 methods: &hwc_module_methods, 68 dso: 0, 69 reserved: {0}, 70 } 71 }; 72 73 /* In case of non-hybrid WFD session, we are fooling SF by piggybacking on 74 * HDMI display ID for virtual. This helper is needed to differentiate their 75 * paths in HAL. 76 * TODO: Not needed once we have WFD client working on top of Google API's */ 77 78 static int getDpyforExternalDisplay(hwc_context_t *ctx, int dpy) { 79 if(dpy == HWC_DISPLAY_EXTERNAL && ctx->mVirtualonExtActive) 80 return HWC_DISPLAY_VIRTUAL; 81 return dpy; 82 } 83 84 /* 85 * Save callback functions registered to HWC 86 */ 87 static void hwc_registerProcs(struct hwc_composer_device_1* dev, 88 hwc_procs_t const* procs) 89 { 90 ALOGI("%s", __FUNCTION__); 91 hwc_context_t* ctx = (hwc_context_t*)(dev); 92 if(!ctx) { 93 ALOGE("%s: Invalid context", __FUNCTION__); 94 return; 95 } 96 ctx->proc = procs; 97 98 // Now that we have the functions needed, kick off 99 // the uevent & vsync threads 100 init_uevent_thread(ctx); 101 init_vsync_thread(ctx); 102 } 103 104 static void setPaddingRound(hwc_context_t *ctx, int numDisplays, 105 hwc_display_contents_1_t** displays) { 106 ctx->isPaddingRound = false; 107 for(int i = 0; i < numDisplays; i++) { 108 hwc_display_contents_1_t *list = displays[i]; 109 if (LIKELY(list && list->numHwLayers > 0)) { 110 if((ctx->mPrevHwLayerCount[i] == 1 or 111 ctx->mPrevHwLayerCount[i] == 0) and 112 (list->numHwLayers > 1)) { 113 /* If the previous cycle for dpy 'i' has 0 AppLayers and the 114 * current cycle has atleast 1 AppLayer, padding round needs 115 * to be invoked in current cycle on all the active displays 116 * to free up the resources. 117 */ 118 ctx->isPaddingRound = true; 119 } 120 ctx->mPrevHwLayerCount[i] = (int)list->numHwLayers; 121 } else { 122 ctx->mPrevHwLayerCount[i] = 0; 123 } 124 } 125 } 126 127 /* Based on certain conditions, isPaddingRound will be set 128 * to make this function self-contained */ 129 static void setDMAState(hwc_context_t *ctx, int numDisplays, 130 hwc_display_contents_1_t** displays) { 131 132 if(ctx->mRotMgr->getNumActiveSessions() == 0) 133 Overlay::setDMAMode(Overlay::DMA_LINE_MODE); 134 135 for(int dpy = 0; dpy < numDisplays; dpy++) { 136 hwc_display_contents_1_t *list = displays[dpy]; 137 if (LIKELY(list && list->numHwLayers > 0)) { 138 for(size_t layerIndex = 0; layerIndex < list->numHwLayers; 139 layerIndex++) { 140 if(list->hwLayers[layerIndex].compositionType != 141 HWC_FRAMEBUFFER_TARGET) 142 { 143 hwc_layer_1_t const* layer = &list->hwLayers[layerIndex]; 144 private_handle_t *hnd = (private_handle_t *)layer->handle; 145 146 /* If a layer requires rotation, set the DMA state 147 * to BLOCK_MODE */ 148 149 if (canUseRotator(ctx, dpy) && 150 has90Transform(layer) && isRotationDoable(ctx, hnd)) { 151 if(not ctx->mOverlay->isDMAMultiplexingSupported()) { 152 if(ctx->mOverlay->isPipeTypeAttached( 153 overlay::utils::OV_MDP_PIPE_DMA)) 154 ctx->isPaddingRound = true; 155 } 156 Overlay::setDMAMode(Overlay::DMA_BLOCK_MODE); 157 } 158 } 159 } 160 if(dpy) { 161 /* Uncomment the below code for testing purpose. 162 Assuming the orientation value is in terms of HAL_TRANSFORM, 163 this needs mapping to HAL, if its in different convention */ 164 165 /* char value[PROPERTY_VALUE_MAX]; 166 property_get("sys.ext_orientation", value, "0"); 167 ctx->mExtOrientation = atoi(value);*/ 168 169 if(ctx->mExtOrientation || ctx->mBufferMirrorMode) { 170 if(ctx->mOverlay->isPipeTypeAttached( 171 overlay::utils::OV_MDP_PIPE_DMA)) { 172 ctx->isPaddingRound = true; 173 } 174 Overlay::setDMAMode(Overlay::DMA_BLOCK_MODE); 175 } 176 } 177 } 178 } 179 } 180 181 static void setNumActiveDisplays(hwc_context_t *ctx, int numDisplays, 182 hwc_display_contents_1_t** displays) { 183 184 ctx->numActiveDisplays = 0; 185 for(int i = 0; i < numDisplays; i++) { 186 hwc_display_contents_1_t *list = displays[i]; 187 if (LIKELY(list && list->numHwLayers > 0)) { 188 /* For display devices like SSD and screenrecord, we cannot 189 * rely on isActive and connected attributes of dpyAttr to 190 * determine if the displaydevice is active. Hence in case if 191 * the layer-list is non-null and numHwLayers > 0, we assume 192 * the display device to be active. 193 */ 194 ctx->numActiveDisplays += 1; 195 } 196 } 197 } 198 199 static void reset(hwc_context_t *ctx, int numDisplays, 200 hwc_display_contents_1_t** displays) { 201 202 203 for(int i = 0; i < numDisplays; i++) { 204 hwc_display_contents_1_t *list = displays[i]; 205 // XXX:SurfaceFlinger no longer guarantees that this 206 // value is reset on every prepare. However, for the layer 207 // cache we need to reset it. 208 // We can probably rethink that later on 209 if (LIKELY(list && list->numHwLayers > 0)) { 210 for(size_t j = 0; j < list->numHwLayers; j++) { 211 if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET) 212 list->hwLayers[j].compositionType = HWC_FRAMEBUFFER; 213 } 214 215 } 216 217 if(ctx->mMDPComp[i]) 218 ctx->mMDPComp[i]->reset(); 219 if(ctx->mFBUpdate[i]) 220 ctx->mFBUpdate[i]->reset(); 221 if(ctx->mCopyBit[i]) 222 ctx->mCopyBit[i]->reset(); 223 if(ctx->mLayerRotMap[i]) 224 ctx->mLayerRotMap[i]->reset(); 225 } 226 227 ctx->mAD->reset(); 228 if(ctx->mHWCVirtual) 229 ctx->mHWCVirtual->destroy(ctx, numDisplays, displays); 230 } 231 232 static void scaleDisplayFrame(hwc_context_t *ctx, int dpy, 233 hwc_display_contents_1_t *list) { 234 uint32_t origXres = ctx->dpyAttr[dpy].xres; 235 uint32_t origYres = ctx->dpyAttr[dpy].yres; 236 uint32_t newXres = ctx->dpyAttr[dpy].xres_new; 237 uint32_t newYres = ctx->dpyAttr[dpy].yres_new; 238 float xresRatio = (float)origXres / (float)newXres; 239 float yresRatio = (float)origYres / (float)newYres; 240 for (size_t i = 0; i < list->numHwLayers; i++) { 241 hwc_layer_1_t *layer = &list->hwLayers[i]; 242 hwc_rect_t& displayFrame = layer->displayFrame; 243 hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf); 244 uint32_t layerWidth = displayFrame.right - displayFrame.left; 245 uint32_t layerHeight = displayFrame.bottom - displayFrame.top; 246 displayFrame.left = (int)(xresRatio * (float)displayFrame.left); 247 displayFrame.top = (int)(yresRatio * (float)displayFrame.top); 248 displayFrame.right = (int)((float)displayFrame.left + 249 (float)layerWidth * xresRatio); 250 displayFrame.bottom = (int)((float)displayFrame.top + 251 (float)layerHeight * yresRatio); 252 } 253 } 254 255 static int hwc_prepare_primary(hwc_composer_device_1 *dev, 256 hwc_display_contents_1_t *list) { 257 ATRACE_CALL(); 258 hwc_context_t* ctx = (hwc_context_t*)(dev); 259 const int dpy = HWC_DISPLAY_PRIMARY; 260 bool fbComp = false; 261 if (LIKELY(list && list->numHwLayers > 1) && 262 ctx->dpyAttr[dpy].isActive) { 263 264 if (ctx->dpyAttr[dpy].customFBSize && 265 list->flags & HWC_GEOMETRY_CHANGED) 266 scaleDisplayFrame(ctx, dpy, list); 267 268 reset_layer_prop(ctx, dpy, (int)list->numHwLayers - 1); 269 setListStats(ctx, list, dpy); 270 271 fbComp = (ctx->mMDPComp[dpy]->prepare(ctx, list) < 0); 272 273 if (fbComp) { 274 const int fbZ = 0; 275 if(not ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ)) { 276 ctx->mOverlay->clear(dpy); 277 ctx->mLayerRotMap[dpy]->clear(); 278 } 279 } 280 281 if (ctx->mMDP.version < qdutils::MDP_V4_0) { 282 if(ctx->mCopyBit[dpy]) 283 ctx->mCopyBit[dpy]->prepare(ctx, list, dpy); 284 } 285 setGPUHint(ctx, list); 286 } 287 return 0; 288 } 289 290 static int hwc_prepare_external(hwc_composer_device_1 *dev, 291 hwc_display_contents_1_t *list) { 292 ATRACE_CALL(); 293 hwc_context_t* ctx = (hwc_context_t*)(dev); 294 const int dpy = HWC_DISPLAY_EXTERNAL; 295 296 if (LIKELY(list && list->numHwLayers > 1) && 297 ctx->dpyAttr[dpy].isActive && 298 ctx->dpyAttr[dpy].connected) { 299 reset_layer_prop(ctx, dpy, (int)list->numHwLayers - 1); 300 if(!ctx->dpyAttr[dpy].isPause) { 301 ctx->dpyAttr[dpy].isConfiguring = false; 302 setListStats(ctx, list, dpy); 303 if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) { 304 const int fbZ = 0; 305 if(not ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ)) 306 { 307 ctx->mOverlay->clear(dpy); 308 ctx->mLayerRotMap[dpy]->clear(); 309 } 310 } 311 } else { 312 /* External Display is in Pause state. 313 * Mark all application layers as OVERLAY so that 314 * GPU will not compose. 315 */ 316 for(size_t i = 0 ;i < (size_t)(list->numHwLayers - 1); i++) { 317 hwc_layer_1_t *layer = &list->hwLayers[i]; 318 layer->compositionType = HWC_OVERLAY; 319 } 320 } 321 } 322 return 0; 323 } 324 325 static int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays, 326 hwc_display_contents_1_t** displays) 327 { 328 int ret = 0; 329 hwc_context_t* ctx = (hwc_context_t*)(dev); 330 331 if (ctx->mPanelResetStatus) { 332 ALOGW("%s: panel is in bad state. reset the panel", __FUNCTION__); 333 reset_panel(dev); 334 } 335 336 //Will be unlocked at the end of set 337 ctx->mDrawLock.lock(); 338 setPaddingRound(ctx, (int)numDisplays, displays); 339 setDMAState(ctx, (int)numDisplays, displays); 340 setNumActiveDisplays(ctx, (int)numDisplays, displays); 341 reset(ctx, (int)numDisplays, displays); 342 343 ctx->mOverlay->configBegin(); 344 ctx->mRotMgr->configBegin(); 345 overlay::Writeback::configBegin(); 346 347 for (int32_t i = ((int32_t)numDisplays-1); i >=0 ; i--) { 348 hwc_display_contents_1_t *list = displays[i]; 349 int dpy = getDpyforExternalDisplay(ctx, i); 350 switch(dpy) { 351 case HWC_DISPLAY_PRIMARY: 352 ret = hwc_prepare_primary(dev, list); 353 break; 354 case HWC_DISPLAY_EXTERNAL: 355 ret = hwc_prepare_external(dev, list); 356 break; 357 case HWC_DISPLAY_VIRTUAL: 358 if(ctx->mHWCVirtual) 359 ret = ctx->mHWCVirtual->prepare(dev, list); 360 break; 361 default: 362 ret = -EINVAL; 363 } 364 } 365 366 ctx->mOverlay->configDone(); 367 ctx->mRotMgr->configDone(); 368 overlay::Writeback::configDone(); 369 370 return ret; 371 } 372 373 static int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy, 374 int event, int enable) 375 { 376 ATRACE_CALL(); 377 int ret = 0; 378 hwc_context_t* ctx = (hwc_context_t*)(dev); 379 switch(event) { 380 case HWC_EVENT_VSYNC: 381 if (ctx->vstate.enable == enable) 382 break; 383 ret = hwc_vsync_control(ctx, dpy, enable); 384 if(ret == 0) 385 ctx->vstate.enable = !!enable; 386 ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s", 387 (enable)?"ENABLED":"DISABLED"); 388 break; 389 #ifdef QCOM_BSP 390 case HWC_EVENT_ORIENTATION: 391 if(dpy == HWC_DISPLAY_PRIMARY) { 392 Locker::Autolock _l(ctx->mDrawLock); 393 // store the primary display orientation 394 ctx->deviceOrientation = enable; 395 } 396 break; 397 #endif 398 default: 399 ret = -EINVAL; 400 } 401 return ret; 402 } 403 404 static int hwc_setPowerMode(struct hwc_composer_device_1* dev, int dpy, 405 int mode) 406 { 407 ATRACE_CALL(); 408 hwc_context_t* ctx = (hwc_context_t*)(dev); 409 int ret = 0, value = 0; 410 411 Locker::Autolock _l(ctx->mDrawLock); 412 ALOGD_IF(POWER_MODE_DEBUG, "%s: Setting mode %d on display: %d", 413 __FUNCTION__, mode, dpy); 414 415 switch(mode) { 416 case HWC_POWER_MODE_OFF: 417 // free up all the overlay pipes in use 418 // when we get a blank for either display 419 // makes sure that all pipes are freed 420 ctx->mOverlay->configBegin(); 421 ctx->mOverlay->configDone(); 422 ctx->mRotMgr->clear(); 423 // If VDS is connected, do not clear WB object as it 424 // will end up detaching IOMMU. This is required 425 // to send black frame to WFD sink on power suspend. 426 // Note: With this change, we keep the WriteBack object 427 // alive on power suspend for AD use case. 428 value = FB_BLANK_POWERDOWN; 429 break; 430 case HWC_POWER_MODE_DOZE: 431 case HWC_POWER_MODE_DOZE_SUSPEND: 432 value = FB_BLANK_VSYNC_SUSPEND; 433 break; 434 case HWC_POWER_MODE_NORMAL: 435 value = FB_BLANK_UNBLANK; 436 break; 437 } 438 439 switch(dpy) { 440 case HWC_DISPLAY_PRIMARY: 441 if(ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK, value) < 0 ) { 442 ALOGE("%s: ioctl FBIOBLANK failed for Primary with error %s" 443 " value %d", __FUNCTION__, strerror(errno), value); 444 return -errno; 445 } 446 447 if(mode == HWC_POWER_MODE_NORMAL) { 448 // Enable HPD here, as during bootup POWER_MODE_NORMAL is set 449 // when SF is completely initialized 450 ctx->mExtDisplay->setHPD(1); 451 } 452 453 ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF); 454 //Deliberate fall through since there is no explicit power mode for 455 //virtual displays. 456 case HWC_DISPLAY_VIRTUAL: 457 if(ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected) { 458 const int dpy = HWC_DISPLAY_VIRTUAL; 459 if(mode == HWC_POWER_MODE_OFF and 460 (not ctx->dpyAttr[dpy].isPause)) { 461 if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) { 462 ALOGE("%s: displayCommit failed for virtual", __FUNCTION__); 463 ret = -1; 464 } 465 } 466 ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF); 467 } 468 break; 469 case HWC_DISPLAY_EXTERNAL: 470 if(mode == HWC_POWER_MODE_OFF) { 471 if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) { 472 ALOGE("%s: displayCommit failed for external", __FUNCTION__); 473 ret = -1; 474 } 475 } 476 ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF); 477 break; 478 default: 479 return -EINVAL; 480 } 481 482 ALOGD_IF(POWER_MODE_DEBUG, "%s: Done setting mode %d on display %d", 483 __FUNCTION__, mode, dpy); 484 return ret; 485 } 486 487 static void reset_panel(struct hwc_composer_device_1* dev) 488 { 489 int ret = 0; 490 hwc_context_t* ctx = (hwc_context_t*)(dev); 491 492 if (!ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) { 493 ALOGD ("%s : Display OFF - Skip BLANK & UNBLANK", __FUNCTION__); 494 ctx->mPanelResetStatus = false; 495 return; 496 } 497 498 ALOGD("%s: setting power mode off", __FUNCTION__); 499 ret = hwc_setPowerMode(dev, HWC_DISPLAY_PRIMARY, HWC_POWER_MODE_OFF); 500 if (ret < 0) { 501 ALOGE("%s: FBIOBLANK failed to BLANK: %s", __FUNCTION__, 502 strerror(errno)); 503 } 504 505 ALOGD("%s: setting power mode normal and enabling vsync", __FUNCTION__); 506 ret = hwc_setPowerMode(dev, HWC_DISPLAY_PRIMARY, HWC_POWER_MODE_NORMAL); 507 if (ret < 0) { 508 ALOGE("%s: FBIOBLANK failed to UNBLANK : %s", __FUNCTION__, 509 strerror(errno)); 510 } 511 hwc_vsync_control(ctx, HWC_DISPLAY_PRIMARY, 1); 512 513 ctx->mPanelResetStatus = false; 514 } 515 516 517 static int hwc_query(struct hwc_composer_device_1* dev, 518 int param, int* value) 519 { 520 hwc_context_t* ctx = (hwc_context_t*)(dev); 521 int supported = HWC_DISPLAY_PRIMARY_BIT; 522 523 switch (param) { 524 case HWC_BACKGROUND_LAYER_SUPPORTED: 525 // Not supported for now 526 value[0] = 0; 527 break; 528 case HWC_DISPLAY_TYPES_SUPPORTED: 529 if(ctx->mMDP.hasOverlay) { 530 supported |= HWC_DISPLAY_VIRTUAL_BIT; 531 if(!(qdutils::MDPVersion::getInstance().is8x26() || 532 qdutils::MDPVersion::getInstance().is8x16() || 533 qdutils::MDPVersion::getInstance().is8x39())) 534 supported |= HWC_DISPLAY_EXTERNAL_BIT; 535 } 536 value[0] = supported; 537 break; 538 case HWC_FORMAT_RB_SWAP: 539 value[0] = 1; 540 break; 541 case HWC_COLOR_FILL: 542 value[0] = 1; 543 break; 544 default: 545 return -EINVAL; 546 } 547 return 0; 548 549 } 550 551 552 static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 553 ATRACE_CALL(); 554 int ret = 0; 555 const int dpy = HWC_DISPLAY_PRIMARY; 556 if (LIKELY(list) && ctx->dpyAttr[dpy].isActive) { 557 size_t last = list->numHwLayers - 1; 558 hwc_layer_1_t *fbLayer = &list->hwLayers[last]; 559 int fd = -1; //FenceFD from the Copybit(valid in async mode) 560 bool copybitDone = false; 561 562 if (ctx->mCopyBit[dpy]) { 563 if (ctx->mMDP.version < qdutils::MDP_V4_0) 564 copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd); 565 else 566 fd = ctx->mMDPComp[dpy]->drawOverlap(ctx, list); 567 } 568 569 if(list->numHwLayers > 1) 570 hwc_sync(ctx, list, dpy, fd); 571 572 // Dump the layers for primary 573 if(ctx->mHwcDebug[dpy]) 574 ctx->mHwcDebug[dpy]->dumpLayers(list); 575 576 if (!ctx->mMDPComp[dpy]->draw(ctx, list)) { 577 ALOGE("%s: MDPComp draw failed", __FUNCTION__); 578 ret = -1; 579 } 580 581 //TODO We dont check for SKIP flag on this layer because we need PAN 582 //always. Last layer is always FB 583 private_handle_t *hnd = (private_handle_t *)fbLayer->handle; 584 if(copybitDone && ctx->mMDP.version >= qdutils::MDP_V4_0) { 585 hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer(); 586 } 587 588 if(isAbcInUse(ctx) == true) { 589 int index = ctx->listStats[dpy].renderBufIndexforABC; 590 hwc_layer_1_t *tempLayer = &list->hwLayers[index]; 591 hnd = (private_handle_t *)tempLayer->handle; 592 } 593 594 if(hnd) { 595 if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) { 596 ALOGE("%s: FBUpdate draw failed", __FUNCTION__); 597 ret = -1; 598 } 599 } 600 601 int lSplit = getLeftSplit(ctx, dpy); 602 qhwc::ovutils::Dim lRoi = qhwc::ovutils::Dim( 603 ctx->listStats[dpy].lRoi.left, 604 ctx->listStats[dpy].lRoi.top, 605 ctx->listStats[dpy].lRoi.right - ctx->listStats[dpy].lRoi.left, 606 ctx->listStats[dpy].lRoi.bottom - ctx->listStats[dpy].lRoi.top); 607 608 qhwc::ovutils::Dim rRoi = qhwc::ovutils::Dim( 609 ctx->listStats[dpy].rRoi.left - lSplit, 610 ctx->listStats[dpy].rRoi.top, 611 ctx->listStats[dpy].rRoi.right - ctx->listStats[dpy].rRoi.left, 612 ctx->listStats[dpy].rRoi.bottom - ctx->listStats[dpy].rRoi.top); 613 614 if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd, lRoi, rRoi)) { 615 ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy); 616 ret = -1; 617 } 618 619 } 620 621 closeAcquireFds(list); 622 return ret; 623 } 624 625 static int hwc_set_external(hwc_context_t *ctx, 626 hwc_display_contents_1_t* list) 627 { 628 ATRACE_CALL(); 629 int ret = 0; 630 631 const int dpy = HWC_DISPLAY_EXTERNAL; 632 633 634 if (LIKELY(list) && ctx->dpyAttr[dpy].isActive && 635 ctx->dpyAttr[dpy].connected && 636 !ctx->dpyAttr[dpy].isPause) { 637 size_t last = list->numHwLayers - 1; 638 hwc_layer_1_t *fbLayer = &list->hwLayers[last]; 639 int fd = -1; //FenceFD from the Copybit(valid in async mode) 640 bool copybitDone = false; 641 if(ctx->mCopyBit[dpy]) 642 copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd); 643 644 if(list->numHwLayers > 1) 645 hwc_sync(ctx, list, dpy, fd); 646 647 // Dump the layers for external 648 if(ctx->mHwcDebug[dpy]) 649 ctx->mHwcDebug[dpy]->dumpLayers(list); 650 651 if (!ctx->mMDPComp[dpy]->draw(ctx, list)) { 652 ALOGE("%s: MDPComp draw failed", __FUNCTION__); 653 ret = -1; 654 } 655 656 int extOnlyLayerIndex = 657 ctx->listStats[dpy].extOnlyLayerIndex; 658 659 private_handle_t *hnd = (private_handle_t *)fbLayer->handle; 660 if(extOnlyLayerIndex!= -1) { 661 hwc_layer_1_t *extLayer = &list->hwLayers[extOnlyLayerIndex]; 662 hnd = (private_handle_t *)extLayer->handle; 663 } else if(copybitDone) { 664 hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer(); 665 } 666 667 if(hnd && !isYuvBuffer(hnd)) { 668 if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) { 669 ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__); 670 ret = -1; 671 } 672 } 673 674 if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) { 675 ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy); 676 ret = -1; 677 } 678 } 679 680 closeAcquireFds(list); 681 return ret; 682 } 683 684 static int hwc_set(hwc_composer_device_1 *dev, 685 size_t numDisplays, 686 hwc_display_contents_1_t** displays) 687 { 688 int ret = 0; 689 hwc_context_t* ctx = (hwc_context_t*)(dev); 690 for (int i = 0; i < (int)numDisplays; i++) { 691 hwc_display_contents_1_t* list = displays[i]; 692 int dpy = getDpyforExternalDisplay(ctx, i); 693 switch(dpy) { 694 case HWC_DISPLAY_PRIMARY: 695 ret = hwc_set_primary(ctx, list); 696 break; 697 case HWC_DISPLAY_EXTERNAL: 698 ret = hwc_set_external(ctx, list); 699 break; 700 case HWC_DISPLAY_VIRTUAL: 701 if(ctx->mHWCVirtual) 702 ret = ctx->mHWCVirtual->set(ctx, list); 703 break; 704 default: 705 ret = -EINVAL; 706 } 707 } 708 // This is only indicative of how many times SurfaceFlinger posts 709 // frames to the display. 710 CALC_FPS(); 711 MDPComp::resetIdleFallBack(); 712 ctx->mVideoTransFlag = false; 713 //Was locked at the beginning of prepare 714 ctx->mDrawLock.unlock(); 715 return ret; 716 } 717 718 int hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp, 719 uint32_t* configs, size_t* numConfigs) { 720 int ret = 0; 721 hwc_context_t* ctx = (hwc_context_t*)(dev); 722 disp = getDpyforExternalDisplay(ctx, disp); 723 //Currently we allow only 1 config, reported as config id # 0 724 //This config is passed in to getDisplayAttributes. Ignored for now. 725 switch(disp) { 726 case HWC_DISPLAY_PRIMARY: 727 if(*numConfigs > 0) { 728 configs[0] = 0; 729 *numConfigs = 1; 730 } 731 ret = 0; //NO_ERROR 732 break; 733 case HWC_DISPLAY_EXTERNAL: 734 case HWC_DISPLAY_VIRTUAL: 735 ret = -1; //Not connected 736 if(ctx->dpyAttr[disp].connected) { 737 ret = 0; //NO_ERROR 738 if(*numConfigs > 0) { 739 configs[0] = 0; 740 *numConfigs = 1; 741 } 742 } 743 break; 744 } 745 return ret; 746 } 747 748 int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp, 749 uint32_t /*config*/, const uint32_t* attributes, int32_t* values) { 750 751 hwc_context_t* ctx = (hwc_context_t*)(dev); 752 disp = getDpyforExternalDisplay(ctx, disp); 753 //If hotpluggable displays(i.e, HDMI, WFD) are inactive return error 754 if( (disp != HWC_DISPLAY_PRIMARY) && !ctx->dpyAttr[disp].connected) { 755 return -1; 756 } 757 758 //From HWComposer 759 static const uint32_t DISPLAY_ATTRIBUTES[] = { 760 HWC_DISPLAY_VSYNC_PERIOD, 761 HWC_DISPLAY_WIDTH, 762 HWC_DISPLAY_HEIGHT, 763 HWC_DISPLAY_DPI_X, 764 HWC_DISPLAY_DPI_Y, 765 HWC_DISPLAY_NO_ATTRIBUTE, 766 }; 767 768 const size_t NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) / 769 sizeof(DISPLAY_ATTRIBUTES)[0]); 770 771 for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) { 772 switch (attributes[i]) { 773 case HWC_DISPLAY_VSYNC_PERIOD: 774 values[i] = ctx->dpyAttr[disp].vsync_period; 775 break; 776 case HWC_DISPLAY_WIDTH: 777 if (ctx->dpyAttr[disp].customFBSize) 778 values[i] = ctx->dpyAttr[disp].xres_new; 779 else 780 values[i] = ctx->dpyAttr[disp].xres; 781 782 ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp, 783 values[i]); 784 break; 785 case HWC_DISPLAY_HEIGHT: 786 if (ctx->dpyAttr[disp].customFBSize) 787 values[i] = ctx->dpyAttr[disp].yres_new; 788 else 789 values[i] = ctx->dpyAttr[disp].yres; 790 ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp, 791 values[i]); 792 break; 793 case HWC_DISPLAY_DPI_X: 794 values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0); 795 break; 796 case HWC_DISPLAY_DPI_Y: 797 values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0); 798 break; 799 default: 800 ALOGE("Unknown display attribute %d", 801 attributes[i]); 802 return -EINVAL; 803 } 804 } 805 return 0; 806 } 807 808 void hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len) 809 { 810 hwc_context_t* ctx = (hwc_context_t*)(dev); 811 Locker::Autolock _l(ctx->mDrawLock); 812 android::String8 aBuf(""); 813 dumpsys_log(aBuf, "Qualcomm HWC state:\n"); 814 dumpsys_log(aBuf, " MDPVersion=%d\n", ctx->mMDP.version); 815 dumpsys_log(aBuf, " DisplayPanel=%c\n", ctx->mMDP.panel); 816 if(ctx->vstate.fakevsync) 817 dumpsys_log(aBuf, " Vsync is being faked!!\n"); 818 for(int dpy = 0; dpy < HWC_NUM_DISPLAY_TYPES; dpy++) { 819 if(ctx->mMDPComp[dpy]) 820 ctx->mMDPComp[dpy]->dump(aBuf, ctx); 821 } 822 char ovDump[2048] = {'\0'}; 823 ctx->mOverlay->getDump(ovDump, 2048); 824 dumpsys_log(aBuf, ovDump); 825 ovDump[0] = '\0'; 826 ctx->mRotMgr->getDump(ovDump, 1024); 827 dumpsys_log(aBuf, ovDump); 828 ovDump[0] = '\0'; 829 if(Writeback::getDump(ovDump, 1024)) { 830 dumpsys_log(aBuf, ovDump); 831 ovDump[0] = '\0'; 832 } 833 strlcpy(buff, aBuf.string(), buff_len); 834 } 835 836 int hwc_getActiveConfig(struct hwc_composer_device_1* /*dev*/, int /*disp*/) { 837 //Supports only the default config (0th index) for now 838 return 0; 839 } 840 841 int hwc_setActiveConfig(struct hwc_composer_device_1* /*dev*/, int /*disp*/, 842 int index) { 843 //Supports only the default config (0th index) for now 844 return (index == 0) ? index : -EINVAL; 845 } 846 847 static int hwc_device_close(struct hw_device_t *dev) 848 { 849 if(!dev) { 850 ALOGE("%s: NULL device pointer", __FUNCTION__); 851 return -1; 852 } 853 closeContext((hwc_context_t*)dev); 854 free(dev); 855 856 return 0; 857 } 858 859 static int hwc_device_open(const struct hw_module_t* module, const char* name, 860 struct hw_device_t** device) 861 { 862 int status = -EINVAL; 863 864 if (!strcmp(name, HWC_HARDWARE_COMPOSER)) { 865 struct hwc_context_t *dev; 866 dev = (hwc_context_t*)malloc(sizeof(*dev)); 867 if(dev == NULL) 868 return status; 869 memset(dev, 0, sizeof(*dev)); 870 871 //Initialize hwc context 872 initContext(dev); 873 874 //Setup HWC methods 875 dev->device.common.tag = HARDWARE_DEVICE_TAG; 876 dev->device.common.version = HWC_DEVICE_API_VERSION_1_4; 877 dev->device.common.module = const_cast<hw_module_t*>(module); 878 dev->device.common.close = hwc_device_close; 879 dev->device.prepare = hwc_prepare; 880 dev->device.set = hwc_set; 881 dev->device.eventControl = hwc_eventControl; 882 dev->device.setPowerMode = hwc_setPowerMode; 883 dev->device.query = hwc_query; 884 dev->device.registerProcs = hwc_registerProcs; 885 dev->device.dump = hwc_dump; 886 dev->device.getDisplayConfigs = hwc_getDisplayConfigs; 887 dev->device.getDisplayAttributes = hwc_getDisplayAttributes; 888 dev->device.getActiveConfig = hwc_getActiveConfig; 889 dev->device.setActiveConfig = hwc_setActiveConfig; 890 *device = &dev->device.common; 891 status = 0; 892 } 893 return status; 894 } 895