hwc.cpp revision 6e5f4943b740677ec2f124fda808f6fb2d715cde
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * Copyright (C) 2012-2013, 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 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 <mdp_version.h> 32#include "hwc_utils.h" 33#include "hwc_fbupdate.h" 34#include "hwc_mdpcomp.h" 35#include "hwc_dump_layers.h" 36#include "external.h" 37#include "hwc_copybit.h" 38#include "profiler.h" 39 40using namespace qhwc; 41using namespace overlay; 42 43#define VSYNC_DEBUG 0 44#define BLANK_DEBUG 1 45 46static int hwc_device_open(const struct hw_module_t* module, 47 const char* name, 48 struct hw_device_t** device); 49 50static struct hw_module_methods_t hwc_module_methods = { 51 open: hwc_device_open 52}; 53 54hwc_module_t HAL_MODULE_INFO_SYM = { 55 common: { 56 tag: HARDWARE_MODULE_TAG, 57 version_major: 2, 58 version_minor: 0, 59 id: HWC_HARDWARE_MODULE_ID, 60 name: "Qualcomm Hardware Composer Module", 61 author: "CodeAurora Forum", 62 methods: &hwc_module_methods, 63 dso: 0, 64 reserved: {0}, 65 } 66}; 67 68/* 69 * Save callback functions registered to HWC 70 */ 71static void hwc_registerProcs(struct hwc_composer_device_1* dev, 72 hwc_procs_t const* procs) 73{ 74 ALOGI("%s", __FUNCTION__); 75 hwc_context_t* ctx = (hwc_context_t*)(dev); 76 if(!ctx) { 77 ALOGE("%s: Invalid context", __FUNCTION__); 78 return; 79 } 80 ctx->proc = procs; 81 82 // Now that we have the functions needed, kick off 83 // the uevent & vsync threads 84 init_uevent_thread(ctx); 85 init_vsync_thread(ctx); 86} 87 88//Helper 89static void reset(hwc_context_t *ctx, int numDisplays, 90 hwc_display_contents_1_t** displays) { 91 memset(ctx->listStats, 0, sizeof(ctx->listStats)); 92 for(int i = 0; i < MAX_DISPLAYS; i++) { 93 hwc_display_contents_1_t *list = displays[i]; 94 // XXX:SurfaceFlinger no longer guarantees that this 95 // value is reset on every prepare. However, for the layer 96 // cache we need to reset it. 97 // We can probably rethink that later on 98 if (LIKELY(list && list->numHwLayers > 1)) { 99 for(uint32_t j = 0; j < list->numHwLayers; j++) { 100 if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET) 101 list->hwLayers[j].compositionType = HWC_FRAMEBUFFER; 102 } 103 } 104 105 if(ctx->mFBUpdate[i]) 106 ctx->mFBUpdate[i]->reset(); 107 if(ctx->mCopyBit[i]) 108 ctx->mCopyBit[i]->reset(); 109 } 110} 111 112//clear prev layer prop flags and realloc for current frame 113static void reset_layer_prop(hwc_context_t* ctx, int dpy, int numAppLayers) { 114 if(ctx->layerProp[dpy]) { 115 delete[] ctx->layerProp[dpy]; 116 ctx->layerProp[dpy] = NULL; 117 } 118 ctx->layerProp[dpy] = new LayerProp[numAppLayers]; 119} 120 121static int display_commit(hwc_context_t *ctx, int dpy) { 122 struct mdp_display_commit commit_info; 123 memset(&commit_info, 0, sizeof(struct mdp_display_commit)); 124 commit_info.flags = MDP_DISPLAY_COMMIT_OVERLAY; 125 if(ioctl(ctx->dpyAttr[dpy].fd, MSMFB_DISPLAY_COMMIT, &commit_info) == -1) { 126 ALOGE("%s: MSMFB_DISPLAY_COMMIT for primary failed", __FUNCTION__); 127 return -errno; 128 } 129 return 0; 130} 131 132static int hwc_prepare_primary(hwc_composer_device_1 *dev, 133 hwc_display_contents_1_t *list) { 134 hwc_context_t* ctx = (hwc_context_t*)(dev); 135 const int dpy = HWC_DISPLAY_PRIMARY; 136 if (LIKELY(list && list->numHwLayers > 1) && 137 ctx->dpyAttr[dpy].isActive) { 138 reset_layer_prop(ctx, dpy, list->numHwLayers - 1); 139 uint32_t last = list->numHwLayers - 1; 140 hwc_layer_1_t *fbLayer = &list->hwLayers[last]; 141 if(fbLayer->handle) { 142 setListStats(ctx, list, dpy); 143 int fbZOrder = ctx->mMDPComp[dpy]->prepare(ctx, list); 144 if(fbZOrder >= 0) 145 ctx->mFBUpdate[dpy]->prepare(ctx, list, fbZOrder); 146 147 /* Temporarily commenting out C2D until we support partial 148 copybit composition for mixed mode MDP 149 150 // Use Copybit, when MDP comp fails 151 if((fbZOrder >= 0) && ctx->mCopyBit[dpy]) 152 ctx->mCopyBit[dpy]->prepare(ctx, list, dpy); 153 */ 154 } 155 } 156 return 0; 157} 158 159static int hwc_prepare_external(hwc_composer_device_1 *dev, 160 hwc_display_contents_1_t *list, int dpy) { 161 162 hwc_context_t* ctx = (hwc_context_t*)(dev); 163 Locker::Autolock _l(ctx->mExtLock); 164 165 if (LIKELY(list && list->numHwLayers > 1) && 166 ctx->dpyAttr[dpy].isActive && 167 ctx->dpyAttr[dpy].connected) { 168 reset_layer_prop(ctx, dpy, list->numHwLayers - 1); 169 uint32_t last = list->numHwLayers - 1; 170 hwc_layer_1_t *fbLayer = &list->hwLayers[last]; 171 if(!ctx->dpyAttr[dpy].isPause) { 172 if(fbLayer->handle) { 173 ctx->mExtDispConfiguring = false; 174 setListStats(ctx, list, dpy); 175 int fbZOrder = ctx->mMDPComp[dpy]->prepare(ctx, list); 176 if(fbZOrder >= 0) 177 ctx->mFBUpdate[dpy]->prepare(ctx, list, fbZOrder); 178 179 /* Temporarily commenting out C2D until we support partial 180 copybit composition for mixed mode MDP 181 182 if((fbZOrder >= 0) && ctx->mCopyBit[dpy]) 183 ctx->mCopyBit[dpy]->prepare(ctx, list, dpy); 184 */ 185 } 186 } else { 187 // External Display is in Pause state. 188 // ToDo: 189 // Mark all application layers as OVERLAY so that 190 // GPU will not compose. This is done for power 191 // optimization 192 } 193 } 194 return 0; 195} 196 197static int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays, 198 hwc_display_contents_1_t** displays) 199{ 200 int ret = 0; 201 hwc_context_t* ctx = (hwc_context_t*)(dev); 202 Locker::Autolock _l(ctx->mBlankLock); 203 reset(ctx, numDisplays, displays); 204 205 ctx->mOverlay->configBegin(); 206 ctx->mRotMgr->configBegin(); 207 Overlay::setDMAMode(Overlay::DMA_LINE_MODE); 208 209 for (int32_t i = numDisplays; i >= 0; i--) { 210 hwc_display_contents_1_t *list = displays[i]; 211 switch(i) { 212 case HWC_DISPLAY_PRIMARY: 213 ret = hwc_prepare_primary(dev, list); 214 break; 215 case HWC_DISPLAY_EXTERNAL: 216 case HWC_DISPLAY_VIRTUAL: 217 ret = hwc_prepare_external(dev, list, i); 218 break; 219 default: 220 ret = -EINVAL; 221 } 222 } 223 224 ctx->mOverlay->configDone(); 225 ctx->mRotMgr->configDone(); 226 227 return ret; 228} 229 230static int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy, 231 int event, int enable) 232{ 233 int ret = 0; 234 hwc_context_t* ctx = (hwc_context_t*)(dev); 235 pthread_mutex_lock(&ctx->vstate.lock); 236 switch(event) { 237 case HWC_EVENT_VSYNC: 238 if (ctx->vstate.enable == enable) 239 break; 240 ret = hwc_vsync_control(ctx, dpy, enable); 241 if(ret == 0) { 242 ctx->vstate.enable = !!enable; 243 pthread_cond_signal(&ctx->vstate.cond); 244 } 245 ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s", 246 (enable)?"ENABLED":"DISABLED"); 247 break; 248 default: 249 ret = -EINVAL; 250 } 251 pthread_mutex_unlock(&ctx->vstate.lock); 252 return ret; 253} 254 255static int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank) 256{ 257 ATRACE_CALL(); 258 hwc_context_t* ctx = (hwc_context_t*)(dev); 259 260 Locker::Autolock _l(ctx->mBlankLock); 261 int ret = 0; 262 ALOGD_IF(BLANK_DEBUG, "%s: %s display: %d", __FUNCTION__, 263 blank==1 ? "Blanking":"Unblanking", dpy); 264 if(blank) { 265 // free up all the overlay pipes in use 266 // when we get a blank for either display 267 // makes sure that all pipes are freed 268 ctx->mOverlay->configBegin(); 269 ctx->mOverlay->configDone(); 270 ctx->mRotMgr->clear(); 271 } 272 switch(dpy) { 273 case HWC_DISPLAY_PRIMARY: 274 if(blank) { 275 ret = ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK,FB_BLANK_POWERDOWN); 276 277 if(ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected == true) { 278 // Surfaceflinger does not send Blank/unblank event to hwc 279 // for virtual display, handle it explicitly when blank for 280 // primary is invoked, so that any pipes unset get committed 281 if (display_commit(ctx, HWC_DISPLAY_VIRTUAL) < 0) { 282 ret = -1; 283 ALOGE("%s:post failed for virtual display !!", 284 __FUNCTION__); 285 } else { 286 ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive = !blank; 287 } 288 } 289 } else { 290 ret = ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK, FB_BLANK_UNBLANK); 291 if(ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected == true) { 292 ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive = !blank; 293 } 294 } 295 break; 296 case HWC_DISPLAY_EXTERNAL: 297 if(blank) { 298 // call external framebuffer commit on blank, 299 // so that any pipe unsets gets committed 300 if (display_commit(ctx, dpy) < 0) { 301 ret = -1; 302 ALOGE("%s:post failed for external display !! ", 303 __FUNCTION__); 304 } 305 } else { 306 } 307 break; 308 default: 309 return -EINVAL; 310 } 311 // Enable HPD here, as during bootup unblank is called 312 // when SF is completely initialized 313 ctx->mExtDisplay->setHPD(1); 314 if(ret == 0){ 315 ctx->dpyAttr[dpy].isActive = !blank; 316 } else { 317 ALOGE("%s: Failed in %s display: %d error:%s", __FUNCTION__, 318 blank==1 ? "blanking":"unblanking", dpy, strerror(errno)); 319 return ret; 320 } 321 322 ALOGD_IF(BLANK_DEBUG, "%s: Done %s display: %d", __FUNCTION__, 323 blank==1 ? "blanking":"unblanking", dpy); 324 return 0; 325} 326 327static int hwc_query(struct hwc_composer_device_1* dev, 328 int param, int* value) 329{ 330 hwc_context_t* ctx = (hwc_context_t*)(dev); 331 int supported = HWC_DISPLAY_PRIMARY_BIT; 332 333 switch (param) { 334 case HWC_BACKGROUND_LAYER_SUPPORTED: 335 // Not supported for now 336 value[0] = 0; 337 break; 338 case HWC_DISPLAY_TYPES_SUPPORTED: 339 if(ctx->mMDP.hasOverlay) 340 supported |= HWC_DISPLAY_EXTERNAL_BIT; 341 value[0] = supported; 342 break; 343 default: 344 return -EINVAL; 345 } 346 return 0; 347 348} 349 350 351static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) { 352 ATRACE_CALL(); 353 int ret = 0; 354 const int dpy = HWC_DISPLAY_PRIMARY; 355 if (LIKELY(list) && ctx->dpyAttr[dpy].isActive) { 356 uint32_t last = list->numHwLayers - 1; 357 hwc_layer_1_t *fbLayer = &list->hwLayers[last]; 358 int fd = -1; //FenceFD from the Copybit(valid in async mode) 359 bool copybitDone = false; 360 if(ctx->mCopyBit[dpy]) 361 copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd); 362 if(list->numHwLayers > 1) 363 hwc_sync(ctx, list, dpy, fd); 364 365 // Dump the layers for primary 366 if(ctx->mHwcDebug[dpy]) 367 ctx->mHwcDebug[dpy]->dumpLayers(list); 368 369 if (!ctx->mMDPComp[dpy]->draw(ctx, list)) { 370 ALOGE("%s: MDPComp draw failed", __FUNCTION__); 371 ret = -1; 372 } 373 374 //TODO We dont check for SKIP flag on this layer because we need PAN 375 //always. Last layer is always FB 376 private_handle_t *hnd = (private_handle_t *)fbLayer->handle; 377 if(copybitDone) { 378 hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer(); 379 } 380 381 if(hnd) { 382 if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) { 383 ALOGE("%s: FBUpdate draw failed", __FUNCTION__); 384 ret = -1; 385 } 386 } 387 388 if (display_commit(ctx, dpy) < 0) { 389 ALOGE("%s: display commit fail!", __FUNCTION__); 390 return -1; 391 } 392 } 393 394 closeAcquireFds(list); 395 return ret; 396} 397 398static int hwc_set_external(hwc_context_t *ctx, 399 hwc_display_contents_1_t* list, int dpy) 400{ 401 ATRACE_CALL(); 402 int ret = 0; 403 Locker::Autolock _l(ctx->mExtLock); 404 405 if (LIKELY(list) && ctx->dpyAttr[dpy].isActive && 406 !ctx->dpyAttr[dpy].isPause && 407 ctx->dpyAttr[dpy].connected) { 408 uint32_t last = list->numHwLayers - 1; 409 hwc_layer_1_t *fbLayer = &list->hwLayers[last]; 410 int fd = -1; //FenceFD from the Copybit(valid in async mode) 411 bool copybitDone = false; 412 if(ctx->mCopyBit[dpy]) 413 copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd); 414 415 if(list->numHwLayers > 1) 416 hwc_sync(ctx, list, dpy, fd); 417 418 // Dump the layers for external 419 if(ctx->mHwcDebug[dpy]) 420 ctx->mHwcDebug[dpy]->dumpLayers(list); 421 422 if (!ctx->mMDPComp[dpy]->draw(ctx, list)) { 423 ALOGE("%s: MDPComp draw failed", __FUNCTION__); 424 ret = -1; 425 } 426 427 private_handle_t *hnd = (private_handle_t *)fbLayer->handle; 428 if(copybitDone) { 429 hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer(); 430 } 431 432 if(hnd) { 433 if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) { 434 ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__); 435 ret = -1; 436 } 437 } 438 439 if (display_commit(ctx, dpy) < 0) { 440 ALOGE("%s: display commit fail!", __FUNCTION__); 441 ret = -1; 442 } 443 } 444 445 closeAcquireFds(list); 446 return ret; 447} 448 449static int hwc_set(hwc_composer_device_1 *dev, 450 size_t numDisplays, 451 hwc_display_contents_1_t** displays) 452{ 453 int ret = 0; 454 hwc_context_t* ctx = (hwc_context_t*)(dev); 455 Locker::Autolock _l(ctx->mBlankLock); 456 for (uint32_t i = 0; i <= numDisplays; i++) { 457 hwc_display_contents_1_t* list = displays[i]; 458 switch(i) { 459 case HWC_DISPLAY_PRIMARY: 460 ret = hwc_set_primary(ctx, list); 461 break; 462 case HWC_DISPLAY_EXTERNAL: 463 case HWC_DISPLAY_VIRTUAL: 464 /* ToDo: We are using hwc_set_external path for both External and 465 Virtual displays on HWC1.1. Eventually, we will have 466 separate functions when we move to HWC1.2 467 */ 468 ret = hwc_set_external(ctx, list, i); 469 break; 470 default: 471 ret = -EINVAL; 472 } 473 } 474 // This is only indicative of how many times SurfaceFlinger posts 475 // frames to the display. 476 CALC_FPS(); 477 return ret; 478} 479 480int hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp, 481 uint32_t* configs, size_t* numConfigs) { 482 int ret = 0; 483 hwc_context_t* ctx = (hwc_context_t*)(dev); 484 //in 1.1 there is no way to choose a config, report as config id # 0 485 //This config is passed to getDisplayAttributes. Ignore for now. 486 switch(disp) { 487 case HWC_DISPLAY_PRIMARY: 488 if(*numConfigs > 0) { 489 configs[0] = 0; 490 *numConfigs = 1; 491 } 492 ret = 0; //NO_ERROR 493 break; 494 case HWC_DISPLAY_EXTERNAL: 495 ret = -1; //Not connected 496 if(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) { 497 ret = 0; //NO_ERROR 498 if(*numConfigs > 0) { 499 configs[0] = 0; 500 *numConfigs = 1; 501 } 502 } 503 break; 504 } 505 return ret; 506} 507 508int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp, 509 uint32_t config, const uint32_t* attributes, int32_t* values) { 510 511 hwc_context_t* ctx = (hwc_context_t*)(dev); 512 //If hotpluggable displays are inactive return error 513 if(disp == HWC_DISPLAY_EXTERNAL && !ctx->dpyAttr[disp].connected) { 514 return -1; 515 } 516 517 //From HWComposer 518 static const uint32_t DISPLAY_ATTRIBUTES[] = { 519 HWC_DISPLAY_VSYNC_PERIOD, 520 HWC_DISPLAY_WIDTH, 521 HWC_DISPLAY_HEIGHT, 522 HWC_DISPLAY_DPI_X, 523 HWC_DISPLAY_DPI_Y, 524 HWC_DISPLAY_NO_ATTRIBUTE, 525 }; 526 527 const int NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) / 528 sizeof(DISPLAY_ATTRIBUTES)[0]); 529 530 for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) { 531 switch (attributes[i]) { 532 case HWC_DISPLAY_VSYNC_PERIOD: 533 values[i] = ctx->dpyAttr[disp].vsync_period; 534 break; 535 case HWC_DISPLAY_WIDTH: 536 values[i] = ctx->dpyAttr[disp].xres; 537 ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp, 538 ctx->dpyAttr[disp].xres); 539 break; 540 case HWC_DISPLAY_HEIGHT: 541 values[i] = ctx->dpyAttr[disp].yres; 542 ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp, 543 ctx->dpyAttr[disp].yres); 544 break; 545 case HWC_DISPLAY_DPI_X: 546 values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0); 547 break; 548 case HWC_DISPLAY_DPI_Y: 549 values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0); 550 break; 551 default: 552 ALOGE("Unknown display attribute %d", 553 attributes[i]); 554 return -EINVAL; 555 } 556 } 557 return 0; 558} 559 560void hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len) 561{ 562 hwc_context_t* ctx = (hwc_context_t*)(dev); 563 android::String8 aBuf(""); 564 dumpsys_log(aBuf, "Qualcomm HWC state:\n"); 565 dumpsys_log(aBuf, " MDPVersion=%d\n", ctx->mMDP.version); 566 dumpsys_log(aBuf, " DisplayPanel=%c\n", ctx->mMDP.panel); 567 for(int dpy = 0; dpy < MAX_DISPLAYS; dpy++) { 568 if(ctx->mMDPComp[dpy]) 569 ctx->mMDPComp[dpy]->dump(aBuf); 570 } 571 char ovDump[2048] = {'\0'}; 572 ctx->mOverlay->getDump(ovDump, 2048); 573 dumpsys_log(aBuf, ovDump); 574 ovDump[0] = '\0'; 575 ctx->mRotMgr->getDump(ovDump, 1024); 576 dumpsys_log(aBuf, ovDump); 577 strlcpy(buff, aBuf.string(), buff_len); 578} 579 580static int hwc_device_close(struct hw_device_t *dev) 581{ 582 if(!dev) { 583 ALOGE("%s: NULL device pointer", __FUNCTION__); 584 return -1; 585 } 586 closeContext((hwc_context_t*)dev); 587 free(dev); 588 589 return 0; 590} 591 592static int hwc_device_open(const struct hw_module_t* module, const char* name, 593 struct hw_device_t** device) 594{ 595 int status = -EINVAL; 596 597 if (!strcmp(name, HWC_HARDWARE_COMPOSER)) { 598 struct hwc_context_t *dev; 599 dev = (hwc_context_t*)malloc(sizeof(*dev)); 600 memset(dev, 0, sizeof(*dev)); 601 602 //Initialize hwc context 603 initContext(dev); 604 605 //Setup HWC methods 606 dev->device.common.tag = HARDWARE_DEVICE_TAG; 607 dev->device.common.version = HWC_DEVICE_API_VERSION_1_1; 608 dev->device.common.module = const_cast<hw_module_t*>(module); 609 dev->device.common.close = hwc_device_close; 610 dev->device.prepare = hwc_prepare; 611 dev->device.set = hwc_set; 612 dev->device.eventControl = hwc_eventControl; 613 dev->device.blank = hwc_blank; 614 dev->device.query = hwc_query; 615 dev->device.registerProcs = hwc_registerProcs; 616 dev->device.dump = hwc_dump; 617 dev->device.getDisplayConfigs = hwc_getDisplayConfigs; 618 dev->device.getDisplayAttributes = hwc_getDisplayAttributes; 619 *device = &dev->device.common; 620 status = 0; 621 } 622 return status; 623} 624