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 698Error 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 721void Display::discardCommands() 722{ 723 mDevice.mComposer->resetCommands(); 724} 725 726// For use by Device 727 728int32_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 744void 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 758void 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 778void 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 790std::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 802Layer::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 812Layer::~Layer() 813{ 814 auto display = mDisplay.lock(); 815 if (display) { 816 display->destroyLayer(mId); 817 } 818} 819 820Error 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 827Error 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 836Error 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 861Error 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 869Error 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 877Error 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 885Error 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 893Error 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 902Error Layer::setPlaneAlpha(float alpha) 903{ 904 auto intError = mDevice.mComposer->setLayerPlaneAlpha(mDisplayId, 905 mId, alpha); 906 return static_cast<Error>(intError); 907} 908 909Error 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 921Error 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 930Error 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 938Error 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 954Error Layer::setZOrder(uint32_t z) 955{ 956 auto intError = mDevice.mComposer->setLayerZOrder(mDisplayId, mId, z); 957 return static_cast<Error>(intError); 958} 959 960Error 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