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