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