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