1 /* 2 * Copyright 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 // #define LOG_NDEBUG 0 18 19 #undef LOG_TAG 20 #define LOG_TAG "HWC2" 21 #define ATRACE_TAG ATRACE_TAG_GRAPHICS 22 23 #include "HWC2.h" 24 #include "ComposerHal.h" 25 26 #include <ui/Fence.h> 27 #include <ui/FloatRect.h> 28 #include <ui/GraphicBuffer.h> 29 #include <ui/Region.h> 30 31 #include <android/configuration.h> 32 33 #include <algorithm> 34 #include <inttypes.h> 35 36 extern "C" { 37 static void hotplug_hook(hwc2_callback_data_t callbackData, 38 hwc2_display_t displayId, int32_t intConnected) { 39 auto device = static_cast<HWC2::Device*>(callbackData); 40 auto display = device->getDisplayById(displayId); 41 if (display) { 42 auto connected = static_cast<HWC2::Connection>(intConnected); 43 device->callHotplug(std::move(display), connected); 44 } else { 45 ALOGE("Hotplug callback called with unknown display %" PRIu64, 46 displayId); 47 } 48 } 49 50 static void refresh_hook(hwc2_callback_data_t callbackData, 51 hwc2_display_t displayId) { 52 auto device = static_cast<HWC2::Device*>(callbackData); 53 auto display = device->getDisplayById(displayId); 54 if (display) { 55 device->callRefresh(std::move(display)); 56 } else { 57 ALOGE("Refresh callback called with unknown display %" PRIu64, 58 displayId); 59 } 60 } 61 62 static void vsync_hook(hwc2_callback_data_t callbackData, 63 hwc2_display_t displayId, int64_t timestamp) { 64 auto device = static_cast<HWC2::Device*>(callbackData); 65 auto display = device->getDisplayById(displayId); 66 if (display) { 67 device->callVsync(std::move(display), timestamp); 68 } else { 69 ALOGE("Vsync callback called with unknown display %" PRIu64, 70 displayId); 71 } 72 } 73 } 74 75 using android::Fence; 76 using android::FloatRect; 77 using android::GraphicBuffer; 78 using android::HdrCapabilities; 79 using android::Rect; 80 using android::Region; 81 using android::sp; 82 using android::hardware::Return; 83 using android::hardware::Void; 84 85 namespace HWC2 { 86 87 namespace Hwc2 = android::Hwc2; 88 89 // Device methods 90 91 Device::Device(bool useVrComposer) 92 : mComposer(std::make_unique<Hwc2::Composer>(useVrComposer)), 93 mCapabilities(), 94 mDisplays(), 95 mHotplug(), 96 mPendingHotplugs(), 97 mRefresh(), 98 mPendingRefreshes(), 99 mVsync(), 100 mPendingVsyncs() 101 { 102 loadCapabilities(); 103 registerCallbacks(); 104 } 105 106 Device::~Device() 107 { 108 for (auto element : mDisplays) { 109 auto display = element.second.lock(); 110 if (!display) { 111 ALOGE("~Device: Found a display (%" PRId64 " that has already been" 112 " destroyed", element.first); 113 continue; 114 } 115 116 DisplayType displayType = HWC2::DisplayType::Invalid; 117 auto error = display->getType(&displayType); 118 if (error != Error::None) { 119 ALOGE("~Device: Failed to determine type of display %" PRIu64 120 ": %s (%d)", display->getId(), to_string(error).c_str(), 121 static_cast<int32_t>(error)); 122 continue; 123 } 124 125 if (displayType == HWC2::DisplayType::Physical) { 126 error = display->setVsyncEnabled(HWC2::Vsync::Disable); 127 if (error != Error::None) { 128 ALOGE("~Device: Failed to disable vsync for display %" PRIu64 129 ": %s (%d)", display->getId(), to_string(error).c_str(), 130 static_cast<int32_t>(error)); 131 } 132 } 133 } 134 } 135 136 // Required by HWC2 device 137 138 std::string Device::dump() const 139 { 140 return mComposer->dumpDebugInfo(); 141 } 142 143 uint32_t Device::getMaxVirtualDisplayCount() const 144 { 145 return mComposer->getMaxVirtualDisplayCount(); 146 } 147 148 Error Device::createVirtualDisplay(uint32_t width, uint32_t height, 149 android_pixel_format_t* format, std::shared_ptr<Display>* outDisplay) 150 { 151 ALOGI("Creating virtual display"); 152 153 hwc2_display_t displayId = 0; 154 auto intFormat = static_cast<Hwc2::PixelFormat>(*format); 155 auto intError = mComposer->createVirtualDisplay(width, height, 156 &intFormat, &displayId); 157 auto error = static_cast<Error>(intError); 158 if (error != Error::None) { 159 return error; 160 } 161 162 ALOGI("Created virtual display"); 163 *format = static_cast<android_pixel_format_t>(intFormat); 164 *outDisplay = getDisplayById(displayId); 165 if (!*outDisplay) { 166 ALOGE("Failed to get display by id"); 167 return Error::BadDisplay; 168 } 169 (*outDisplay)->setConnected(true); 170 return Error::None; 171 } 172 173 void Device::registerHotplugCallback(HotplugCallback hotplug) 174 { 175 ALOGV("registerHotplugCallback"); 176 mHotplug = hotplug; 177 for (auto& pending : mPendingHotplugs) { 178 auto& display = pending.first; 179 auto connected = pending.second; 180 ALOGV("Sending pending hotplug(%" PRIu64 ", %s)", display->getId(), 181 to_string(connected).c_str()); 182 mHotplug(std::move(display), connected); 183 } 184 } 185 186 void Device::registerRefreshCallback(RefreshCallback refresh) 187 { 188 mRefresh = refresh; 189 for (auto& pending : mPendingRefreshes) { 190 mRefresh(std::move(pending)); 191 } 192 } 193 194 void Device::registerVsyncCallback(VsyncCallback vsync) 195 { 196 mVsync = vsync; 197 for (auto& pending : mPendingVsyncs) { 198 auto& display = pending.first; 199 auto timestamp = pending.second; 200 mVsync(std::move(display), timestamp); 201 } 202 } 203 204 // For use by Device callbacks 205 206 void Device::callHotplug(std::shared_ptr<Display> display, Connection connected) 207 { 208 if (connected == Connection::Connected) { 209 if (!display->isConnected()) { 210 mComposer->setClientTargetSlotCount(display->getId()); 211 display->loadConfigs(); 212 display->setConnected(true); 213 } 214 } else { 215 display->setConnected(false); 216 mDisplays.erase(display->getId()); 217 } 218 219 if (mHotplug) { 220 mHotplug(std::move(display), connected); 221 } else { 222 ALOGV("callHotplug called, but no valid callback registered, storing"); 223 mPendingHotplugs.emplace_back(std::move(display), connected); 224 } 225 } 226 227 void Device::callRefresh(std::shared_ptr<Display> display) 228 { 229 if (mRefresh) { 230 mRefresh(std::move(display)); 231 } else { 232 ALOGV("callRefresh called, but no valid callback registered, storing"); 233 mPendingRefreshes.emplace_back(std::move(display)); 234 } 235 } 236 237 void Device::callVsync(std::shared_ptr<Display> display, nsecs_t timestamp) 238 { 239 if (mVsync) { 240 mVsync(std::move(display), timestamp); 241 } else { 242 ALOGV("callVsync called, but no valid callback registered, storing"); 243 mPendingVsyncs.emplace_back(std::move(display), timestamp); 244 } 245 } 246 247 // Other Device methods 248 249 std::shared_ptr<Display> Device::getDisplayById(hwc2_display_t id) { 250 if (mDisplays.count(id) != 0) { 251 auto strongDisplay = mDisplays[id].lock(); 252 ALOGE_IF(!strongDisplay, "Display %" PRId64 " is in mDisplays but is no" 253 " longer alive", id); 254 return strongDisplay; 255 } 256 257 auto display = std::make_shared<Display>(*this, id); 258 mDisplays.emplace(id, display); 259 return display; 260 } 261 262 // Device initialization methods 263 264 void Device::loadCapabilities() 265 { 266 static_assert(sizeof(Capability) == sizeof(int32_t), 267 "Capability size has changed"); 268 auto capabilities = mComposer->getCapabilities(); 269 for (auto capability : capabilities) { 270 mCapabilities.emplace(static_cast<Capability>(capability)); 271 } 272 } 273 274 bool Device::hasCapability(HWC2::Capability capability) const 275 { 276 return std::find(mCapabilities.cbegin(), mCapabilities.cend(), 277 capability) != mCapabilities.cend(); 278 } 279 280 namespace { 281 class ComposerCallback : public Hwc2::IComposerCallback { 282 public: 283 ComposerCallback(Device* device) : mDevice(device) {} 284 285 Return<void> onHotplug(Hwc2::Display display, 286 Connection connected) override 287 { 288 hotplug_hook(mDevice, display, static_cast<int32_t>(connected)); 289 return Void(); 290 } 291 292 Return<void> onRefresh(Hwc2::Display display) override 293 { 294 refresh_hook(mDevice, display); 295 return Void(); 296 } 297 298 Return<void> onVsync(Hwc2::Display display, int64_t timestamp) override 299 { 300 vsync_hook(mDevice, display, timestamp); 301 return Void(); 302 } 303 304 private: 305 Device* mDevice; 306 }; 307 } // namespace anonymous 308 309 void Device::registerCallbacks() 310 { 311 sp<ComposerCallback> callback = new ComposerCallback(this); 312 mComposer->registerCallback(callback); 313 } 314 315 316 // For use by Display 317 318 void Device::destroyVirtualDisplay(hwc2_display_t display) 319 { 320 ALOGI("Destroying virtual display"); 321 auto intError = mComposer->destroyVirtualDisplay(display); 322 auto error = static_cast<Error>(intError); 323 ALOGE_IF(error != Error::None, "destroyVirtualDisplay(%" PRIu64 ") failed:" 324 " %s (%d)", display, to_string(error).c_str(), intError); 325 mDisplays.erase(display); 326 } 327 328 // Display methods 329 330 Display::Display(Device& device, hwc2_display_t id) 331 : mDevice(device), 332 mId(id), 333 mIsConnected(false), 334 mType(DisplayType::Invalid) 335 { 336 ALOGV("Created display %" PRIu64, id); 337 338 auto intError = mDevice.mComposer->getDisplayType(mId, 339 reinterpret_cast<Hwc2::IComposerClient::DisplayType *>(&mType)); 340 auto error = static_cast<Error>(intError); 341 if (error != Error::None) { 342 ALOGE("getDisplayType(%" PRIu64 ") failed: %s (%d)", 343 id, to_string(error).c_str(), intError); 344 } 345 } 346 347 Display::~Display() 348 { 349 ALOGV("Destroyed display %" PRIu64, mId); 350 if (mType == DisplayType::Virtual) { 351 mDevice.destroyVirtualDisplay(mId); 352 } 353 } 354 355 Display::Config::Config(Display& display, hwc2_config_t id) 356 : mDisplay(display), 357 mId(id), 358 mWidth(-1), 359 mHeight(-1), 360 mVsyncPeriod(-1), 361 mDpiX(-1), 362 mDpiY(-1) {} 363 364 Display::Config::Builder::Builder(Display& display, hwc2_config_t id) 365 : mConfig(new Config(display, id)) {} 366 367 float Display::Config::Builder::getDefaultDensity() { 368 // Default density is based on TVs: 1080p displays get XHIGH density, lower- 369 // resolution displays get TV density. Maybe eventually we'll need to update 370 // it for 4k displays, though hopefully those will just report accurate DPI 371 // information to begin with. This is also used for virtual displays and 372 // older HWC implementations, so be careful about orientation. 373 374 auto longDimension = std::max(mConfig->mWidth, mConfig->mHeight); 375 if (longDimension >= 1080) { 376 return ACONFIGURATION_DENSITY_XHIGH; 377 } else { 378 return ACONFIGURATION_DENSITY_TV; 379 } 380 } 381 382 // Required by HWC2 display 383 384 Error Display::acceptChanges() 385 { 386 auto intError = mDevice.mComposer->acceptDisplayChanges(mId); 387 return static_cast<Error>(intError); 388 } 389 390 Error Display::createLayer(std::shared_ptr<Layer>* outLayer) 391 { 392 hwc2_layer_t layerId = 0; 393 auto intError = mDevice.mComposer->createLayer(mId, &layerId); 394 auto error = static_cast<Error>(intError); 395 if (error != Error::None) { 396 return error; 397 } 398 399 auto layer = std::make_shared<Layer>(shared_from_this(), layerId); 400 mLayers.emplace(layerId, layer); 401 *outLayer = std::move(layer); 402 return Error::None; 403 } 404 405 Error Display::getActiveConfig( 406 std::shared_ptr<const Display::Config>* outConfig) const 407 { 408 ALOGV("[%" PRIu64 "] getActiveConfig", mId); 409 hwc2_config_t configId = 0; 410 auto intError = mDevice.mComposer->getActiveConfig(mId, &configId); 411 auto error = static_cast<Error>(intError); 412 413 if (error != Error::None) { 414 ALOGE("Unable to get active config for mId:[%" PRIu64 "]", mId); 415 *outConfig = nullptr; 416 return error; 417 } 418 419 if (mConfigs.count(configId) != 0) { 420 *outConfig = mConfigs.at(configId); 421 } else { 422 ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId, 423 configId); 424 // Return no error, but the caller needs to check for a null pointer to 425 // detect this case 426 *outConfig = nullptr; 427 } 428 429 return Error::None; 430 } 431 432 Error Display::getChangedCompositionTypes( 433 std::unordered_map<std::shared_ptr<Layer>, Composition>* outTypes) 434 { 435 std::vector<Hwc2::Layer> layerIds; 436 std::vector<Hwc2::IComposerClient::Composition> types; 437 auto intError = mDevice.mComposer->getChangedCompositionTypes(mId, 438 &layerIds, &types); 439 uint32_t numElements = layerIds.size(); 440 auto error = static_cast<Error>(intError); 441 error = static_cast<Error>(intError); 442 if (error != Error::None) { 443 return error; 444 } 445 446 outTypes->clear(); 447 outTypes->reserve(numElements); 448 for (uint32_t element = 0; element < numElements; ++element) { 449 auto layer = getLayerById(layerIds[element]); 450 if (layer) { 451 auto type = static_cast<Composition>(types[element]); 452 ALOGV("getChangedCompositionTypes: adding %" PRIu64 " %s", 453 layer->getId(), to_string(type).c_str()); 454 outTypes->emplace(layer, type); 455 } else { 456 ALOGE("getChangedCompositionTypes: invalid layer %" PRIu64 " found" 457 " on display %" PRIu64, layerIds[element], mId); 458 } 459 } 460 461 return Error::None; 462 } 463 464 Error Display::getColorModes(std::vector<android_color_mode_t>* outModes) const 465 { 466 std::vector<Hwc2::ColorMode> modes; 467 auto intError = mDevice.mComposer->getColorModes(mId, &modes); 468 uint32_t numModes = modes.size(); 469 auto error = static_cast<Error>(intError); 470 if (error != Error::None) { 471 return error; 472 } 473 474 outModes->resize(numModes); 475 for (size_t i = 0; i < numModes; i++) { 476 (*outModes)[i] = static_cast<android_color_mode_t>(modes[i]); 477 } 478 return Error::None; 479 } 480 481 std::vector<std::shared_ptr<const Display::Config>> Display::getConfigs() const 482 { 483 std::vector<std::shared_ptr<const Config>> configs; 484 for (const auto& element : mConfigs) { 485 configs.emplace_back(element.second); 486 } 487 return configs; 488 } 489 490 Error Display::getName(std::string* outName) const 491 { 492 auto intError = mDevice.mComposer->getDisplayName(mId, outName); 493 return static_cast<Error>(intError); 494 } 495 496 Error Display::getRequests(HWC2::DisplayRequest* outDisplayRequests, 497 std::unordered_map<std::shared_ptr<Layer>, LayerRequest>* 498 outLayerRequests) 499 { 500 uint32_t intDisplayRequests; 501 std::vector<Hwc2::Layer> layerIds; 502 std::vector<uint32_t> layerRequests; 503 auto intError = mDevice.mComposer->getDisplayRequests(mId, 504 &intDisplayRequests, &layerIds, &layerRequests); 505 uint32_t numElements = layerIds.size(); 506 auto error = static_cast<Error>(intError); 507 if (error != Error::None) { 508 return error; 509 } 510 511 *outDisplayRequests = static_cast<DisplayRequest>(intDisplayRequests); 512 outLayerRequests->clear(); 513 outLayerRequests->reserve(numElements); 514 for (uint32_t element = 0; element < numElements; ++element) { 515 auto layer = getLayerById(layerIds[element]); 516 if (layer) { 517 auto layerRequest = 518 static_cast<LayerRequest>(layerRequests[element]); 519 outLayerRequests->emplace(layer, layerRequest); 520 } else { 521 ALOGE("getRequests: invalid layer %" PRIu64 " found on display %" 522 PRIu64, layerIds[element], mId); 523 } 524 } 525 526 return Error::None; 527 } 528 529 Error Display::getType(DisplayType* outType) const 530 { 531 *outType = mType; 532 return Error::None; 533 } 534 535 Error Display::supportsDoze(bool* outSupport) const 536 { 537 bool intSupport = false; 538 auto intError = mDevice.mComposer->getDozeSupport(mId, &intSupport); 539 auto error = static_cast<Error>(intError); 540 if (error != Error::None) { 541 return error; 542 } 543 *outSupport = static_cast<bool>(intSupport); 544 return Error::None; 545 } 546 547 Error Display::getHdrCapabilities( 548 std::unique_ptr<HdrCapabilities>* outCapabilities) const 549 { 550 uint32_t numTypes = 0; 551 float maxLuminance = -1.0f; 552 float maxAverageLuminance = -1.0f; 553 float minLuminance = -1.0f; 554 std::vector<Hwc2::Hdr> intTypes; 555 auto intError = mDevice.mComposer->getHdrCapabilities(mId, &intTypes, 556 &maxLuminance, &maxAverageLuminance, &minLuminance); 557 auto error = static_cast<HWC2::Error>(intError); 558 559 std::vector<int32_t> types; 560 for (auto type : intTypes) { 561 types.push_back(static_cast<int32_t>(type)); 562 } 563 numTypes = types.size(); 564 if (error != Error::None) { 565 return error; 566 } 567 568 *outCapabilities = std::make_unique<HdrCapabilities>(std::move(types), 569 maxLuminance, maxAverageLuminance, minLuminance); 570 return Error::None; 571 } 572 573 Error Display::getReleaseFences( 574 std::unordered_map<std::shared_ptr<Layer>, sp<Fence>>* outFences) const 575 { 576 std::vector<Hwc2::Layer> layerIds; 577 std::vector<int> fenceFds; 578 auto intError = mDevice.mComposer->getReleaseFences(mId, 579 &layerIds, &fenceFds); 580 auto error = static_cast<Error>(intError); 581 uint32_t numElements = layerIds.size(); 582 if (error != Error::None) { 583 return error; 584 } 585 586 std::unordered_map<std::shared_ptr<Layer>, sp<Fence>> releaseFences; 587 releaseFences.reserve(numElements); 588 for (uint32_t element = 0; element < numElements; ++element) { 589 auto layer = getLayerById(layerIds[element]); 590 if (layer) { 591 sp<Fence> fence(new Fence(fenceFds[element])); 592 releaseFences.emplace(std::move(layer), fence); 593 } else { 594 ALOGE("getReleaseFences: invalid layer %" PRIu64 595 " found on display %" PRIu64, layerIds[element], mId); 596 for (; element < numElements; ++element) { 597 close(fenceFds[element]); 598 } 599 return Error::BadLayer; 600 } 601 } 602 603 *outFences = std::move(releaseFences); 604 return Error::None; 605 } 606 607 Error Display::present(sp<Fence>* outPresentFence) 608 { 609 int32_t presentFenceFd = -1; 610 auto intError = mDevice.mComposer->presentDisplay(mId, &presentFenceFd); 611 auto error = static_cast<Error>(intError); 612 if (error != Error::None) { 613 return error; 614 } 615 616 *outPresentFence = new Fence(presentFenceFd); 617 return Error::None; 618 } 619 620 Error Display::setActiveConfig(const std::shared_ptr<const Config>& config) 621 { 622 if (config->getDisplayId() != mId) { 623 ALOGE("setActiveConfig received config %u for the wrong display %" 624 PRIu64 " (expected %" PRIu64 ")", config->getId(), 625 config->getDisplayId(), mId); 626 return Error::BadConfig; 627 } 628 auto intError = mDevice.mComposer->setActiveConfig(mId, config->getId()); 629 return static_cast<Error>(intError); 630 } 631 632 Error Display::setClientTarget(uint32_t slot, const sp<GraphicBuffer>& target, 633 const sp<Fence>& acquireFence, android_dataspace_t dataspace) 634 { 635 // TODO: Properly encode client target surface damage 636 int32_t fenceFd = acquireFence->dup(); 637 auto intError = mDevice.mComposer->setClientTarget(mId, slot, target, 638 fenceFd, static_cast<Hwc2::Dataspace>(dataspace), 639 std::vector<Hwc2::IComposerClient::Rect>()); 640 return static_cast<Error>(intError); 641 } 642 643 Error Display::setColorMode(android_color_mode_t mode) 644 { 645 auto intError = mDevice.mComposer->setColorMode(mId, 646 static_cast<Hwc2::ColorMode>(mode)); 647 return static_cast<Error>(intError); 648 } 649 650 Error Display::setColorTransform(const android::mat4& matrix, 651 android_color_transform_t hint) 652 { 653 auto intError = mDevice.mComposer->setColorTransform(mId, 654 matrix.asArray(), static_cast<Hwc2::ColorTransform>(hint)); 655 return static_cast<Error>(intError); 656 } 657 658 Error Display::setOutputBuffer(const sp<GraphicBuffer>& buffer, 659 const sp<Fence>& releaseFence) 660 { 661 int32_t fenceFd = releaseFence->dup(); 662 auto handle = buffer->getNativeBuffer()->handle; 663 auto intError = mDevice.mComposer->setOutputBuffer(mId, handle, fenceFd); 664 close(fenceFd); 665 return static_cast<Error>(intError); 666 } 667 668 Error Display::setPowerMode(PowerMode mode) 669 { 670 auto intMode = static_cast<Hwc2::IComposerClient::PowerMode>(mode); 671 auto intError = mDevice.mComposer->setPowerMode(mId, intMode); 672 return static_cast<Error>(intError); 673 } 674 675 Error Display::setVsyncEnabled(Vsync enabled) 676 { 677 auto intEnabled = static_cast<Hwc2::IComposerClient::Vsync>(enabled); 678 auto intError = mDevice.mComposer->setVsyncEnabled(mId, intEnabled); 679 return static_cast<Error>(intError); 680 } 681 682 Error Display::validate(uint32_t* outNumTypes, uint32_t* outNumRequests) 683 { 684 uint32_t numTypes = 0; 685 uint32_t numRequests = 0; 686 auto intError = mDevice.mComposer->validateDisplay(mId, 687 &numTypes, &numRequests); 688 auto error = static_cast<Error>(intError); 689 if (error != Error::None && error != Error::HasChanges) { 690 return error; 691 } 692 693 *outNumTypes = numTypes; 694 *outNumRequests = numRequests; 695 return error; 696 } 697 698 Error Display::presentOrValidate(uint32_t* outNumTypes, uint32_t* outNumRequests, 699 sp<android::Fence>* outPresentFence, uint32_t* state) { 700 701 uint32_t numTypes = 0; 702 uint32_t numRequests = 0; 703 int32_t presentFenceFd = -1; 704 auto intError = mDevice.mComposer->presentOrValidateDisplay(mId, &numTypes, &numRequests, &presentFenceFd, state); 705 auto error = static_cast<Error>(intError); 706 if (error != Error::None && error != Error::HasChanges) { 707 return error; 708 } 709 710 if (*state == 1) { 711 *outPresentFence = new Fence(presentFenceFd); 712 } 713 714 if (*state == 0) { 715 *outNumTypes = numTypes; 716 *outNumRequests = numRequests; 717 } 718 return error; 719 } 720 721 void Display::discardCommands() 722 { 723 mDevice.mComposer->resetCommands(); 724 } 725 726 // For use by Device 727 728 int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute) 729 { 730 int32_t value = 0; 731 auto intError = mDevice.mComposer->getDisplayAttribute(mId, configId, 732 static_cast<Hwc2::IComposerClient::Attribute>(attribute), 733 &value); 734 auto error = static_cast<Error>(intError); 735 if (error != Error::None) { 736 ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId, 737 configId, to_string(attribute).c_str(), 738 to_string(error).c_str(), intError); 739 return -1; 740 } 741 return value; 742 } 743 744 void Display::loadConfig(hwc2_config_t configId) 745 { 746 ALOGV("[%" PRIu64 "] loadConfig(%u)", mId, configId); 747 748 auto config = Config::Builder(*this, configId) 749 .setWidth(getAttribute(configId, Attribute::Width)) 750 .setHeight(getAttribute(configId, Attribute::Height)) 751 .setVsyncPeriod(getAttribute(configId, Attribute::VsyncPeriod)) 752 .setDpiX(getAttribute(configId, Attribute::DpiX)) 753 .setDpiY(getAttribute(configId, Attribute::DpiY)) 754 .build(); 755 mConfigs.emplace(configId, std::move(config)); 756 } 757 758 void Display::loadConfigs() 759 { 760 ALOGV("[%" PRIu64 "] loadConfigs", mId); 761 762 std::vector<Hwc2::Config> configIds; 763 auto intError = mDevice.mComposer->getDisplayConfigs(mId, &configIds); 764 auto error = static_cast<Error>(intError); 765 if (error != Error::None) { 766 ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId, 767 to_string(error).c_str(), intError); 768 return; 769 } 770 771 for (auto configId : configIds) { 772 loadConfig(configId); 773 } 774 } 775 776 // For use by Layer 777 778 void Display::destroyLayer(hwc2_layer_t layerId) 779 { 780 auto intError =mDevice.mComposer->destroyLayer(mId, layerId); 781 auto error = static_cast<Error>(intError); 782 ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")" 783 " failed: %s (%d)", mId, layerId, to_string(error).c_str(), 784 intError); 785 mLayers.erase(layerId); 786 } 787 788 // Other Display methods 789 790 std::shared_ptr<Layer> Display::getLayerById(hwc2_layer_t id) const 791 { 792 if (mLayers.count(id) == 0) { 793 return nullptr; 794 } 795 796 auto layer = mLayers.at(id).lock(); 797 return layer; 798 } 799 800 // Layer methods 801 802 Layer::Layer(const std::shared_ptr<Display>& display, hwc2_layer_t id) 803 : mDisplay(display), 804 mDisplayId(display->getId()), 805 mDevice(display->getDevice()), 806 mId(id) 807 { 808 ALOGV("Created layer %" PRIu64 " on display %" PRIu64, id, 809 display->getId()); 810 } 811 812 Layer::~Layer() 813 { 814 auto display = mDisplay.lock(); 815 if (display) { 816 display->destroyLayer(mId); 817 } 818 } 819 820 Error Layer::setCursorPosition(int32_t x, int32_t y) 821 { 822 auto intError = mDevice.mComposer->setCursorPosition(mDisplayId, 823 mId, x, y); 824 return static_cast<Error>(intError); 825 } 826 827 Error Layer::setBuffer(uint32_t slot, const sp<GraphicBuffer>& buffer, 828 const sp<Fence>& acquireFence) 829 { 830 int32_t fenceFd = acquireFence->dup(); 831 auto intError = mDevice.mComposer->setLayerBuffer(mDisplayId, 832 mId, slot, buffer, fenceFd); 833 return static_cast<Error>(intError); 834 } 835 836 Error Layer::setSurfaceDamage(const Region& damage) 837 { 838 // We encode default full-screen damage as INVALID_RECT upstream, but as 0 839 // rects for HWC 840 Hwc2::Error intError = Hwc2::Error::NONE; 841 if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) { 842 intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId, 843 mId, std::vector<Hwc2::IComposerClient::Rect>()); 844 } else { 845 size_t rectCount = 0; 846 auto rectArray = damage.getArray(&rectCount); 847 848 std::vector<Hwc2::IComposerClient::Rect> hwcRects; 849 for (size_t rect = 0; rect < rectCount; ++rect) { 850 hwcRects.push_back({rectArray[rect].left, rectArray[rect].top, 851 rectArray[rect].right, rectArray[rect].bottom}); 852 } 853 854 intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId, 855 mId, hwcRects); 856 } 857 858 return static_cast<Error>(intError); 859 } 860 861 Error Layer::setBlendMode(BlendMode mode) 862 { 863 auto intMode = static_cast<Hwc2::IComposerClient::BlendMode>(mode); 864 auto intError = mDevice.mComposer->setLayerBlendMode(mDisplayId, 865 mId, intMode); 866 return static_cast<Error>(intError); 867 } 868 869 Error Layer::setColor(hwc_color_t color) 870 { 871 Hwc2::IComposerClient::Color hwcColor{color.r, color.g, color.b, color.a}; 872 auto intError = mDevice.mComposer->setLayerColor(mDisplayId, 873 mId, hwcColor); 874 return static_cast<Error>(intError); 875 } 876 877 Error Layer::setCompositionType(Composition type) 878 { 879 auto intType = static_cast<Hwc2::IComposerClient::Composition>(type); 880 auto intError = mDevice.mComposer->setLayerCompositionType(mDisplayId, 881 mId, intType); 882 return static_cast<Error>(intError); 883 } 884 885 Error Layer::setDataspace(android_dataspace_t dataspace) 886 { 887 auto intDataspace = static_cast<Hwc2::Dataspace>(dataspace); 888 auto intError = mDevice.mComposer->setLayerDataspace(mDisplayId, 889 mId, intDataspace); 890 return static_cast<Error>(intError); 891 } 892 893 Error Layer::setDisplayFrame(const Rect& frame) 894 { 895 Hwc2::IComposerClient::Rect hwcRect{frame.left, frame.top, 896 frame.right, frame.bottom}; 897 auto intError = mDevice.mComposer->setLayerDisplayFrame(mDisplayId, 898 mId, hwcRect); 899 return static_cast<Error>(intError); 900 } 901 902 Error Layer::setPlaneAlpha(float alpha) 903 { 904 auto intError = mDevice.mComposer->setLayerPlaneAlpha(mDisplayId, 905 mId, alpha); 906 return static_cast<Error>(intError); 907 } 908 909 Error Layer::setSidebandStream(const native_handle_t* stream) 910 { 911 if (!mDevice.hasCapability(Capability::SidebandStream)) { 912 ALOGE("Attempted to call setSidebandStream without checking that the " 913 "device supports sideband streams"); 914 return Error::Unsupported; 915 } 916 auto intError = mDevice.mComposer->setLayerSidebandStream(mDisplayId, 917 mId, stream); 918 return static_cast<Error>(intError); 919 } 920 921 Error Layer::setSourceCrop(const FloatRect& crop) 922 { 923 Hwc2::IComposerClient::FRect hwcRect{ 924 crop.left, crop.top, crop.right, crop.bottom}; 925 auto intError = mDevice.mComposer->setLayerSourceCrop(mDisplayId, 926 mId, hwcRect); 927 return static_cast<Error>(intError); 928 } 929 930 Error Layer::setTransform(Transform transform) 931 { 932 auto intTransform = static_cast<Hwc2::Transform>(transform); 933 auto intError = mDevice.mComposer->setLayerTransform(mDisplayId, 934 mId, intTransform); 935 return static_cast<Error>(intError); 936 } 937 938 Error Layer::setVisibleRegion(const Region& region) 939 { 940 size_t rectCount = 0; 941 auto rectArray = region.getArray(&rectCount); 942 943 std::vector<Hwc2::IComposerClient::Rect> hwcRects; 944 for (size_t rect = 0; rect < rectCount; ++rect) { 945 hwcRects.push_back({rectArray[rect].left, rectArray[rect].top, 946 rectArray[rect].right, rectArray[rect].bottom}); 947 } 948 949 auto intError = mDevice.mComposer->setLayerVisibleRegion(mDisplayId, 950 mId, hwcRects); 951 return static_cast<Error>(intError); 952 } 953 954 Error Layer::setZOrder(uint32_t z) 955 { 956 auto intError = mDevice.mComposer->setLayerZOrder(mDisplayId, mId, z); 957 return static_cast<Error>(intError); 958 } 959 960 Error Layer::setInfo(uint32_t type, uint32_t appId) 961 { 962 auto intError = mDevice.mComposer->setLayerInfo(mDisplayId, mId, type, appId); 963 return static_cast<Error>(intError); 964 } 965 966 } // namespace HWC2 967