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