1 /* 2 // Copyright(c)2014 IntelCorporation 3 // 4 // LicensedundertheApacheLicense,Version2.0(the"License"); 5 // youmaynotusethisfileexceptincompliancewiththeLicense. 6 // YoumayobtainacopyoftheLicenseat 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unlessrequiredbyapplicablelaworagreedtoinwriting,software 11 // distributedundertheLicenseisdistributedonan"ASIS"BASIS, 12 // WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied. 13 // SeetheLicenseforthespecificlanguagegoverningpermissionsand 14 // limitationsundertheLicense. 15 */ 16 #include <HwcTrace.h> 17 #include <Hwcomposer.h> 18 #include <Dump.h> 19 #include <UeventObserver.h> 20 21 namespace android { 22 namespace intel { 23 24 Hwcomposer* Hwcomposer::sInstance(0); 25 26 Hwcomposer::Hwcomposer(IPlatFactory *factory) 27 : mProcs(0), 28 mDrm(0), 29 mPlatFactory(factory), 30 mVsyncManager(0), 31 mDisplayAnalyzer(0), 32 mMultiDisplayObserver(0), 33 mUeventObserver(0), 34 mPlaneManager(0), 35 mBufferManager(0), 36 mDisplayContext(0), 37 mInitialized(false) 38 { 39 CTRACE(); 40 41 mDisplayDevices.setCapacity(IDisplayDevice::DEVICE_COUNT); 42 mDisplayDevices.clear(); 43 } 44 45 Hwcomposer::~Hwcomposer() 46 { 47 CTRACE(); 48 deinitialize(); 49 } 50 51 bool Hwcomposer::initCheck() const 52 { 53 return mInitialized; 54 } 55 56 bool Hwcomposer::prepare(size_t numDisplays, 57 hwc_display_contents_1_t** displays) 58 { 59 bool ret = true; 60 61 RETURN_FALSE_IF_NOT_INIT(); 62 ATRACE("display count = %d", numDisplays); 63 64 if (!numDisplays || !displays) { 65 ETRACE("invalid parameters"); 66 return false; 67 } 68 69 mDisplayAnalyzer->analyzeContents(numDisplays, displays); 70 71 // disable reclaimed planes 72 mPlaneManager->disableReclaimedPlanes(); 73 74 if(numDisplays > mDisplayDevices.size()) 75 numDisplays = mDisplayDevices.size(); 76 77 // reclaim all allocated planes if possible 78 for (size_t i = 0; i < numDisplays; i++) { 79 IDisplayDevice *device = mDisplayDevices.itemAt(i); 80 if (!device) { 81 VTRACE("device %d doesn't exist", i); 82 continue; 83 } 84 if (device->getType() != IDisplayDevice::DEVICE_PRIMARY) 85 continue; 86 87 device->prePrepare(displays[i]); 88 } 89 90 for (size_t i = 0; i < numDisplays; i++) { 91 IDisplayDevice *device = mDisplayDevices.itemAt(i); 92 if (!device) { 93 VTRACE("device %d doesn't exist", i); 94 continue; 95 } 96 97 if (device->getType() != IDisplayDevice::DEVICE_PRIMARY) 98 continue; 99 100 ret = device->prepare(displays[i]); 101 if (ret == false) { 102 ETRACE("failed to do prepare for device %d", i); 103 continue; 104 } 105 } 106 107 return ret; 108 } 109 110 bool Hwcomposer::commit(size_t numDisplays, 111 hwc_display_contents_1_t **displays) 112 { 113 bool ret = true; 114 115 RETURN_FALSE_IF_NOT_INIT(); 116 ATRACE("display count = %d", numDisplays); 117 118 if (!numDisplays || !displays) { 119 ETRACE("invalid parameters"); 120 return false; 121 } 122 123 if(numDisplays > mDisplayDevices.size()) 124 numDisplays = mDisplayDevices.size(); 125 126 mDisplayContext->commitBegin(numDisplays, displays); 127 128 for (size_t i = 0; i < numDisplays; i++) { 129 IDisplayDevice *device = mDisplayDevices.itemAt(i); 130 if (!device) { 131 VTRACE("device %d doesn't exist", i); 132 continue; 133 } 134 135 if (!device->isConnected()) { 136 VTRACE("device %d is disconnected", i); 137 continue; 138 } 139 140 if (device->getType() != IDisplayDevice::DEVICE_PRIMARY) 141 continue; 142 143 ret = device->commit(displays[i], mDisplayContext); 144 if (ret == false) { 145 ETRACE("failed to do commit for device %d", i); 146 continue; 147 } 148 } 149 150 mDisplayContext->commitEnd(numDisplays, displays); 151 // return true always 152 return true; 153 } 154 155 bool Hwcomposer::setPowerMode(int disp, int mode) 156 { 157 RETURN_FALSE_IF_NOT_INIT(); 158 159 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) { 160 ETRACE("invalid disp %d", disp); 161 return false; 162 } 163 164 if(disp >= mDisplayDevices.size()){ 165 ETRACE("no device found"); 166 return false; 167 } 168 169 IDisplayDevice *device = mDisplayDevices.itemAt(disp); 170 if (!device) { 171 ETRACE("no device found"); 172 return false; 173 } 174 175 return device->setPowerMode(mode); 176 } 177 178 int Hwcomposer::getActiveConfig(int disp) 179 { 180 RETURN_NULL_IF_NOT_INIT(); 181 182 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) { 183 ETRACE("invalid disp %d", disp); 184 return -1; 185 } 186 187 IDisplayDevice *device = mDisplayDevices.itemAt(disp); 188 if (!device) { 189 ETRACE("no device found"); 190 return -1; 191 } 192 193 return device->getActiveConfig(); 194 } 195 196 bool Hwcomposer::setActiveConfig(int disp, int index) 197 { 198 RETURN_FALSE_IF_NOT_INIT(); 199 200 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) { 201 ETRACE("invalid disp %d", disp); 202 return false; 203 } 204 205 IDisplayDevice *device = mDisplayDevices.itemAt(disp); 206 if (!device) { 207 ETRACE("no device found"); 208 return false; 209 } 210 211 return device->setActiveConfig(index); 212 } 213 214 bool Hwcomposer::setCursorPositionAsync(int disp, int x, int y) 215 { 216 RETURN_FALSE_IF_NOT_INIT(); 217 218 if (disp != HWC_DISPLAY_PRIMARY && disp != HWC_DISPLAY_EXTERNAL) { 219 ETRACE("invalid disp %d", disp); 220 return false; 221 } 222 223 return mDisplayContext->setCursorPosition(disp, x, y); 224 } 225 226 bool Hwcomposer::vsyncControl(int disp, int enabled) 227 { 228 RETURN_FALSE_IF_NOT_INIT(); 229 ATRACE("disp = %d, enabled = %d", disp, enabled); 230 return mVsyncManager->handleVsyncControl(disp, enabled ? true : false); 231 } 232 233 bool Hwcomposer::blank(int disp, int blank) 234 { 235 RETURN_FALSE_IF_NOT_INIT(); 236 ATRACE("disp = %d, blank = %d", disp, blank); 237 238 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) { 239 ETRACE("invalid disp %d", disp); 240 return false; 241 } 242 243 IDisplayDevice *device = mDisplayDevices.itemAt(disp); 244 if (!device) { 245 ETRACE("no device found"); 246 return false; 247 } 248 249 return device->blank(blank ? true : false); 250 } 251 252 bool Hwcomposer::getDisplayConfigs(int disp, 253 uint32_t *configs, 254 size_t *numConfigs) 255 { 256 RETURN_FALSE_IF_NOT_INIT(); 257 258 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) { 259 ETRACE("invalid disp %d", disp); 260 return false; 261 } 262 263 if(disp >= mDisplayDevices.size()){ 264 ETRACE("no device found"); 265 return false; 266 } 267 268 IDisplayDevice *device = mDisplayDevices.itemAt(disp); 269 if (!device) { 270 ETRACE("no device %d found", disp); 271 return false; 272 } 273 274 return device->getDisplayConfigs(configs, numConfigs); 275 } 276 277 bool Hwcomposer::getDisplayAttributes(int disp, 278 uint32_t config, 279 const uint32_t *attributes, 280 int32_t *values) 281 { 282 RETURN_FALSE_IF_NOT_INIT(); 283 284 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) { 285 ETRACE("invalid disp %d", disp); 286 return false; 287 } 288 if(disp >= mDisplayDevices.size()){ 289 ETRACE("no device found"); 290 return false; 291 } 292 293 294 IDisplayDevice *device = mDisplayDevices.itemAt(disp); 295 if (!device) { 296 ETRACE("no device found"); 297 return false; 298 } 299 300 return device->getDisplayAttributes(config, attributes, values); 301 } 302 303 bool Hwcomposer::compositionComplete(int disp) 304 { 305 RETURN_FALSE_IF_NOT_INIT(); 306 307 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) { 308 ETRACE("invalid disp %d", disp); 309 return false; 310 } 311 312 mDisplayContext->compositionComplete(); 313 314 if(disp >= mDisplayDevices.size()){ 315 ETRACE("no device found"); 316 return false; 317 } 318 319 IDisplayDevice *device = mDisplayDevices.itemAt(disp); 320 if (!device) { 321 ETRACE("no device found"); 322 return false; 323 } 324 325 return device->compositionComplete(); 326 } 327 328 void Hwcomposer::vsync(int disp, int64_t timestamp) 329 { 330 RETURN_VOID_IF_NOT_INIT(); 331 332 if (mProcs && mProcs->vsync) { 333 VTRACE("report vsync on disp %d, timestamp %llu", disp, timestamp); 334 // workaround to pretend vsync is from primary display 335 // Display will freeze if vsync is from external display. 336 mProcs->vsync(const_cast<hwc_procs_t*>(mProcs), IDisplayDevice::DEVICE_PRIMARY, timestamp); 337 } 338 } 339 340 void Hwcomposer::hotplug(int disp, bool connected) 341 { 342 RETURN_VOID_IF_NOT_INIT(); 343 344 // TODO: Two fake hotplug events are sent during mode setting. To avoid 345 // unnecessary audio switch, real connection status should be sent to MDS 346 mMultiDisplayObserver->notifyHotPlug(mDrm->isConnected(disp)); 347 348 if (mProcs && mProcs->hotplug) { 349 DTRACE("report hotplug on disp %d, connected %d", disp, connected); 350 mProcs->hotplug(const_cast<hwc_procs_t*>(mProcs), disp, connected); 351 DTRACE("hotplug callback processed and returned!"); 352 } 353 354 mDisplayAnalyzer->postHotplugEvent(connected); 355 } 356 357 void Hwcomposer::invalidate() 358 { 359 RETURN_VOID_IF_NOT_INIT(); 360 361 if (mProcs && mProcs->invalidate) { 362 DTRACE("invalidating screen..."); 363 mProcs->invalidate(const_cast<hwc_procs_t*>(mProcs)); 364 } 365 } 366 367 bool Hwcomposer::release() 368 { 369 RETURN_FALSE_IF_NOT_INIT(); 370 371 return true; 372 } 373 374 bool Hwcomposer::dump(char *buff, int buff_len, int *cur_len) 375 { 376 RETURN_FALSE_IF_NOT_INIT(); 377 378 Dump d(buff, buff_len); 379 380 // dump composer status 381 d.append("Hardware Composer state:"); 382 // dump device status 383 for (size_t i= 0; i < mDisplayDevices.size(); i++) { 384 IDisplayDevice *device = mDisplayDevices.itemAt(i); 385 if (device) 386 device->dump(d); 387 } 388 389 // dump plane manager status 390 if (mPlaneManager) 391 mPlaneManager->dump(d); 392 393 // dump buffer manager status 394 if (mBufferManager) 395 mBufferManager->dump(d); 396 397 return true; 398 } 399 400 void Hwcomposer::registerProcs(hwc_procs_t const *procs) 401 { 402 CTRACE(); 403 404 if (!procs) { 405 WTRACE("procs is NULL"); 406 } 407 mProcs = procs; 408 } 409 410 bool Hwcomposer::initialize() 411 { 412 CTRACE(); 413 414 // create drm 415 mDrm = new Drm(); 416 if (!mDrm || !mDrm->initialize()) { 417 DEINIT_AND_RETURN_FALSE("failed to create DRM"); 418 } 419 420 if (!mPlatFactory){ 421 DEINIT_AND_RETURN_FALSE("failed to provide a PlatFactory"); 422 } 423 424 // create buffer manager 425 mBufferManager = mPlatFactory->createBufferManager(); 426 if (!mBufferManager || !mBufferManager->initialize()) { 427 DEINIT_AND_RETURN_FALSE("failed to create buffer manager"); 428 } 429 430 // create display plane manager 431 mPlaneManager = mPlatFactory->createDisplayPlaneManager(); 432 if (!mPlaneManager || !mPlaneManager->initialize()) { 433 DEINIT_AND_RETURN_FALSE("failed to create display plane manager"); 434 } 435 436 mDisplayContext = mPlatFactory->createDisplayContext(); 437 if (!mDisplayContext || !mDisplayContext->initialize()) { 438 DEINIT_AND_RETURN_FALSE("failed to create display context"); 439 } 440 441 mUeventObserver = new UeventObserver(); 442 if (!mUeventObserver || !mUeventObserver->initialize()) { 443 DEINIT_AND_RETURN_FALSE("failed to initialize uevent observer"); 444 } 445 446 // create display device 447 mDisplayDevices.clear(); 448 for (int i = 0; i < IDisplayDevice::DEVICE_COUNT; i++) { 449 IDisplayDevice *device = mPlatFactory->createDisplayDevice(i); 450 if (!device || !device->initialize()) { 451 DEINIT_AND_DELETE_OBJ(device); 452 DEINIT_AND_RETURN_FALSE("failed to create device %d", i); 453 } 454 // add this device 455 ETRACE("HWC devices initialize device is %p at %d", device, i); 456 mDisplayDevices.insertAt(device, i, 1); 457 } 458 459 mVsyncManager = new VsyncManager(*this); 460 if (!mVsyncManager || !mVsyncManager->initialize()) { 461 DEINIT_AND_RETURN_FALSE("failed to create Vsync Manager"); 462 } 463 464 mDisplayAnalyzer = new DisplayAnalyzer(); 465 if (!mDisplayAnalyzer || !mDisplayAnalyzer->initialize()) { 466 DEINIT_AND_RETURN_FALSE("failed to initialize display analyzer"); 467 } 468 469 mMultiDisplayObserver = new MultiDisplayObserver(); 470 if (!mMultiDisplayObserver || !mMultiDisplayObserver->initialize()) { 471 DEINIT_AND_RETURN_FALSE("failed to initialize display observer"); 472 } 473 474 // all initialized, starting uevent observer 475 mUeventObserver->start(); 476 477 mInitialized = true; 478 return true; 479 } 480 481 void Hwcomposer::deinitialize() 482 { 483 DEINIT_AND_DELETE_OBJ(mMultiDisplayObserver); 484 DEINIT_AND_DELETE_OBJ(mDisplayAnalyzer); 485 // delete mVsyncManager first as it holds reference to display devices. 486 DEINIT_AND_DELETE_OBJ(mVsyncManager); 487 488 DEINIT_AND_DELETE_OBJ(mUeventObserver); 489 // destroy display devices 490 for (size_t i = 0; i < mDisplayDevices.size(); i++) { 491 IDisplayDevice *device = mDisplayDevices.itemAt(i); 492 DEINIT_AND_DELETE_OBJ(device); 493 } 494 mDisplayDevices.clear(); 495 496 if (mPlatFactory) { 497 delete mPlatFactory; 498 mPlatFactory = 0; 499 } 500 501 DEINIT_AND_DELETE_OBJ(mDisplayContext); 502 DEINIT_AND_DELETE_OBJ(mPlaneManager); 503 DEINIT_AND_DELETE_OBJ(mBufferManager); 504 DEINIT_AND_DELETE_OBJ(mDrm); 505 mInitialized = false; 506 } 507 508 Drm* Hwcomposer::getDrm() 509 { 510 return mDrm; 511 } 512 513 DisplayPlaneManager* Hwcomposer::getPlaneManager() 514 { 515 return mPlaneManager; 516 } 517 518 BufferManager* Hwcomposer::getBufferManager() 519 { 520 return mBufferManager; 521 } 522 523 IDisplayContext* Hwcomposer::getDisplayContext() 524 { 525 return mDisplayContext; 526 } 527 528 DisplayAnalyzer* Hwcomposer::getDisplayAnalyzer() 529 { 530 return mDisplayAnalyzer; 531 } 532 533 MultiDisplayObserver* Hwcomposer::getMultiDisplayObserver() 534 { 535 return mMultiDisplayObserver; 536 } 537 538 IDisplayDevice* Hwcomposer::getDisplayDevice(int disp) 539 { 540 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) { 541 ETRACE("invalid disp %d", disp); 542 return NULL; 543 } 544 return mDisplayDevices.itemAt(disp); 545 } 546 547 VsyncManager* Hwcomposer::getVsyncManager() 548 { 549 return mVsyncManager; 550 } 551 552 UeventObserver* Hwcomposer::getUeventObserver() 553 { 554 return mUeventObserver; 555 } 556 557 } // namespace intel 558 } // namespace android 559