HWC2.cpp revision 5b3cf0576d91358cb850945d89382938ff8dc5ed
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 36extern "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 75using android::Fence; 76using android::FloatRect; 77using android::GraphicBuffer; 78using android::HdrCapabilities; 79using android::Rect; 80using android::Region; 81using android::sp; 82using android::hardware::Return; 83using android::hardware::Void; 84 85namespace HWC2 { 86 87namespace Hwc2 = android::Hwc2; 88 89// Device methods 90 91Device::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 106Device::~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 138std::string Device::dump() const 139{ 140 return mComposer->dumpDebugInfo(); 141} 142 143uint32_t Device::getMaxVirtualDisplayCount() const 144{ 145 return mComposer->getMaxVirtualDisplayCount(); 146} 147 148Error 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 173void 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 186void Device::registerRefreshCallback(RefreshCallback refresh) 187{ 188 mRefresh = refresh; 189 for (auto& pending : mPendingRefreshes) { 190 mRefresh(std::move(pending)); 191 } 192} 193 194void 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 206void 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 227void 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 237void 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 249std::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 264void 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 274bool Device::hasCapability(HWC2::Capability capability) const 275{ 276 return std::find(mCapabilities.cbegin(), mCapabilities.cend(), 277 capability) != mCapabilities.cend(); 278} 279 280namespace { 281class ComposerCallback : public Hwc2::IComposerCallback { 282public: 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 304private: 305 Device* mDevice; 306}; 307} // namespace anonymous 308 309void Device::registerCallbacks() 310{ 311 sp<ComposerCallback> callback = new ComposerCallback(this); 312 mComposer->registerCallback(callback); 313} 314 315 316// For use by Display 317 318void 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 330Display::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 347Display::~Display() 348{ 349 ALOGV("Destroyed display %" PRIu64, mId); 350 if (mType == DisplayType::Virtual) { 351 mDevice.destroyVirtualDisplay(mId); 352 } 353} 354 355Display::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 364Display::Config::Builder::Builder(Display& display, hwc2_config_t id) 365 : mConfig(new Config(display, id)) {} 366 367float 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 384Error Display::acceptChanges() 385{ 386 auto intError = mDevice.mComposer->acceptDisplayChanges(mId); 387 return static_cast<Error>(intError); 388} 389 390Error 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 405Error 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 432Error 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 464Error 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 481std::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 490Error Display::getName(std::string* outName) const 491{ 492 auto intError = mDevice.mComposer->getDisplayName(mId, outName); 493 return static_cast<Error>(intError); 494} 495 496Error 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 529Error Display::getType(DisplayType* outType) const 530{ 531 *outType = mType; 532 return Error::None; 533} 534 535Error 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 547Error 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 573Error 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 return Error::BadLayer; 597 } 598 } 599 600 *outFences = std::move(releaseFences); 601 return Error::None; 602} 603 604Error Display::present(sp<Fence>* outPresentFence) 605{ 606 int32_t presentFenceFd = -1; 607 auto intError = mDevice.mComposer->presentDisplay(mId, &presentFenceFd); 608 auto error = static_cast<Error>(intError); 609 if (error != Error::None) { 610 return error; 611 } 612 613 *outPresentFence = new Fence(presentFenceFd); 614 return Error::None; 615} 616 617Error Display::setActiveConfig(const std::shared_ptr<const Config>& config) 618{ 619 if (config->getDisplayId() != mId) { 620 ALOGE("setActiveConfig received config %u for the wrong display %" 621 PRIu64 " (expected %" PRIu64 ")", config->getId(), 622 config->getDisplayId(), mId); 623 return Error::BadConfig; 624 } 625 auto intError = mDevice.mComposer->setActiveConfig(mId, config->getId()); 626 return static_cast<Error>(intError); 627} 628 629Error Display::setClientTarget(uint32_t slot, const sp<GraphicBuffer>& target, 630 const sp<Fence>& acquireFence, android_dataspace_t dataspace) 631{ 632 // TODO: Properly encode client target surface damage 633 int32_t fenceFd = acquireFence->dup(); 634 auto intError = mDevice.mComposer->setClientTarget(mId, slot, target, 635 fenceFd, static_cast<Hwc2::Dataspace>(dataspace), 636 std::vector<Hwc2::IComposerClient::Rect>()); 637 return static_cast<Error>(intError); 638} 639 640Error Display::setColorMode(android_color_mode_t mode) 641{ 642 auto intError = mDevice.mComposer->setColorMode(mId, 643 static_cast<Hwc2::ColorMode>(mode)); 644 return static_cast<Error>(intError); 645} 646 647Error Display::setColorTransform(const android::mat4& matrix, 648 android_color_transform_t hint) 649{ 650 auto intError = mDevice.mComposer->setColorTransform(mId, 651 matrix.asArray(), static_cast<Hwc2::ColorTransform>(hint)); 652 return static_cast<Error>(intError); 653} 654 655Error Display::setOutputBuffer(const sp<GraphicBuffer>& buffer, 656 const sp<Fence>& releaseFence) 657{ 658 int32_t fenceFd = releaseFence->dup(); 659 auto handle = buffer->getNativeBuffer()->handle; 660 auto intError = mDevice.mComposer->setOutputBuffer(mId, handle, fenceFd); 661 close(fenceFd); 662 return static_cast<Error>(intError); 663} 664 665Error Display::setPowerMode(PowerMode mode) 666{ 667 auto intMode = static_cast<Hwc2::IComposerClient::PowerMode>(mode); 668 auto intError = mDevice.mComposer->setPowerMode(mId, intMode); 669 return static_cast<Error>(intError); 670} 671 672Error Display::setVsyncEnabled(Vsync enabled) 673{ 674 auto intEnabled = static_cast<Hwc2::IComposerClient::Vsync>(enabled); 675 auto intError = mDevice.mComposer->setVsyncEnabled(mId, intEnabled); 676 return static_cast<Error>(intError); 677} 678 679Error Display::validate(uint32_t* outNumTypes, uint32_t* outNumRequests) 680{ 681 uint32_t numTypes = 0; 682 uint32_t numRequests = 0; 683 auto intError = mDevice.mComposer->validateDisplay(mId, 684 &numTypes, &numRequests); 685 auto error = static_cast<Error>(intError); 686 if (error != Error::None && error != Error::HasChanges) { 687 return error; 688 } 689 690 *outNumTypes = numTypes; 691 *outNumRequests = numRequests; 692 return error; 693} 694 695// For use by Device 696 697int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute) 698{ 699 int32_t value = 0; 700 auto intError = mDevice.mComposer->getDisplayAttribute(mId, configId, 701 static_cast<Hwc2::IComposerClient::Attribute>(attribute), 702 &value); 703 auto error = static_cast<Error>(intError); 704 if (error != Error::None) { 705 ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId, 706 configId, to_string(attribute).c_str(), 707 to_string(error).c_str(), intError); 708 return -1; 709 } 710 return value; 711} 712 713void Display::loadConfig(hwc2_config_t configId) 714{ 715 ALOGV("[%" PRIu64 "] loadConfig(%u)", mId, configId); 716 717 auto config = Config::Builder(*this, configId) 718 .setWidth(getAttribute(configId, Attribute::Width)) 719 .setHeight(getAttribute(configId, Attribute::Height)) 720 .setVsyncPeriod(getAttribute(configId, Attribute::VsyncPeriod)) 721 .setDpiX(getAttribute(configId, Attribute::DpiX)) 722 .setDpiY(getAttribute(configId, Attribute::DpiY)) 723 .build(); 724 mConfigs.emplace(configId, std::move(config)); 725} 726 727void Display::loadConfigs() 728{ 729 ALOGV("[%" PRIu64 "] loadConfigs", mId); 730 731 std::vector<Hwc2::Config> configIds; 732 auto intError = mDevice.mComposer->getDisplayConfigs(mId, &configIds); 733 auto error = static_cast<Error>(intError); 734 if (error != Error::None) { 735 ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId, 736 to_string(error).c_str(), intError); 737 return; 738 } 739 740 for (auto configId : configIds) { 741 loadConfig(configId); 742 } 743} 744 745// For use by Layer 746 747void Display::destroyLayer(hwc2_layer_t layerId) 748{ 749 auto intError =mDevice.mComposer->destroyLayer(mId, layerId); 750 auto error = static_cast<Error>(intError); 751 ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")" 752 " failed: %s (%d)", mId, layerId, to_string(error).c_str(), 753 intError); 754 mLayers.erase(layerId); 755} 756 757// Other Display methods 758 759std::shared_ptr<Layer> Display::getLayerById(hwc2_layer_t id) const 760{ 761 if (mLayers.count(id) == 0) { 762 return nullptr; 763 } 764 765 auto layer = mLayers.at(id).lock(); 766 return layer; 767} 768 769// Layer methods 770 771Layer::Layer(const std::shared_ptr<Display>& display, hwc2_layer_t id) 772 : mDisplay(display), 773 mDisplayId(display->getId()), 774 mDevice(display->getDevice()), 775 mId(id) 776{ 777 ALOGV("Created layer %" PRIu64 " on display %" PRIu64, id, 778 display->getId()); 779} 780 781Layer::~Layer() 782{ 783 auto display = mDisplay.lock(); 784 if (display) { 785 display->destroyLayer(mId); 786 } 787} 788 789Error Layer::setCursorPosition(int32_t x, int32_t y) 790{ 791 auto intError = mDevice.mComposer->setCursorPosition(mDisplayId, 792 mId, x, y); 793 return static_cast<Error>(intError); 794} 795 796Error Layer::setBuffer(uint32_t slot, const sp<GraphicBuffer>& buffer, 797 const sp<Fence>& acquireFence) 798{ 799 int32_t fenceFd = acquireFence->dup(); 800 auto intError = mDevice.mComposer->setLayerBuffer(mDisplayId, 801 mId, slot, buffer, fenceFd); 802 return static_cast<Error>(intError); 803} 804 805Error Layer::setSurfaceDamage(const Region& damage) 806{ 807 // We encode default full-screen damage as INVALID_RECT upstream, but as 0 808 // rects for HWC 809 Hwc2::Error intError = Hwc2::Error::NONE; 810 if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) { 811 intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId, 812 mId, std::vector<Hwc2::IComposerClient::Rect>()); 813 } else { 814 size_t rectCount = 0; 815 auto rectArray = damage.getArray(&rectCount); 816 817 std::vector<Hwc2::IComposerClient::Rect> hwcRects; 818 for (size_t rect = 0; rect < rectCount; ++rect) { 819 hwcRects.push_back({rectArray[rect].left, rectArray[rect].top, 820 rectArray[rect].right, rectArray[rect].bottom}); 821 } 822 823 intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId, 824 mId, hwcRects); 825 } 826 827 return static_cast<Error>(intError); 828} 829 830Error Layer::setBlendMode(BlendMode mode) 831{ 832 auto intMode = static_cast<Hwc2::IComposerClient::BlendMode>(mode); 833 auto intError = mDevice.mComposer->setLayerBlendMode(mDisplayId, 834 mId, intMode); 835 return static_cast<Error>(intError); 836} 837 838Error Layer::setColor(hwc_color_t color) 839{ 840 Hwc2::IComposerClient::Color hwcColor{color.r, color.g, color.b, color.a}; 841 auto intError = mDevice.mComposer->setLayerColor(mDisplayId, 842 mId, hwcColor); 843 return static_cast<Error>(intError); 844} 845 846Error Layer::setCompositionType(Composition type) 847{ 848 auto intType = static_cast<Hwc2::IComposerClient::Composition>(type); 849 auto intError = mDevice.mComposer->setLayerCompositionType(mDisplayId, 850 mId, intType); 851 return static_cast<Error>(intError); 852} 853 854Error Layer::setDataspace(android_dataspace_t dataspace) 855{ 856 auto intDataspace = static_cast<Hwc2::Dataspace>(dataspace); 857 auto intError = mDevice.mComposer->setLayerDataspace(mDisplayId, 858 mId, intDataspace); 859 return static_cast<Error>(intError); 860} 861 862Error Layer::setDisplayFrame(const Rect& frame) 863{ 864 Hwc2::IComposerClient::Rect hwcRect{frame.left, frame.top, 865 frame.right, frame.bottom}; 866 auto intError = mDevice.mComposer->setLayerDisplayFrame(mDisplayId, 867 mId, hwcRect); 868 return static_cast<Error>(intError); 869} 870 871Error Layer::setPlaneAlpha(float alpha) 872{ 873 auto intError = mDevice.mComposer->setLayerPlaneAlpha(mDisplayId, 874 mId, alpha); 875 return static_cast<Error>(intError); 876} 877 878Error Layer::setSidebandStream(const native_handle_t* stream) 879{ 880 if (!mDevice.hasCapability(Capability::SidebandStream)) { 881 ALOGE("Attempted to call setSidebandStream without checking that the " 882 "device supports sideband streams"); 883 return Error::Unsupported; 884 } 885 auto intError = mDevice.mComposer->setLayerSidebandStream(mDisplayId, 886 mId, stream); 887 return static_cast<Error>(intError); 888} 889 890Error Layer::setSourceCrop(const FloatRect& crop) 891{ 892 Hwc2::IComposerClient::FRect hwcRect{ 893 crop.left, crop.top, crop.right, crop.bottom}; 894 auto intError = mDevice.mComposer->setLayerSourceCrop(mDisplayId, 895 mId, hwcRect); 896 return static_cast<Error>(intError); 897} 898 899Error Layer::setTransform(Transform transform) 900{ 901 auto intTransform = static_cast<Hwc2::Transform>(transform); 902 auto intError = mDevice.mComposer->setLayerTransform(mDisplayId, 903 mId, intTransform); 904 return static_cast<Error>(intError); 905} 906 907Error Layer::setVisibleRegion(const Region& region) 908{ 909 size_t rectCount = 0; 910 auto rectArray = region.getArray(&rectCount); 911 912 std::vector<Hwc2::IComposerClient::Rect> hwcRects; 913 for (size_t rect = 0; rect < rectCount; ++rect) { 914 hwcRects.push_back({rectArray[rect].left, rectArray[rect].top, 915 rectArray[rect].right, rectArray[rect].bottom}); 916 } 917 918 auto intError = mDevice.mComposer->setLayerVisibleRegion(mDisplayId, 919 mId, hwcRects); 920 return static_cast<Error>(intError); 921} 922 923Error Layer::setZOrder(uint32_t z) 924{ 925 auto intError = mDevice.mComposer->setLayerZOrder(mDisplayId, mId, z); 926 return static_cast<Error>(intError); 927} 928 929Error Layer::setInfo(uint32_t type, uint32_t appId) 930{ 931 auto intError = mDevice.mComposer->setLayerInfo(mDisplayId, mId, type, appId); 932 return static_cast<Error>(intError); 933} 934 935} // namespace HWC2 936