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