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