HWC2.cpp revision d8ac4fd17a71b8b523121186b8a03212cd5122fe
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 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 607Error 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 620Error 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 632Error 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 643Error 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 650Error 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 658Error 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 668Error 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 675Error 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 682Error 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// For use by Device 699 700int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute) 701{ 702 int32_t value = 0; 703 auto intError = mDevice.mComposer->getDisplayAttribute(mId, configId, 704 static_cast<Hwc2::IComposerClient::Attribute>(attribute), 705 &value); 706 auto error = static_cast<Error>(intError); 707 if (error != Error::None) { 708 ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId, 709 configId, to_string(attribute).c_str(), 710 to_string(error).c_str(), intError); 711 return -1; 712 } 713 return value; 714} 715 716void Display::loadConfig(hwc2_config_t configId) 717{ 718 ALOGV("[%" PRIu64 "] loadConfig(%u)", mId, configId); 719 720 auto config = Config::Builder(*this, configId) 721 .setWidth(getAttribute(configId, Attribute::Width)) 722 .setHeight(getAttribute(configId, Attribute::Height)) 723 .setVsyncPeriod(getAttribute(configId, Attribute::VsyncPeriod)) 724 .setDpiX(getAttribute(configId, Attribute::DpiX)) 725 .setDpiY(getAttribute(configId, Attribute::DpiY)) 726 .build(); 727 mConfigs.emplace(configId, std::move(config)); 728} 729 730void Display::loadConfigs() 731{ 732 ALOGV("[%" PRIu64 "] loadConfigs", mId); 733 734 std::vector<Hwc2::Config> configIds; 735 auto intError = mDevice.mComposer->getDisplayConfigs(mId, &configIds); 736 auto error = static_cast<Error>(intError); 737 if (error != Error::None) { 738 ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId, 739 to_string(error).c_str(), intError); 740 return; 741 } 742 743 for (auto configId : configIds) { 744 loadConfig(configId); 745 } 746} 747 748// For use by Layer 749 750void Display::destroyLayer(hwc2_layer_t layerId) 751{ 752 auto intError =mDevice.mComposer->destroyLayer(mId, layerId); 753 auto error = static_cast<Error>(intError); 754 ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")" 755 " failed: %s (%d)", mId, layerId, to_string(error).c_str(), 756 intError); 757 mLayers.erase(layerId); 758} 759 760// Other Display methods 761 762std::shared_ptr<Layer> Display::getLayerById(hwc2_layer_t id) const 763{ 764 if (mLayers.count(id) == 0) { 765 return nullptr; 766 } 767 768 auto layer = mLayers.at(id).lock(); 769 return layer; 770} 771 772// Layer methods 773 774Layer::Layer(const std::shared_ptr<Display>& display, hwc2_layer_t id) 775 : mDisplay(display), 776 mDisplayId(display->getId()), 777 mDevice(display->getDevice()), 778 mId(id) 779{ 780 ALOGV("Created layer %" PRIu64 " on display %" PRIu64, id, 781 display->getId()); 782} 783 784Layer::~Layer() 785{ 786 auto display = mDisplay.lock(); 787 if (display) { 788 display->destroyLayer(mId); 789 } 790} 791 792Error Layer::setCursorPosition(int32_t x, int32_t y) 793{ 794 auto intError = mDevice.mComposer->setCursorPosition(mDisplayId, 795 mId, x, y); 796 return static_cast<Error>(intError); 797} 798 799Error Layer::setBuffer(uint32_t slot, const sp<GraphicBuffer>& buffer, 800 const sp<Fence>& acquireFence) 801{ 802 int32_t fenceFd = acquireFence->dup(); 803 auto intError = mDevice.mComposer->setLayerBuffer(mDisplayId, 804 mId, slot, buffer, fenceFd); 805 return static_cast<Error>(intError); 806} 807 808Error Layer::setSurfaceDamage(const Region& damage) 809{ 810 // We encode default full-screen damage as INVALID_RECT upstream, but as 0 811 // rects for HWC 812 Hwc2::Error intError = Hwc2::Error::NONE; 813 if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) { 814 intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId, 815 mId, std::vector<Hwc2::IComposerClient::Rect>()); 816 } else { 817 size_t rectCount = 0; 818 auto rectArray = damage.getArray(&rectCount); 819 820 std::vector<Hwc2::IComposerClient::Rect> hwcRects; 821 for (size_t rect = 0; rect < rectCount; ++rect) { 822 hwcRects.push_back({rectArray[rect].left, rectArray[rect].top, 823 rectArray[rect].right, rectArray[rect].bottom}); 824 } 825 826 intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId, 827 mId, hwcRects); 828 } 829 830 return static_cast<Error>(intError); 831} 832 833Error Layer::setBlendMode(BlendMode mode) 834{ 835 auto intMode = static_cast<Hwc2::IComposerClient::BlendMode>(mode); 836 auto intError = mDevice.mComposer->setLayerBlendMode(mDisplayId, 837 mId, intMode); 838 return static_cast<Error>(intError); 839} 840 841Error Layer::setColor(hwc_color_t color) 842{ 843 Hwc2::IComposerClient::Color hwcColor{color.r, color.g, color.b, color.a}; 844 auto intError = mDevice.mComposer->setLayerColor(mDisplayId, 845 mId, hwcColor); 846 return static_cast<Error>(intError); 847} 848 849Error Layer::setCompositionType(Composition type) 850{ 851 auto intType = static_cast<Hwc2::IComposerClient::Composition>(type); 852 auto intError = mDevice.mComposer->setLayerCompositionType(mDisplayId, 853 mId, intType); 854 return static_cast<Error>(intError); 855} 856 857Error Layer::setDataspace(android_dataspace_t dataspace) 858{ 859 auto intDataspace = static_cast<Hwc2::Dataspace>(dataspace); 860 auto intError = mDevice.mComposer->setLayerDataspace(mDisplayId, 861 mId, intDataspace); 862 return static_cast<Error>(intError); 863} 864 865Error Layer::setDisplayFrame(const Rect& frame) 866{ 867 Hwc2::IComposerClient::Rect hwcRect{frame.left, frame.top, 868 frame.right, frame.bottom}; 869 auto intError = mDevice.mComposer->setLayerDisplayFrame(mDisplayId, 870 mId, hwcRect); 871 return static_cast<Error>(intError); 872} 873 874Error Layer::setPlaneAlpha(float alpha) 875{ 876 auto intError = mDevice.mComposer->setLayerPlaneAlpha(mDisplayId, 877 mId, alpha); 878 return static_cast<Error>(intError); 879} 880 881Error Layer::setSidebandStream(const native_handle_t* stream) 882{ 883 if (!mDevice.hasCapability(Capability::SidebandStream)) { 884 ALOGE("Attempted to call setSidebandStream without checking that the " 885 "device supports sideband streams"); 886 return Error::Unsupported; 887 } 888 auto intError = mDevice.mComposer->setLayerSidebandStream(mDisplayId, 889 mId, stream); 890 return static_cast<Error>(intError); 891} 892 893Error Layer::setSourceCrop(const FloatRect& crop) 894{ 895 Hwc2::IComposerClient::FRect hwcRect{ 896 crop.left, crop.top, crop.right, crop.bottom}; 897 auto intError = mDevice.mComposer->setLayerSourceCrop(mDisplayId, 898 mId, hwcRect); 899 return static_cast<Error>(intError); 900} 901 902Error Layer::setTransform(Transform transform) 903{ 904 auto intTransform = static_cast<Hwc2::Transform>(transform); 905 auto intError = mDevice.mComposer->setLayerTransform(mDisplayId, 906 mId, intTransform); 907 return static_cast<Error>(intError); 908} 909 910Error Layer::setVisibleRegion(const Region& region) 911{ 912 size_t rectCount = 0; 913 auto rectArray = region.getArray(&rectCount); 914 915 std::vector<Hwc2::IComposerClient::Rect> hwcRects; 916 for (size_t rect = 0; rect < rectCount; ++rect) { 917 hwcRects.push_back({rectArray[rect].left, rectArray[rect].top, 918 rectArray[rect].right, rectArray[rect].bottom}); 919 } 920 921 auto intError = mDevice.mComposer->setLayerVisibleRegion(mDisplayId, 922 mId, hwcRects); 923 return static_cast<Error>(intError); 924} 925 926Error Layer::setZOrder(uint32_t z) 927{ 928 auto intError = mDevice.mComposer->setLayerZOrder(mDisplayId, mId, z); 929 return static_cast<Error>(intError); 930} 931 932Error Layer::setInfo(uint32_t type, uint32_t appId) 933{ 934 auto intError = mDevice.mComposer->setLayerInfo(mDisplayId, mId, type, appId); 935 return static_cast<Error>(intError); 936} 937 938} // namespace HWC2 939