HWC2.cpp revision 7d7ae7345abfb91be55c4aed6c9be9d09a144e4c
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 25#include "FloatRect.h" 26 27#include <ui/Fence.h> 28#include <ui/GraphicBuffer.h> 29#include <ui/Region.h> 30 31#include <android/configuration.h> 32 33#include <inttypes.h> 34 35extern "C" { 36 static void hotplug_hook(hwc2_callback_data_t callbackData, 37 hwc2_display_t displayId, int32_t intConnected) { 38 auto device = static_cast<HWC2::Device*>(callbackData); 39 auto display = device->getDisplayById(displayId); 40 if (display) { 41 auto connected = static_cast<HWC2::Connection>(intConnected); 42 device->callHotplug(std::move(display), connected); 43 } else { 44 ALOGE("Hotplug callback called with unknown display %" PRIu64, 45 displayId); 46 } 47 } 48 49 static void refresh_hook(hwc2_callback_data_t callbackData, 50 hwc2_display_t displayId) { 51 auto device = static_cast<HWC2::Device*>(callbackData); 52 auto display = device->getDisplayById(displayId); 53 if (display) { 54 device->callRefresh(std::move(display)); 55 } else { 56 ALOGE("Refresh callback called with unknown display %" PRIu64, 57 displayId); 58 } 59 } 60 61 static void vsync_hook(hwc2_callback_data_t callbackData, 62 hwc2_display_t displayId, int64_t timestamp) { 63 auto device = static_cast<HWC2::Device*>(callbackData); 64 auto display = device->getDisplayById(displayId); 65 if (display) { 66 device->callVsync(std::move(display), timestamp); 67 } else { 68 ALOGE("Vsync callback called with unknown display %" PRIu64, 69 displayId); 70 } 71 } 72} 73 74using android::Fence; 75using android::FloatRect; 76using android::GraphicBuffer; 77using android::HdrCapabilities; 78using android::Rect; 79using android::Region; 80using android::sp; 81 82namespace HWC2 { 83 84// Device methods 85 86Device::Device(hwc2_device_t* device) 87 : mHwcDevice(device), 88 mCreateVirtualDisplay(nullptr), 89 mDestroyVirtualDisplay(nullptr), 90 mDump(nullptr), 91 mGetMaxVirtualDisplayCount(nullptr), 92 mRegisterCallback(nullptr), 93 mAcceptDisplayChanges(nullptr), 94 mCreateLayer(nullptr), 95 mDestroyLayer(nullptr), 96 mGetActiveConfig(nullptr), 97 mGetChangedCompositionTypes(nullptr), 98 mGetDisplayAttribute(nullptr), 99 mGetDisplayConfigs(nullptr), 100 mGetDisplayName(nullptr), 101 mGetDisplayRequests(nullptr), 102 mGetDisplayType(nullptr), 103 mGetDozeSupport(nullptr), 104 mGetHdrCapabilities(nullptr), 105 mGetReleaseFences(nullptr), 106 mPresentDisplay(nullptr), 107 mSetActiveConfig(nullptr), 108 mSetClientTarget(nullptr), 109 mSetOutputBuffer(nullptr), 110 mSetPowerMode(nullptr), 111 mSetVsyncEnabled(nullptr), 112 mValidateDisplay(nullptr), 113 mSetCursorPosition(nullptr), 114 mSetLayerBuffer(nullptr), 115 mSetLayerSurfaceDamage(nullptr), 116 mSetLayerBlendMode(nullptr), 117 mSetLayerColor(nullptr), 118 mSetLayerCompositionType(nullptr), 119 mSetLayerDisplayFrame(nullptr), 120 mSetLayerPlaneAlpha(nullptr), 121 mSetLayerSidebandStream(nullptr), 122 mSetLayerSourceCrop(nullptr), 123 mSetLayerTransform(nullptr), 124 mSetLayerVisibleRegion(nullptr), 125 mSetLayerZOrder(nullptr), 126 mCapabilities(), 127 mDisplays(), 128 mHotplug(), 129 mPendingHotplugs(), 130 mRefresh(), 131 mPendingRefreshes(), 132 mVsync(), 133 mPendingVsyncs() 134{ 135 loadCapabilities(); 136 loadFunctionPointers(); 137 registerCallbacks(); 138} 139 140Device::~Device() 141{ 142 if (mHwcDevice == nullptr) { 143 return; 144 } 145 146 for (auto element : mDisplays) { 147 auto display = element.second; 148 149 DisplayType displayType = HWC2::DisplayType::Invalid; 150 auto error = display->getType(&displayType); 151 if (error != Error::None) { 152 ALOGE("~Device: Failed to determine type of display %" PRIu64 153 ": %s (%d)", display->getId(), to_string(error).c_str(), 154 static_cast<int32_t>(error)); 155 continue; 156 } 157 158 if (displayType == HWC2::DisplayType::Physical) { 159 error = display->setVsyncEnabled(HWC2::Vsync::Disable); 160 if (error != Error::None) { 161 ALOGE("~Device: Failed to disable vsync for display %" PRIu64 162 ": %s (%d)", display->getId(), to_string(error).c_str(), 163 static_cast<int32_t>(error)); 164 } 165 } 166 } 167 168 hwc2_close(mHwcDevice); 169} 170 171// Required by HWC2 device 172 173std::string Device::dump() const 174{ 175 uint32_t numBytes = 0; 176 mDump(mHwcDevice, &numBytes, nullptr); 177 178 std::vector<char> buffer(numBytes); 179 mDump(mHwcDevice, &numBytes, buffer.data()); 180 181 return std::string(buffer.data(), buffer.size()); 182} 183 184uint32_t Device::getMaxVirtualDisplayCount() const 185{ 186 return mGetMaxVirtualDisplayCount(mHwcDevice); 187} 188 189Error Device::createVirtualDisplay(uint32_t width, uint32_t height, 190 std::shared_ptr<Display>* outDisplay) 191{ 192 ALOGI("Creating virtual display"); 193 194 hwc2_display_t displayId = 0; 195 int32_t intError = mCreateVirtualDisplay(mHwcDevice, width, height, 196 &displayId); 197 auto error = static_cast<Error>(intError); 198 if (error != Error::None) { 199 return error; 200 } 201 202 ALOGI("Created virtual display"); 203 *outDisplay = getDisplayById(displayId); 204 (*outDisplay)->setVirtual(); 205 return Error::None; 206} 207 208void Device::registerHotplugCallback(HotplugCallback hotplug) 209{ 210 ALOGV("registerHotplugCallback"); 211 mHotplug = hotplug; 212 for (auto& pending : mPendingHotplugs) { 213 auto& display = pending.first; 214 auto connected = pending.second; 215 ALOGV("Sending pending hotplug(%" PRIu64 ", %s)", display->getId(), 216 to_string(connected).c_str()); 217 mHotplug(std::move(display), connected); 218 } 219} 220 221void Device::registerRefreshCallback(RefreshCallback refresh) 222{ 223 mRefresh = refresh; 224 for (auto& pending : mPendingRefreshes) { 225 mRefresh(std::move(pending)); 226 } 227} 228 229void Device::registerVsyncCallback(VsyncCallback vsync) 230{ 231 mVsync = vsync; 232 for (auto& pending : mPendingVsyncs) { 233 auto& display = pending.first; 234 auto timestamp = pending.second; 235 mVsync(std::move(display), timestamp); 236 } 237} 238 239// For use by Device callbacks 240 241void Device::callHotplug(std::shared_ptr<Display> display, Connection connected) 242{ 243 if (connected == Connection::Connected) { 244 if (!display->isConnected()) { 245 display->loadConfigs(); 246 display->setConnected(true); 247 } 248 } else { 249 display->setConnected(false); 250 mDisplays.erase(display->getId()); 251 } 252 253 if (mHotplug) { 254 mHotplug(std::move(display), connected); 255 } else { 256 ALOGV("callHotplug called, but no valid callback registered, storing"); 257 mPendingHotplugs.emplace_back(std::move(display), connected); 258 } 259} 260 261void Device::callRefresh(std::shared_ptr<Display> display) 262{ 263 if (mRefresh) { 264 mRefresh(std::move(display)); 265 } else { 266 ALOGV("callRefresh called, but no valid callback registered, storing"); 267 mPendingRefreshes.emplace_back(std::move(display)); 268 } 269} 270 271void Device::callVsync(std::shared_ptr<Display> display, nsecs_t timestamp) 272{ 273 if (mVsync) { 274 mVsync(std::move(display), timestamp); 275 } else { 276 ALOGV("callVsync called, but no valid callback registered, storing"); 277 mPendingVsyncs.emplace_back(std::move(display), timestamp); 278 } 279} 280 281// Other Device methods 282 283std::shared_ptr<Display> Device::getDisplayById(hwc2_display_t id) { 284 if (mDisplays.count(id) != 0) { 285 return mDisplays.at(id); 286 } 287 288 auto display = std::make_shared<Display>(*this, id); 289 mDisplays.emplace(id, display); 290 return display; 291} 292 293// Device initialization methods 294 295void Device::loadCapabilities() 296{ 297 static_assert(sizeof(Capability) == sizeof(int32_t), 298 "Capability size has changed"); 299 uint32_t numCapabilities = 0; 300 mHwcDevice->getCapabilities(mHwcDevice, &numCapabilities, nullptr); 301 mCapabilities.resize(numCapabilities); 302 auto asInt = reinterpret_cast<int32_t*>(mCapabilities.data()); 303 mHwcDevice->getCapabilities(mHwcDevice, &numCapabilities, asInt); 304} 305 306void Device::loadFunctionPointers() 307{ 308 // For all of these early returns, we log an error message inside 309 // loadFunctionPointer specifying which function failed to load 310 311 // Display function pointers 312 if (!loadFunctionPointer(FunctionDescriptor::CreateVirtualDisplay, 313 mCreateVirtualDisplay)) return; 314 if (!loadFunctionPointer(FunctionDescriptor::DestroyVirtualDisplay, 315 mDestroyVirtualDisplay)) return; 316 if (!loadFunctionPointer(FunctionDescriptor::Dump, mDump)) return; 317 if (!loadFunctionPointer(FunctionDescriptor::GetMaxVirtualDisplayCount, 318 mGetMaxVirtualDisplayCount)) return; 319 if (!loadFunctionPointer(FunctionDescriptor::RegisterCallback, 320 mRegisterCallback)) return; 321 322 // Device function pointers 323 if (!loadFunctionPointer(FunctionDescriptor::AcceptDisplayChanges, 324 mAcceptDisplayChanges)) return; 325 if (!loadFunctionPointer(FunctionDescriptor::CreateLayer, 326 mCreateLayer)) return; 327 if (!loadFunctionPointer(FunctionDescriptor::DestroyLayer, 328 mDestroyLayer)) return; 329 if (!loadFunctionPointer(FunctionDescriptor::GetActiveConfig, 330 mGetActiveConfig)) return; 331 if (!loadFunctionPointer(FunctionDescriptor::GetChangedCompositionTypes, 332 mGetChangedCompositionTypes)) return; 333 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayAttribute, 334 mGetDisplayAttribute)) return; 335 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayConfigs, 336 mGetDisplayConfigs)) return; 337 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayName, 338 mGetDisplayName)) return; 339 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayRequests, 340 mGetDisplayRequests)) return; 341 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayType, 342 mGetDisplayType)) return; 343 if (!loadFunctionPointer(FunctionDescriptor::GetDozeSupport, 344 mGetDozeSupport)) return; 345 if (!loadFunctionPointer(FunctionDescriptor::GetHdrCapabilities, 346 mGetHdrCapabilities)) return; 347 if (!loadFunctionPointer(FunctionDescriptor::GetReleaseFences, 348 mGetReleaseFences)) return; 349 if (!loadFunctionPointer(FunctionDescriptor::PresentDisplay, 350 mPresentDisplay)) return; 351 if (!loadFunctionPointer(FunctionDescriptor::SetActiveConfig, 352 mSetActiveConfig)) return; 353 if (!loadFunctionPointer(FunctionDescriptor::SetClientTarget, 354 mSetClientTarget)) return; 355 if (!loadFunctionPointer(FunctionDescriptor::SetOutputBuffer, 356 mSetOutputBuffer)) return; 357 if (!loadFunctionPointer(FunctionDescriptor::SetPowerMode, 358 mSetPowerMode)) return; 359 if (!loadFunctionPointer(FunctionDescriptor::SetVsyncEnabled, 360 mSetVsyncEnabled)) return; 361 if (!loadFunctionPointer(FunctionDescriptor::ValidateDisplay, 362 mValidateDisplay)) return; 363 364 // Layer function pointers 365 if (!loadFunctionPointer(FunctionDescriptor::SetCursorPosition, 366 mSetCursorPosition)) return; 367 if (!loadFunctionPointer(FunctionDescriptor::SetLayerBuffer, 368 mSetLayerBuffer)) return; 369 if (!loadFunctionPointer(FunctionDescriptor::SetLayerSurfaceDamage, 370 mSetLayerSurfaceDamage)) return; 371 if (!loadFunctionPointer(FunctionDescriptor::SetLayerBlendMode, 372 mSetLayerBlendMode)) return; 373 if (!loadFunctionPointer(FunctionDescriptor::SetLayerColor, 374 mSetLayerColor)) return; 375 if (!loadFunctionPointer(FunctionDescriptor::SetLayerCompositionType, 376 mSetLayerCompositionType)) return; 377 if (!loadFunctionPointer(FunctionDescriptor::SetLayerDisplayFrame, 378 mSetLayerDisplayFrame)) return; 379 if (!loadFunctionPointer(FunctionDescriptor::SetLayerPlaneAlpha, 380 mSetLayerPlaneAlpha)) return; 381 if (!loadFunctionPointer(FunctionDescriptor::SetLayerSidebandStream, 382 mSetLayerSidebandStream)) return; 383 if (!loadFunctionPointer(FunctionDescriptor::SetLayerSourceCrop, 384 mSetLayerSourceCrop)) return; 385 if (!loadFunctionPointer(FunctionDescriptor::SetLayerTransform, 386 mSetLayerTransform)) return; 387 if (!loadFunctionPointer(FunctionDescriptor::SetLayerVisibleRegion, 388 mSetLayerVisibleRegion)) return; 389 if (!loadFunctionPointer(FunctionDescriptor::SetLayerZOrder, 390 mSetLayerZOrder)) return; 391} 392 393void Device::registerCallbacks() 394{ 395 registerCallback<HWC2_PFN_HOTPLUG>(Callback::Hotplug, hotplug_hook); 396 registerCallback<HWC2_PFN_REFRESH>(Callback::Refresh, refresh_hook); 397 registerCallback<HWC2_PFN_VSYNC>(Callback::Vsync, vsync_hook); 398} 399 400 401// For use by Display 402 403void Device::destroyVirtualDisplay(hwc2_display_t display) 404{ 405 ALOGI("Destroying virtual display"); 406 int32_t intError = mDestroyVirtualDisplay(mHwcDevice, display); 407 auto error = static_cast<Error>(intError); 408 ALOGE_IF(error != Error::None, "destroyVirtualDisplay(%" PRIu64 ") failed:" 409 " %s (%d)", display, to_string(error).c_str(), intError); 410} 411 412// Display methods 413 414Display::Display(Device& device, hwc2_display_t id) 415 : mDevice(device), 416 mId(id), 417 mIsConnected(false), 418 mIsVirtual(false) 419{ 420 ALOGV("Created display %" PRIu64, id); 421} 422 423Display::~Display() 424{ 425 ALOGV("Destroyed display %" PRIu64, mId); 426 if (mIsVirtual) { 427 mDevice.destroyVirtualDisplay(mId); 428 } 429} 430 431Display::Config::Config(Display& display, hwc2_config_t id) 432 : mDisplay(display), 433 mId(id), 434 mWidth(-1), 435 mHeight(-1), 436 mVsyncPeriod(-1), 437 mDpiX(-1), 438 mDpiY(-1) {} 439 440Display::Config::Builder::Builder(Display& display, hwc2_config_t id) 441 : mConfig(new Config(display, id)) {} 442 443float Display::Config::Builder::getDefaultDensity() { 444 // Default density is based on TVs: 1080p displays get XHIGH density, lower- 445 // resolution displays get TV density. Maybe eventually we'll need to update 446 // it for 4k displays, though hopefully those will just report accurate DPI 447 // information to begin with. This is also used for virtual displays and 448 // older HWC implementations, so be careful about orientation. 449 450 auto longDimension = std::max(mConfig->mWidth, mConfig->mHeight); 451 if (longDimension >= 1080) { 452 return ACONFIGURATION_DENSITY_XHIGH; 453 } else { 454 return ACONFIGURATION_DENSITY_TV; 455 } 456} 457 458// Required by HWC2 display 459 460Error Display::acceptChanges() 461{ 462 int32_t intError = mDevice.mAcceptDisplayChanges(mDevice.mHwcDevice, mId); 463 return static_cast<Error>(intError); 464} 465 466Error Display::createLayer(std::shared_ptr<Layer>* outLayer) 467{ 468 hwc2_layer_t layerId = 0; 469 int32_t intError = mDevice.mCreateLayer(mDevice.mHwcDevice, mId, &layerId); 470 auto error = static_cast<Error>(intError); 471 if (error != Error::None) { 472 return error; 473 } 474 475 auto layer = std::make_shared<Layer>(shared_from_this(), layerId); 476 mLayers.emplace(layerId, layer); 477 *outLayer = std::move(layer); 478 return Error::None; 479} 480 481Error Display::getActiveConfig( 482 std::shared_ptr<const Display::Config>* outConfig) const 483{ 484 ALOGV("[%" PRIu64 "] getActiveConfig", mId); 485 hwc2_config_t configId = 0; 486 int32_t intError = mDevice.mGetActiveConfig(mDevice.mHwcDevice, mId, 487 &configId); 488 auto error = static_cast<Error>(intError); 489 490 if (error != Error::None) { 491 return error; 492 } 493 494 if (mConfigs.count(configId) != 0) { 495 *outConfig = mConfigs.at(configId); 496 } else { 497 ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId, 498 configId); 499 // Return no error, but the caller needs to check for a null pointer to 500 // detect this case 501 *outConfig = nullptr; 502 } 503 504 return Error::None; 505} 506 507Error Display::getChangedCompositionTypes( 508 std::unordered_map<std::shared_ptr<Layer>, Composition>* outTypes) 509{ 510 uint32_t numElements = 0; 511 int32_t intError = mDevice.mGetChangedCompositionTypes(mDevice.mHwcDevice, 512 mId, &numElements, nullptr, nullptr); 513 auto error = static_cast<Error>(intError); 514 if (error != Error::None) { 515 return error; 516 } 517 518 std::vector<hwc2_layer_t> layerIds(numElements); 519 std::vector<int32_t> types(numElements); 520 intError = mDevice.mGetChangedCompositionTypes(mDevice.mHwcDevice, mId, 521 &numElements, layerIds.data(), types.data()); 522 error = static_cast<Error>(intError); 523 if (error != Error::None) { 524 return error; 525 } 526 527 outTypes->clear(); 528 outTypes->reserve(numElements); 529 for (uint32_t element = 0; element < numElements; ++element) { 530 auto layer = getLayerById(layerIds[element]); 531 if (layer) { 532 auto type = static_cast<Composition>(types[element]); 533 ALOGV("getChangedCompositionTypes: adding %" PRIu64 " %s", 534 layer->getId(), to_string(type).c_str()); 535 outTypes->emplace(layer, type); 536 } else { 537 ALOGE("getChangedCompositionTypes: invalid layer %" PRIu64 " found" 538 " on display %" PRIu64, layerIds[element], mId); 539 } 540 } 541 542 return Error::None; 543} 544 545std::vector<std::shared_ptr<const Display::Config>> Display::getConfigs() const 546{ 547 std::vector<std::shared_ptr<const Config>> configs; 548 for (const auto& element : mConfigs) { 549 configs.emplace_back(element.second); 550 } 551 return configs; 552} 553 554Error Display::getName(std::string* outName) const 555{ 556 uint32_t size; 557 int32_t intError = mDevice.mGetDisplayName(mDevice.mHwcDevice, mId, &size, 558 nullptr); 559 auto error = static_cast<Error>(intError); 560 if (error != Error::None) { 561 return error; 562 } 563 564 std::vector<char> rawName(size); 565 intError = mDevice.mGetDisplayName(mDevice.mHwcDevice, mId, &size, 566 rawName.data()); 567 error = static_cast<Error>(intError); 568 if (error != Error::None) { 569 return error; 570 } 571 572 *outName = std::string(rawName.cbegin(), rawName.cend()); 573 return Error::None; 574} 575 576Error Display::getRequests(HWC2::DisplayRequest* outDisplayRequests, 577 std::unordered_map<std::shared_ptr<Layer>, LayerRequest>* 578 outLayerRequests) 579{ 580 int32_t intDisplayRequests = 0; 581 uint32_t numElements = 0; 582 int32_t intError = mDevice.mGetDisplayRequests(mDevice.mHwcDevice, mId, 583 &intDisplayRequests, &numElements, nullptr, nullptr); 584 auto error = static_cast<Error>(intError); 585 if (error != Error::None) { 586 return error; 587 } 588 589 std::vector<hwc2_layer_t> layerIds(numElements); 590 std::vector<int32_t> layerRequests(numElements); 591 intError = mDevice.mGetDisplayRequests(mDevice.mHwcDevice, mId, 592 &intDisplayRequests, &numElements, layerIds.data(), 593 layerRequests.data()); 594 error = static_cast<Error>(intError); 595 if (error != Error::None) { 596 return error; 597 } 598 599 *outDisplayRequests = static_cast<DisplayRequest>(intDisplayRequests); 600 outLayerRequests->clear(); 601 outLayerRequests->reserve(numElements); 602 for (uint32_t element = 0; element < numElements; ++element) { 603 auto layer = getLayerById(layerIds[element]); 604 if (layer) { 605 auto layerRequest = 606 static_cast<LayerRequest>(layerRequests[element]); 607 outLayerRequests->emplace(layer, layerRequest); 608 } else { 609 ALOGE("getRequests: invalid layer %" PRIu64 " found on display %" 610 PRIu64, layerIds[element], mId); 611 } 612 } 613 614 return Error::None; 615} 616 617Error Display::getType(DisplayType* outType) const 618{ 619 int32_t intType = 0; 620 int32_t intError = mDevice.mGetDisplayType(mDevice.mHwcDevice, mId, 621 &intType); 622 auto error = static_cast<Error>(intError); 623 if (error != Error::None) { 624 return error; 625 } 626 627 *outType = static_cast<DisplayType>(intType); 628 return Error::None; 629} 630 631Error Display::supportsDoze(bool* outSupport) const 632{ 633 int32_t intSupport = 0; 634 int32_t intError = mDevice.mGetDozeSupport(mDevice.mHwcDevice, mId, 635 &intSupport); 636 auto error = static_cast<Error>(intError); 637 if (error != Error::None) { 638 return error; 639 } 640 *outSupport = static_cast<bool>(intSupport); 641 return Error::None; 642} 643 644Error Display::getHdrCapabilities( 645 std::unique_ptr<HdrCapabilities>* outCapabilities) const 646{ 647 uint32_t numTypes = 0; 648 float maxLuminance = -1.0f; 649 float maxAverageLuminance = -1.0f; 650 float minLuminance = -1.0f; 651 int32_t intError = mDevice.mGetHdrCapabilities(mDevice.mHwcDevice, mId, 652 &numTypes, nullptr, &maxLuminance, &maxAverageLuminance, 653 &minLuminance); 654 auto error = static_cast<HWC2::Error>(intError); 655 if (error != Error::None) { 656 return error; 657 } 658 659 std::vector<int32_t> types(numTypes); 660 intError = mDevice.mGetHdrCapabilities(mDevice.mHwcDevice, mId, &numTypes, 661 types.data(), &maxLuminance, &maxAverageLuminance, &minLuminance); 662 error = static_cast<HWC2::Error>(intError); 663 if (error != Error::None) { 664 return error; 665 } 666 667 *outCapabilities = std::make_unique<HdrCapabilities>(std::move(types), 668 maxLuminance, maxAverageLuminance, minLuminance); 669 return Error::None; 670} 671 672Error Display::getReleaseFences( 673 std::unordered_map<std::shared_ptr<Layer>, sp<Fence>>* outFences) const 674{ 675 uint32_t numElements = 0; 676 int32_t intError = mDevice.mGetReleaseFences(mDevice.mHwcDevice, mId, 677 &numElements, nullptr, nullptr); 678 auto error = static_cast<Error>(intError); 679 if (error != Error::None) { 680 return error; 681 } 682 683 std::vector<hwc2_layer_t> layerIds(numElements); 684 std::vector<int32_t> fenceFds(numElements); 685 intError = mDevice.mGetReleaseFences(mDevice.mHwcDevice, mId, &numElements, 686 layerIds.data(), fenceFds.data()); 687 error = static_cast<Error>(intError); 688 if (error != Error::None) { 689 return error; 690 } 691 692 std::unordered_map<std::shared_ptr<Layer>, sp<Fence>> releaseFences; 693 releaseFences.reserve(numElements); 694 for (uint32_t element = 0; element < numElements; ++element) { 695 auto layer = getLayerById(layerIds[element]); 696 if (layer) { 697 sp<Fence> fence(new Fence(fenceFds[element])); 698 releaseFences.emplace(std::move(layer), fence); 699 } else { 700 ALOGE("getReleaseFences: invalid layer %" PRIu64 701 " found on display %" PRIu64, layerIds[element], mId); 702 return Error::BadLayer; 703 } 704 } 705 706 *outFences = std::move(releaseFences); 707 return Error::None; 708} 709 710Error Display::present(sp<Fence>* outRetireFence) 711{ 712 int32_t retireFenceFd = 0; 713 int32_t intError = mDevice.mPresentDisplay(mDevice.mHwcDevice, mId, 714 &retireFenceFd); 715 auto error = static_cast<Error>(intError); 716 if (error != Error::None) { 717 return error; 718 } 719 720 *outRetireFence = new Fence(retireFenceFd); 721 return Error::None; 722} 723 724Error Display::setActiveConfig(const std::shared_ptr<const Config>& config) 725{ 726 if (config->getDisplayId() != mId) { 727 ALOGE("setActiveConfig received config %u for the wrong display %" 728 PRIu64 " (expected %" PRIu64 ")", config->getId(), 729 config->getDisplayId(), mId); 730 return Error::BadConfig; 731 } 732 int32_t intError = mDevice.mSetActiveConfig(mDevice.mHwcDevice, mId, 733 config->getId()); 734 return static_cast<Error>(intError); 735} 736 737Error Display::setClientTarget(buffer_handle_t target, 738 const sp<Fence>& acquireFence, android_dataspace_t dataspace) 739{ 740 int32_t fenceFd = acquireFence->dup(); 741 int32_t intError = mDevice.mSetClientTarget(mDevice.mHwcDevice, mId, target, 742 fenceFd, static_cast<int32_t>(dataspace)); 743 return static_cast<Error>(intError); 744} 745 746Error Display::setOutputBuffer(const sp<GraphicBuffer>& buffer, 747 const sp<Fence>& releaseFence) 748{ 749 int32_t fenceFd = releaseFence->dup(); 750 auto handle = buffer->getNativeBuffer()->handle; 751 int32_t intError = mDevice.mSetOutputBuffer(mDevice.mHwcDevice, mId, handle, 752 fenceFd); 753 return static_cast<Error>(intError); 754} 755 756Error Display::setPowerMode(PowerMode mode) 757{ 758 auto intMode = static_cast<int32_t>(mode); 759 int32_t intError = mDevice.mSetPowerMode(mDevice.mHwcDevice, mId, intMode); 760 return static_cast<Error>(intError); 761} 762 763Error Display::setVsyncEnabled(Vsync enabled) 764{ 765 auto intEnabled = static_cast<int32_t>(enabled); 766 int32_t intError = mDevice.mSetVsyncEnabled(mDevice.mHwcDevice, mId, 767 intEnabled); 768 return static_cast<Error>(intError); 769} 770 771Error Display::validate(uint32_t* outNumTypes, uint32_t* outNumRequests) 772{ 773 uint32_t numTypes = 0; 774 uint32_t numRequests = 0; 775 int32_t intError = mDevice.mValidateDisplay(mDevice.mHwcDevice, mId, 776 &numTypes, &numRequests); 777 auto error = static_cast<Error>(intError); 778 if (error != Error::None && error != Error::HasChanges) { 779 return error; 780 } 781 782 *outNumTypes = numTypes; 783 *outNumRequests = numRequests; 784 return error; 785} 786 787// For use by Device 788 789int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute) 790{ 791 int32_t value = 0; 792 int32_t intError = mDevice.mGetDisplayAttribute(mDevice.mHwcDevice, mId, 793 configId, static_cast<int32_t>(attribute), &value); 794 auto error = static_cast<Error>(intError); 795 if (error != Error::None) { 796 ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId, 797 configId, to_string(attribute).c_str(), 798 to_string(error).c_str(), intError); 799 return -1; 800 } 801 return value; 802} 803 804void Display::loadConfig(hwc2_config_t configId) 805{ 806 ALOGV("[%" PRIu64 "] loadConfig(%u)", mId, configId); 807 808 auto config = Config::Builder(*this, configId) 809 .setWidth(getAttribute(configId, Attribute::Width)) 810 .setHeight(getAttribute(configId, Attribute::Height)) 811 .setVsyncPeriod(getAttribute(configId, Attribute::VsyncPeriod)) 812 .setDpiX(getAttribute(configId, Attribute::DpiX)) 813 .setDpiY(getAttribute(configId, Attribute::DpiY)) 814 .build(); 815 mConfigs.emplace(configId, std::move(config)); 816} 817 818void Display::loadConfigs() 819{ 820 ALOGV("[%" PRIu64 "] loadConfigs", mId); 821 822 uint32_t numConfigs = 0; 823 int32_t intError = mDevice.mGetDisplayConfigs(mDevice.mHwcDevice, mId, 824 &numConfigs, nullptr); 825 auto error = static_cast<Error>(intError); 826 if (error != Error::None) { 827 ALOGE("[%" PRIu64 "] getDisplayConfigs [1] failed: %s (%d)", mId, 828 to_string(error).c_str(), intError); 829 return; 830 } 831 832 std::vector<hwc2_config_t> configIds(numConfigs); 833 intError = mDevice.mGetDisplayConfigs(mDevice.mHwcDevice, mId, &numConfigs, 834 configIds.data()); 835 error = static_cast<Error>(intError); 836 if (error != Error::None) { 837 ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId, 838 to_string(error).c_str(), intError); 839 return; 840 } 841 842 for (auto configId : configIds) { 843 loadConfig(configId); 844 } 845} 846 847// For use by Layer 848 849void Display::destroyLayer(hwc2_layer_t layerId) 850{ 851 int32_t intError = mDevice.mDestroyLayer(mDevice.mHwcDevice, mId, layerId); 852 auto error = static_cast<Error>(intError); 853 ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")" 854 " failed: %s (%d)", mId, layerId, to_string(error).c_str(), 855 intError); 856 mLayers.erase(layerId); 857} 858 859// Other Display methods 860 861std::shared_ptr<Layer> Display::getLayerById(hwc2_layer_t id) const 862{ 863 if (mLayers.count(id) == 0) { 864 return nullptr; 865 } 866 867 auto layer = mLayers.at(id).lock(); 868 return layer; 869} 870 871// Layer methods 872 873Layer::Layer(const std::shared_ptr<Display>& display, hwc2_layer_t id) 874 : mDisplay(display), 875 mDisplayId(display->getId()), 876 mDevice(display->getDevice()), 877 mId(id) 878{ 879 ALOGV("Created layer %" PRIu64 " on display %" PRIu64, id, 880 display->getId()); 881} 882 883Layer::~Layer() 884{ 885 auto display = mDisplay.lock(); 886 if (display) { 887 display->destroyLayer(mId); 888 } 889} 890 891Error Layer::setCursorPosition(int32_t x, int32_t y) 892{ 893 int32_t intError = mDevice.mSetCursorPosition(mDevice.mHwcDevice, 894 mDisplayId, mId, x, y); 895 return static_cast<Error>(intError); 896} 897 898Error Layer::setBuffer(buffer_handle_t buffer, 899 const sp<Fence>& acquireFence) 900{ 901 int32_t fenceFd = acquireFence->dup(); 902 int32_t intError = mDevice.mSetLayerBuffer(mDevice.mHwcDevice, mDisplayId, 903 mId, buffer, fenceFd); 904 return static_cast<Error>(intError); 905} 906 907Error Layer::setSurfaceDamage(const Region& damage) 908{ 909 // We encode default full-screen damage as INVALID_RECT upstream, but as 0 910 // rects for HWC 911 int32_t intError = 0; 912 if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) { 913 intError = mDevice.mSetLayerSurfaceDamage(mDevice.mHwcDevice, 914 mDisplayId, mId, {0, nullptr}); 915 } else { 916 size_t rectCount = 0; 917 auto rectArray = damage.getArray(&rectCount); 918 919 std::vector<hwc_rect_t> hwcRects; 920 for (size_t rect = 0; rect < rectCount; ++rect) { 921 hwcRects.push_back({rectArray[rect].left, rectArray[rect].top, 922 rectArray[rect].right, rectArray[rect].bottom}); 923 } 924 925 hwc_region_t hwcRegion = {}; 926 hwcRegion.numRects = rectCount; 927 hwcRegion.rects = hwcRects.data(); 928 929 intError = mDevice.mSetLayerSurfaceDamage(mDevice.mHwcDevice, 930 mDisplayId, mId, hwcRegion); 931 } 932 933 return static_cast<Error>(intError); 934} 935 936Error Layer::setBlendMode(BlendMode mode) 937{ 938 auto intMode = static_cast<int32_t>(mode); 939 int32_t intError = mDevice.mSetLayerBlendMode(mDevice.mHwcDevice, 940 mDisplayId, mId, intMode); 941 return static_cast<Error>(intError); 942} 943 944Error Layer::setColor(hwc_color_t color) 945{ 946 int32_t intError = mDevice.mSetLayerColor(mDevice.mHwcDevice, mDisplayId, 947 mId, color); 948 return static_cast<Error>(intError); 949} 950 951Error Layer::setCompositionType(Composition type) 952{ 953 auto intType = static_cast<int32_t>(type); 954 int32_t intError = mDevice.mSetLayerCompositionType(mDevice.mHwcDevice, 955 mDisplayId, mId, intType); 956 return static_cast<Error>(intError); 957} 958 959Error Layer::setDisplayFrame(const Rect& frame) 960{ 961 hwc_rect_t hwcRect{frame.left, frame.top, frame.right, frame.bottom}; 962 int32_t intError = mDevice.mSetLayerDisplayFrame(mDevice.mHwcDevice, 963 mDisplayId, mId, hwcRect); 964 return static_cast<Error>(intError); 965} 966 967Error Layer::setPlaneAlpha(float alpha) 968{ 969 int32_t intError = mDevice.mSetLayerPlaneAlpha(mDevice.mHwcDevice, 970 mDisplayId, mId, alpha); 971 return static_cast<Error>(intError); 972} 973 974Error Layer::setSidebandStream(const native_handle_t* stream) 975{ 976 int32_t intError = mDevice.mSetLayerSidebandStream(mDevice.mHwcDevice, 977 mDisplayId, mId, stream); 978 return static_cast<Error>(intError); 979} 980 981Error Layer::setSourceCrop(const FloatRect& crop) 982{ 983 hwc_frect_t hwcRect{crop.left, crop.top, crop.right, crop.bottom}; 984 int32_t intError = mDevice.mSetLayerSourceCrop(mDevice.mHwcDevice, 985 mDisplayId, mId, hwcRect); 986 return static_cast<Error>(intError); 987} 988 989Error Layer::setTransform(Transform transform) 990{ 991 auto intTransform = static_cast<int32_t>(transform); 992 int32_t intError = mDevice.mSetLayerTransform(mDevice.mHwcDevice, 993 mDisplayId, mId, intTransform); 994 return static_cast<Error>(intError); 995} 996 997Error Layer::setVisibleRegion(const Region& region) 998{ 999 size_t rectCount = 0; 1000 auto rectArray = region.getArray(&rectCount); 1001 1002 std::vector<hwc_rect_t> hwcRects; 1003 for (size_t rect = 0; rect < rectCount; ++rect) { 1004 hwcRects.push_back({rectArray[rect].left, rectArray[rect].top, 1005 rectArray[rect].right, rectArray[rect].bottom}); 1006 } 1007 1008 hwc_region_t hwcRegion = {}; 1009 hwcRegion.numRects = rectCount; 1010 hwcRegion.rects = hwcRects.data(); 1011 1012 int32_t intError = mDevice.mSetLayerVisibleRegion(mDevice.mHwcDevice, 1013 mDisplayId, mId, hwcRegion); 1014 return static_cast<Error>(intError); 1015} 1016 1017Error Layer::setZOrder(uint32_t z) 1018{ 1019 int32_t intError = mDevice.mSetLayerZOrder(mDevice.mHwcDevice, mDisplayId, 1020 mId, z); 1021 return static_cast<Error>(intError); 1022} 1023 1024} // namespace HWC2 1025