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 43using namespace qhwc; 44using namespace overlay; 45 46#define VSYNC_DEBUG 0 47#define POWER_MODE_DEBUG 1 48 49static int hwc_device_open(const struct hw_module_t* module, 50 const char* name, 51 struct hw_device_t** device); 52 53static struct hw_module_methods_t hwc_module_methods = { 54 open: hwc_device_open 55}; 56 57static void reset_panel(struct hwc_composer_device_1* dev); 58 59hwc_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 78static 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 */ 87static 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 104static 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 */ 129static 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 video layer requires rotation, set the DMA state 147 * to BLOCK_MODE */ 148 149 if (UNLIKELY(isYuvBuffer(hnd)) && canUseRotator(ctx, dpy) && 150 (layer->transform & HWC_TRANSFORM_ROT_90)) { 151 if(not qdutils::MDPVersion::getInstance().is8x26()) { 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 181static 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 199static 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 ctx->mPrevHwLayerCount[i] = (int)list->numHwLayers; 215 } else { 216 ctx->mPrevHwLayerCount[i] = 0; 217 } 218 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 MDPComp::reset(); 229 if(ctx->mHWCVirtual) 230 ctx->mHWCVirtual->destroy(ctx, numDisplays, displays); 231} 232 233bool isEqual(float f1, float f2) { 234 return ((int)(f1*100) == (int)(f2*100)) ? true : false; 235} 236 237static void scaleDisplayFrame(hwc_context_t *ctx, int dpy, 238 hwc_display_contents_1_t *list) { 239 uint32_t origXres = ctx->dpyAttr[dpy].xres_orig; 240 uint32_t origYres = ctx->dpyAttr[dpy].yres_orig; 241 uint32_t fakeXres = ctx->dpyAttr[dpy].xres; 242 uint32_t fakeYres = ctx->dpyAttr[dpy].yres; 243 float xresRatio = (float)origXres / (float)fakeXres; 244 float yresRatio = (float)origYres / (float)fakeYres; 245 for (size_t i = 0; i < list->numHwLayers; i++) { 246 hwc_layer_1_t *layer = &list->hwLayers[i]; 247 hwc_rect_t& displayFrame = layer->displayFrame; 248 hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf); 249 uint32_t layerWidth = displayFrame.right - displayFrame.left; 250 uint32_t layerHeight = displayFrame.bottom - displayFrame.top; 251 uint32_t sourceWidth = sourceCrop.right - sourceCrop.left; 252 uint32_t sourceHeight = sourceCrop.bottom - sourceCrop.top; 253 254 if (isEqual(((float)layerWidth / (float)sourceWidth), xresRatio) && 255 isEqual(((float)layerHeight / (float)sourceHeight), yresRatio)) 256 break; 257 258 displayFrame.left = (int)(xresRatio * (float)displayFrame.left); 259 displayFrame.top = (int)(yresRatio * (float)displayFrame.top); 260 displayFrame.right = (int)((float)displayFrame.left + 261 (float)layerWidth * xresRatio); 262 displayFrame.bottom = (int)((float)displayFrame.top + 263 (float)layerHeight * yresRatio); 264 } 265} 266 267static int hwc_prepare_primary(hwc_composer_device_1 *dev, 268 hwc_display_contents_1_t *list) { 269 ATRACE_CALL(); 270 hwc_context_t* ctx = (hwc_context_t*)(dev); 271 const int dpy = HWC_DISPLAY_PRIMARY; 272 bool fbComp = false; 273 if (LIKELY(list && list->numHwLayers > 1) && 274 ctx->dpyAttr[dpy].isActive) { 275 276 if (ctx->dpyAttr[dpy].customFBSize) 277 scaleDisplayFrame(ctx, dpy, list); 278 279 reset_layer_prop(ctx, dpy, (int)list->numHwLayers - 1); 280 setListStats(ctx, list, dpy); 281 282 fbComp = (ctx->mMDPComp[dpy]->prepare(ctx, list) < 0); 283 284 if (fbComp) { 285 const int fbZ = 0; 286 if(not ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ)) { 287 ctx->mOverlay->clear(dpy); 288 ctx->mLayerRotMap[dpy]->clear(); 289 } 290 } 291 292 if (ctx->mMDP.version < qdutils::MDP_V4_0) { 293 if(ctx->mCopyBit[dpy]) 294 ctx->mCopyBit[dpy]->prepare(ctx, list, dpy); 295 } 296 setGPUHint(ctx, list); 297 } 298 return 0; 299} 300 301static int hwc_prepare_external(hwc_composer_device_1 *dev, 302 hwc_display_contents_1_t *list) { 303 ATRACE_CALL(); 304 hwc_context_t* ctx = (hwc_context_t*)(dev); 305 const int dpy = HWC_DISPLAY_EXTERNAL; 306 307 if (LIKELY(list && list->numHwLayers > 1) && 308 ctx->dpyAttr[dpy].isActive && 309 ctx->dpyAttr[dpy].connected) { 310 reset_layer_prop(ctx, dpy, (int)list->numHwLayers - 1); 311 if(!ctx->dpyAttr[dpy].isPause) { 312 ctx->dpyAttr[dpy].isConfiguring = false; 313 setListStats(ctx, list, dpy); 314 if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) { 315 const int fbZ = 0; 316 if(not ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ)) 317 { 318 ctx->mOverlay->clear(dpy); 319 ctx->mLayerRotMap[dpy]->clear(); 320 } 321 } 322 } else { 323 /* External Display is in Pause state. 324 * Mark all application layers as OVERLAY so that 325 * GPU will not compose. 326 */ 327 for(size_t i = 0 ;i < (size_t)(list->numHwLayers - 1); i++) { 328 hwc_layer_1_t *layer = &list->hwLayers[i]; 329 layer->compositionType = HWC_OVERLAY; 330 } 331 } 332 } 333 return 0; 334} 335 336static int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays, 337 hwc_display_contents_1_t** displays) 338{ 339 int ret = 0; 340 hwc_context_t* ctx = (hwc_context_t*)(dev); 341 342 if (ctx->mPanelResetStatus) { 343 ALOGW("%s: panel is in bad state. reset the panel", __FUNCTION__); 344 reset_panel(dev); 345 } 346 347 //Will be unlocked at the end of set 348 ctx->mDrawLock.lock(); 349 setPaddingRound(ctx,numDisplays,displays); 350 setDMAState(ctx,numDisplays,displays); 351 setNumActiveDisplays(ctx,numDisplays,displays); 352 reset(ctx, (int)numDisplays, displays); 353 354 ctx->mOverlay->configBegin(); 355 ctx->mRotMgr->configBegin(); 356 overlay::Writeback::configBegin(); 357 358 for (int32_t i = ((int32_t)numDisplays-1); i >=0 ; i--) { 359 hwc_display_contents_1_t *list = displays[i]; 360 int dpy = getDpyforExternalDisplay(ctx, i); 361 switch(dpy) { 362 case HWC_DISPLAY_PRIMARY: 363 ret = hwc_prepare_primary(dev, list); 364 break; 365 case HWC_DISPLAY_EXTERNAL: 366 ret = hwc_prepare_external(dev, list); 367 break; 368 case HWC_DISPLAY_VIRTUAL: 369 if(ctx->mHWCVirtual) 370 ret = ctx->mHWCVirtual->prepare(dev, list); 371 break; 372 default: 373 ret = -EINVAL; 374 } 375 } 376 377 ctx->mOverlay->configDone(); 378 ctx->mRotMgr->configDone(); 379 overlay::Writeback::configDone(); 380 381 return ret; 382} 383 384static int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy, 385 int event, int enable) 386{ 387 ATRACE_CALL(); 388 int ret = 0; 389 hwc_context_t* ctx = (hwc_context_t*)(dev); 390 switch(event) { 391 case HWC_EVENT_VSYNC: 392 if (ctx->vstate.enable == enable) 393 break; 394 ret = hwc_vsync_control(ctx, dpy, enable); 395 if(ret == 0) 396 ctx->vstate.enable = !!enable; 397 ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s", 398 (enable)?"ENABLED":"DISABLED"); 399 break; 400#ifdef QCOM_BSP 401 case HWC_EVENT_ORIENTATION: 402 if(dpy == HWC_DISPLAY_PRIMARY) { 403 Locker::Autolock _l(ctx->mDrawLock); 404 // store the primary display orientation 405 ctx->deviceOrientation = enable; 406 } 407 break; 408#endif 409 default: 410 ret = -EINVAL; 411 } 412 return ret; 413} 414 415static int hwc_setPowerMode(struct hwc_composer_device_1* dev, int dpy, 416 int mode) 417{ 418 ATRACE_CALL(); 419 hwc_context_t* ctx = (hwc_context_t*)(dev); 420 int ret = 0, value = 0; 421 422 Locker::Autolock _l(ctx->mDrawLock); 423 ALOGD_IF(POWER_MODE_DEBUG, "%s: Setting mode %d on display: %d", 424 __FUNCTION__, mode, dpy); 425 426 switch(mode) { 427 case HWC_POWER_MODE_OFF: 428 // free up all the overlay pipes in use 429 // when we get a blank for either display 430 // makes sure that all pipes are freed 431 ctx->mOverlay->configBegin(); 432 ctx->mOverlay->configDone(); 433 ctx->mRotMgr->clear(); 434 // If VDS is connected, do not clear WB object as it 435 // will end up detaching IOMMU. This is required 436 // to send black frame to WFD sink on power suspend. 437 // Note: With this change, we keep the WriteBack object 438 // alive on power suspend for AD use case. 439 // Instead, we now clear the writeback and associated pipes 440 // when the primary display is unblanking. 441 value = FB_BLANK_POWERDOWN; 442 break; 443 case HWC_POWER_MODE_DOZE: 444 case HWC_POWER_MODE_DOZE_SUSPEND: 445 value = FB_BLANK_VSYNC_SUSPEND; 446 break; 447 case HWC_POWER_MODE_NORMAL: 448 value = FB_BLANK_UNBLANK; 449 break; 450 } 451 452 // XXX: Workaround 453 // Clear writeback and all overlays when primary is unblanking, 454 // since the kernel may have internally reset writeback in XO shutdown. 455 // This is to maintain consistency with the kernel's internal state and 456 // not assume that we have a valid writeback object when unblanking primary 457 // Ideally, we should get an explicit blank on the virtual display 458 // or, the blank frames when the virtual display is blanking should 459 // be sent _before_ the primary is unblanked 460 if (dpy == HWC_DISPLAY_PRIMARY && not (mode == HWC_POWER_MODE_OFF)) { 461 ctx->mOverlay->configBegin(); 462 ctx->mOverlay->configDone(); 463 ctx->mRotMgr->clear(); 464 Writeback::clear(); 465 } 466 467 switch(dpy) { 468 case HWC_DISPLAY_PRIMARY: 469 if(ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK, value) < 0 ) { 470 ALOGE("%s: ioctl FBIOBLANK failed for Primary with error %s" 471 " value %d", __FUNCTION__, strerror(errno), value); 472 return -errno; 473 } 474 475 if(mode == HWC_POWER_MODE_NORMAL) { 476 // Enable HPD here, as during bootup POWER_MODE_NORMAL is set 477 // when SF is completely initialized 478 ctx->mExtDisplay->setHPD(1); 479 } 480 481 ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF); 482 //Deliberate fall through since there is no explicit power mode for 483 //virtual displays. 484 case HWC_DISPLAY_VIRTUAL: 485 if(ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected) { 486 const int dpy = HWC_DISPLAY_VIRTUAL; 487 if(mode == HWC_POWER_MODE_OFF and 488 (not ctx->dpyAttr[dpy].isPause)) { 489 if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) { 490 ALOGE("%s: displayCommit failed for virtual", __FUNCTION__); 491 ret = -1; 492 } 493 } 494 ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF); 495 } 496 break; 497 case HWC_DISPLAY_EXTERNAL: 498 if(mode == HWC_POWER_MODE_OFF) { 499 if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) { 500 ALOGE("%s: displayCommit failed for external", __FUNCTION__); 501 ret = -1; 502 } 503 } 504 ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF); 505 break; 506 default: 507 return -EINVAL; 508 } 509 510 ALOGD_IF(POWER_MODE_DEBUG, "%s: Done setting mode %d on display %d", 511 __FUNCTION__, mode, dpy); 512 return ret; 513} 514 515static void reset_panel(struct hwc_composer_device_1* dev) 516{ 517 int ret = 0; 518 hwc_context_t* ctx = (hwc_context_t*)(dev); 519 520 if (!ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) { 521 ALOGD ("%s : Display OFF - Skip BLANK & UNBLANK", __FUNCTION__); 522 ctx->mPanelResetStatus = false; 523 return; 524 } 525 526 ALOGD("%s: setting power mode off", __FUNCTION__); 527 ret = hwc_setPowerMode(dev, HWC_DISPLAY_PRIMARY, HWC_POWER_MODE_OFF); 528 if (ret < 0) { 529 ALOGE("%s: FBIOBLANK failed to BLANK: %s", __FUNCTION__, 530 strerror(errno)); 531 } 532 533 ALOGD("%s: setting power mode normal and enabling vsync", __FUNCTION__); 534 ret = hwc_setPowerMode(dev, HWC_DISPLAY_PRIMARY, HWC_POWER_MODE_NORMAL); 535 if (ret < 0) { 536 ALOGE("%s: FBIOBLANK failed to UNBLANK : %s", __FUNCTION__, 537 strerror(errno)); 538 } 539 hwc_vsync_control(ctx, HWC_DISPLAY_PRIMARY, 1); 540 541 ctx->mPanelResetStatus = false; 542} 543 544 545static int hwc_query(struct hwc_composer_device_1* dev, 546 int param, int* value) 547{ 548 hwc_context_t* ctx = (hwc_context_t*)(dev); 549 int supported = HWC_DISPLAY_PRIMARY_BIT; 550 551 switch (param) { 552 case HWC_BACKGROUND_LAYER_SUPPORTED: 553 // Not supported for now 554 value[0] = 0; 555 break; 556 case HWC_DISPLAY_TYPES_SUPPORTED: 557 if(ctx->mMDP.hasOverlay) { 558 supported |= HWC_DISPLAY_VIRTUAL_BIT; 559 if(!(qdutils::MDPVersion::getInstance().is8x26() || 560 qdutils::MDPVersion::getInstance().is8x16())) 561 supported |= HWC_DISPLAY_EXTERNAL_BIT; 562 } 563 value[0] = supported; 564 break; 565 case HWC_FORMAT_RB_SWAP: 566 value[0] = 1; 567 break; 568 case HWC_COLOR_FILL: 569 value[0] = 1; 570 break; 571 default: 572 return -EINVAL; 573 } 574 return 0; 575 576} 577 578 579static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 580 ATRACE_CALL(); 581 int ret = 0; 582 const int dpy = HWC_DISPLAY_PRIMARY; 583 if (LIKELY(list) && ctx->dpyAttr[dpy].isActive) { 584 size_t last = list->numHwLayers - 1; 585 hwc_layer_1_t *fbLayer = &list->hwLayers[last]; 586 int fd = -1; //FenceFD from the Copybit(valid in async mode) 587 bool copybitDone = false; 588 if(ctx->mCopyBit[dpy]) 589 copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd); 590 if(list->numHwLayers > 1) 591 hwc_sync(ctx, list, dpy, fd); 592 593 // Dump the layers for primary 594 if(ctx->mHwcDebug[dpy]) 595 ctx->mHwcDebug[dpy]->dumpLayers(list); 596 597 if (!ctx->mMDPComp[dpy]->draw(ctx, list)) { 598 ALOGE("%s: MDPComp draw failed", __FUNCTION__); 599 ret = -1; 600 } 601 602 //TODO We dont check for SKIP flag on this layer because we need PAN 603 //always. Last layer is always FB 604 private_handle_t *hnd = (private_handle_t *)fbLayer->handle; 605 if(copybitDone && ctx->mMDP.version >= qdutils::MDP_V4_0) { 606 hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer(); 607 } 608 609 if(hnd) { 610 if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) { 611 ALOGE("%s: FBUpdate draw failed", __FUNCTION__); 612 ret = -1; 613 } 614 } 615 616 int lSplit = getLeftSplit(ctx, dpy); 617 qhwc::ovutils::Dim lRoi = qhwc::ovutils::Dim( 618 ctx->listStats[dpy].lRoi.left, 619 ctx->listStats[dpy].lRoi.top, 620 ctx->listStats[dpy].lRoi.right - ctx->listStats[dpy].lRoi.left, 621 ctx->listStats[dpy].lRoi.bottom - ctx->listStats[dpy].lRoi.top); 622 623 qhwc::ovutils::Dim rRoi = qhwc::ovutils::Dim( 624 ctx->listStats[dpy].rRoi.left - lSplit, 625 ctx->listStats[dpy].rRoi.top, 626 ctx->listStats[dpy].rRoi.right - ctx->listStats[dpy].rRoi.left, 627 ctx->listStats[dpy].rRoi.bottom - ctx->listStats[dpy].rRoi.top); 628 629 if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd, lRoi, rRoi)) { 630 ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy); 631 ret = -1; 632 } 633 634 } 635 636 closeAcquireFds(list); 637 return ret; 638} 639 640static int hwc_set_external(hwc_context_t *ctx, 641 hwc_display_contents_1_t* list) 642{ 643 ATRACE_CALL(); 644 int ret = 0; 645 646 const int dpy = HWC_DISPLAY_EXTERNAL; 647 648 649 if (LIKELY(list) && ctx->dpyAttr[dpy].isActive && 650 ctx->dpyAttr[dpy].connected && 651 !ctx->dpyAttr[dpy].isPause) { 652 size_t last = list->numHwLayers - 1; 653 hwc_layer_1_t *fbLayer = &list->hwLayers[last]; 654 int fd = -1; //FenceFD from the Copybit(valid in async mode) 655 bool copybitDone = false; 656 if(ctx->mCopyBit[dpy]) 657 copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd); 658 659 if(list->numHwLayers > 1) 660 hwc_sync(ctx, list, dpy, fd); 661 662 // Dump the layers for external 663 if(ctx->mHwcDebug[dpy]) 664 ctx->mHwcDebug[dpy]->dumpLayers(list); 665 666 if (!ctx->mMDPComp[dpy]->draw(ctx, list)) { 667 ALOGE("%s: MDPComp draw failed", __FUNCTION__); 668 ret = -1; 669 } 670 671 int extOnlyLayerIndex = 672 ctx->listStats[dpy].extOnlyLayerIndex; 673 674 private_handle_t *hnd = (private_handle_t *)fbLayer->handle; 675 if(extOnlyLayerIndex!= -1) { 676 hwc_layer_1_t *extLayer = &list->hwLayers[extOnlyLayerIndex]; 677 hnd = (private_handle_t *)extLayer->handle; 678 } else if(copybitDone) { 679 hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer(); 680 } 681 682 if(hnd && !isYuvBuffer(hnd)) { 683 if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) { 684 ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__); 685 ret = -1; 686 } 687 } 688 689 if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) { 690 ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy); 691 ret = -1; 692 } 693 } 694 695 closeAcquireFds(list); 696 return ret; 697} 698 699static int hwc_set(hwc_composer_device_1 *dev, 700 size_t numDisplays, 701 hwc_display_contents_1_t** displays) 702{ 703 int ret = 0; 704 hwc_context_t* ctx = (hwc_context_t*)(dev); 705 for (int i = 0; i < (int)numDisplays; i++) { 706 hwc_display_contents_1_t* list = displays[i]; 707 int dpy = getDpyforExternalDisplay(ctx, i); 708 switch(dpy) { 709 case HWC_DISPLAY_PRIMARY: 710 ret = hwc_set_primary(ctx, list); 711 break; 712 case HWC_DISPLAY_EXTERNAL: 713 ret = hwc_set_external(ctx, list); 714 break; 715 case HWC_DISPLAY_VIRTUAL: 716 if(ctx->mHWCVirtual) 717 ret = ctx->mHWCVirtual->set(ctx, list); 718 break; 719 default: 720 ret = -EINVAL; 721 } 722 } 723 // This is only indicative of how many times SurfaceFlinger posts 724 // frames to the display. 725 CALC_FPS(); 726 MDPComp::resetIdleFallBack(); 727 ctx->mVideoTransFlag = false; 728 //Was locked at the beginning of prepare 729 ctx->mDrawLock.unlock(); 730 return ret; 731} 732 733int hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp, 734 uint32_t* configs, size_t* numConfigs) { 735 int ret = 0; 736 hwc_context_t* ctx = (hwc_context_t*)(dev); 737 disp = getDpyforExternalDisplay(ctx, disp); 738 //Currently we allow only 1 config, reported as config id # 0 739 //This config is passed in to getDisplayAttributes. Ignored for now. 740 switch(disp) { 741 case HWC_DISPLAY_PRIMARY: 742 if(*numConfigs > 0) { 743 configs[0] = 0; 744 *numConfigs = 1; 745 } 746 ret = 0; //NO_ERROR 747 break; 748 case HWC_DISPLAY_EXTERNAL: 749 case HWC_DISPLAY_VIRTUAL: 750 ret = -1; //Not connected 751 if(ctx->dpyAttr[disp].connected) { 752 ret = 0; //NO_ERROR 753 if(*numConfigs > 0) { 754 configs[0] = 0; 755 *numConfigs = 1; 756 } 757 } 758 break; 759 } 760 return ret; 761} 762 763int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp, 764 uint32_t /*config*/, const uint32_t* attributes, int32_t* values) { 765 766 hwc_context_t* ctx = (hwc_context_t*)(dev); 767 disp = getDpyforExternalDisplay(ctx, disp); 768 //If hotpluggable displays(i.e, HDMI, WFD) are inactive return error 769 if( (disp != HWC_DISPLAY_PRIMARY) && !ctx->dpyAttr[disp].connected) { 770 return -1; 771 } 772 773 //From HWComposer 774 static const uint32_t DISPLAY_ATTRIBUTES[] = { 775 HWC_DISPLAY_VSYNC_PERIOD, 776 HWC_DISPLAY_WIDTH, 777 HWC_DISPLAY_HEIGHT, 778 HWC_DISPLAY_DPI_X, 779 HWC_DISPLAY_DPI_Y, 780 HWC_DISPLAY_NO_ATTRIBUTE, 781 }; 782 783 const size_t NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) / 784 sizeof(DISPLAY_ATTRIBUTES)[0]); 785 786 for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) { 787 switch (attributes[i]) { 788 case HWC_DISPLAY_VSYNC_PERIOD: 789 values[i] = ctx->dpyAttr[disp].vsync_period; 790 break; 791 case HWC_DISPLAY_WIDTH: 792 values[i] = ctx->dpyAttr[disp].xres; 793 ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp, 794 ctx->dpyAttr[disp].xres); 795 break; 796 case HWC_DISPLAY_HEIGHT: 797 values[i] = ctx->dpyAttr[disp].yres; 798 ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp, 799 ctx->dpyAttr[disp].yres); 800 break; 801 case HWC_DISPLAY_DPI_X: 802 values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0); 803 break; 804 case HWC_DISPLAY_DPI_Y: 805 values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0); 806 break; 807 default: 808 ALOGE("Unknown display attribute %d", 809 attributes[i]); 810 return -EINVAL; 811 } 812 } 813 return 0; 814} 815 816void hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len) 817{ 818 hwc_context_t* ctx = (hwc_context_t*)(dev); 819 Locker::Autolock _l(ctx->mDrawLock); 820 android::String8 aBuf(""); 821 dumpsys_log(aBuf, "Qualcomm HWC state:\n"); 822 dumpsys_log(aBuf, " MDPVersion=%d\n", ctx->mMDP.version); 823 dumpsys_log(aBuf, " DisplayPanel=%c\n", ctx->mMDP.panel); 824 for(int dpy = 0; dpy < HWC_NUM_DISPLAY_TYPES; dpy++) { 825 if(ctx->mMDPComp[dpy]) 826 ctx->mMDPComp[dpy]->dump(aBuf, ctx); 827 } 828 char ovDump[2048] = {'\0'}; 829 ctx->mOverlay->getDump(ovDump, 2048); 830 dumpsys_log(aBuf, ovDump); 831 ovDump[0] = '\0'; 832 ctx->mRotMgr->getDump(ovDump, 1024); 833 dumpsys_log(aBuf, ovDump); 834 ovDump[0] = '\0'; 835 if(Writeback::getDump(ovDump, 1024)) { 836 dumpsys_log(aBuf, ovDump); 837 ovDump[0] = '\0'; 838 } 839 strlcpy(buff, aBuf.string(), buff_len); 840} 841 842int hwc_getActiveConfig(struct hwc_composer_device_1* /*dev*/, int /*disp*/) { 843 //Supports only the default config (0th index) for now 844 return 0; 845} 846 847int hwc_setActiveConfig(struct hwc_composer_device_1* /*dev*/, int /*disp*/, 848 int index) { 849 //Supports only the default config (0th index) for now 850 return (index == 0) ? index : -EINVAL; 851} 852 853static int hwc_device_close(struct hw_device_t *dev) 854{ 855 if(!dev) { 856 ALOGE("%s: NULL device pointer", __FUNCTION__); 857 return -1; 858 } 859 closeContext((hwc_context_t*)dev); 860 free(dev); 861 862 return 0; 863} 864 865static int hwc_device_open(const struct hw_module_t* module, const char* name, 866 struct hw_device_t** device) 867{ 868 int status = -EINVAL; 869 870 if (!strcmp(name, HWC_HARDWARE_COMPOSER)) { 871 struct hwc_context_t *dev; 872 dev = (hwc_context_t*)malloc(sizeof(*dev)); 873 if(dev == NULL) 874 return status; 875 memset(dev, 0, sizeof(*dev)); 876 877 //Initialize hwc context 878 initContext(dev); 879 880 //Setup HWC methods 881 dev->device.common.tag = HARDWARE_DEVICE_TAG; 882 dev->device.common.version = HWC_DEVICE_API_VERSION_1_4; 883 dev->device.common.module = const_cast<hw_module_t*>(module); 884 dev->device.common.close = hwc_device_close; 885 dev->device.prepare = hwc_prepare; 886 dev->device.set = hwc_set; 887 dev->device.eventControl = hwc_eventControl; 888 dev->device.setPowerMode = hwc_setPowerMode; 889 dev->device.query = hwc_query; 890 dev->device.registerProcs = hwc_registerProcs; 891 dev->device.dump = hwc_dump; 892 dev->device.getDisplayConfigs = hwc_getDisplayConfigs; 893 dev->device.getDisplayAttributes = hwc_getDisplayAttributes; 894 dev->device.getActiveConfig = hwc_getActiveConfig; 895 dev->device.setActiveConfig = hwc_setActiveConfig; 896 *device = &dev->device.common; 897 status = 0; 898 } 899 return status; 900} 901