HWC2.cpp revision b7432cc57cd957fb18f68d7976c5829b3a3a7751
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 "FloatRect.h" 27 28#include <ui/Fence.h> 29#include <ui/GraphicBuffer.h> 30#include <ui/Region.h> 31 32#include <android/configuration.h> 33 34#include <algorithm> 35#include <inttypes.h> 36 37extern "C" { 38 static void hotplug_hook(hwc2_callback_data_t callbackData, 39 hwc2_display_t displayId, int32_t intConnected) { 40 auto device = static_cast<HWC2::Device*>(callbackData); 41 auto display = device->getDisplayById(displayId); 42 if (display) { 43 auto connected = static_cast<HWC2::Connection>(intConnected); 44 device->callHotplug(std::move(display), connected); 45 } else { 46 ALOGE("Hotplug callback called with unknown display %" PRIu64, 47 displayId); 48 } 49 } 50 51 static void refresh_hook(hwc2_callback_data_t callbackData, 52 hwc2_display_t displayId) { 53 auto device = static_cast<HWC2::Device*>(callbackData); 54 auto display = device->getDisplayById(displayId); 55 if (display) { 56 device->callRefresh(std::move(display)); 57 } else { 58 ALOGE("Refresh callback called with unknown display %" PRIu64, 59 displayId); 60 } 61 } 62 63 static void vsync_hook(hwc2_callback_data_t callbackData, 64 hwc2_display_t displayId, int64_t timestamp) { 65 auto device = static_cast<HWC2::Device*>(callbackData); 66 auto display = device->getDisplayById(displayId); 67 if (display) { 68 device->callVsync(std::move(display), timestamp); 69 } else { 70 ALOGE("Vsync callback called with unknown display %" PRIu64, 71 displayId); 72 } 73 } 74} 75 76using android::Fence; 77using android::FloatRect; 78using android::GraphicBuffer; 79using android::HdrCapabilities; 80using android::Rect; 81using android::Region; 82using android::sp; 83using android::hardware::Return; 84using android::hardware::Void; 85 86namespace HWC2 { 87 88namespace Hwc2 = android::Hwc2; 89 90// Device methods 91 92#ifdef BYPASS_IHWC 93Device::Device(hwc2_device_t* device) 94 : mHwcDevice(device), 95 mCreateVirtualDisplay(nullptr), 96 mDestroyVirtualDisplay(nullptr), 97 mDump(nullptr), 98 mGetMaxVirtualDisplayCount(nullptr), 99 mRegisterCallback(nullptr), 100 mAcceptDisplayChanges(nullptr), 101 mCreateLayer(nullptr), 102 mDestroyLayer(nullptr), 103 mGetActiveConfig(nullptr), 104 mGetChangedCompositionTypes(nullptr), 105 mGetColorModes(nullptr), 106 mGetDisplayAttribute(nullptr), 107 mGetDisplayConfigs(nullptr), 108 mGetDisplayName(nullptr), 109 mGetDisplayRequests(nullptr), 110 mGetDisplayType(nullptr), 111 mGetDozeSupport(nullptr), 112 mGetHdrCapabilities(nullptr), 113 mGetReleaseFences(nullptr), 114 mPresentDisplay(nullptr), 115 mSetActiveConfig(nullptr), 116 mSetClientTarget(nullptr), 117 mSetColorMode(nullptr), 118 mSetColorTransform(nullptr), 119 mSetOutputBuffer(nullptr), 120 mSetPowerMode(nullptr), 121 mSetVsyncEnabled(nullptr), 122 mValidateDisplay(nullptr), 123 mSetCursorPosition(nullptr), 124 mSetLayerBuffer(nullptr), 125 mSetLayerSurfaceDamage(nullptr), 126 mSetLayerBlendMode(nullptr), 127 mSetLayerColor(nullptr), 128 mSetLayerCompositionType(nullptr), 129 mSetLayerDataspace(nullptr), 130 mSetLayerDisplayFrame(nullptr), 131 mSetLayerPlaneAlpha(nullptr), 132 mSetLayerSidebandStream(nullptr), 133 mSetLayerSourceCrop(nullptr), 134 mSetLayerTransform(nullptr), 135 mSetLayerVisibleRegion(nullptr), 136 mSetLayerZOrder(nullptr), 137#else 138Device::Device() 139 : mComposer(std::make_unique<Hwc2::Composer>()), 140#endif // BYPASS_IHWC 141 mCapabilities(), 142 mDisplays(), 143 mHotplug(), 144 mPendingHotplugs(), 145 mRefresh(), 146 mPendingRefreshes(), 147 mVsync(), 148 mPendingVsyncs() 149{ 150 loadCapabilities(); 151 loadFunctionPointers(); 152 registerCallbacks(); 153} 154 155Device::~Device() 156{ 157#ifdef BYPASS_IHWC 158 if (mHwcDevice == nullptr) { 159 return; 160 } 161#endif 162 163 for (auto element : mDisplays) { 164 auto display = element.second.lock(); 165 if (!display) { 166 ALOGE("~Device: Found a display (%" PRId64 " that has already been" 167 " destroyed", element.first); 168 continue; 169 } 170 171 DisplayType displayType = HWC2::DisplayType::Invalid; 172 auto error = display->getType(&displayType); 173 if (error != Error::None) { 174 ALOGE("~Device: Failed to determine type of display %" PRIu64 175 ": %s (%d)", display->getId(), to_string(error).c_str(), 176 static_cast<int32_t>(error)); 177 continue; 178 } 179 180 if (displayType == HWC2::DisplayType::Physical) { 181 error = display->setVsyncEnabled(HWC2::Vsync::Disable); 182 if (error != Error::None) { 183 ALOGE("~Device: Failed to disable vsync for display %" PRIu64 184 ": %s (%d)", display->getId(), to_string(error).c_str(), 185 static_cast<int32_t>(error)); 186 } 187 } 188 } 189 190#ifdef BYPASS_IHWC 191 hwc2_close(mHwcDevice); 192#endif 193} 194 195// Required by HWC2 device 196 197std::string Device::dump() const 198{ 199#ifdef BYPASS_IHWC 200 uint32_t numBytes = 0; 201 mDump(mHwcDevice, &numBytes, nullptr); 202 203 std::vector<char> buffer(numBytes); 204 mDump(mHwcDevice, &numBytes, buffer.data()); 205 206 return std::string(buffer.data(), buffer.size()); 207#else 208 return mComposer->dumpDebugInfo(); 209#endif 210} 211 212uint32_t Device::getMaxVirtualDisplayCount() const 213{ 214#ifdef BYPASS_IHWC 215 return mGetMaxVirtualDisplayCount(mHwcDevice); 216#else 217 return mComposer->getMaxVirtualDisplayCount(); 218#endif 219} 220 221Error Device::createVirtualDisplay(uint32_t width, uint32_t height, 222 android_pixel_format_t* format, std::shared_ptr<Display>* outDisplay) 223{ 224 ALOGI("Creating virtual display"); 225 226 hwc2_display_t displayId = 0; 227#ifdef BYPASS_IHWC 228 int32_t intFormat = static_cast<int32_t>(*format); 229 int32_t intError = mCreateVirtualDisplay(mHwcDevice, width, height, 230 &intFormat, &displayId); 231#else 232 auto intFormat = static_cast<Hwc2::PixelFormat>(*format); 233 auto intError = mComposer->createVirtualDisplay(width, height, 234 intFormat, displayId); 235#endif 236 auto error = static_cast<Error>(intError); 237 if (error != Error::None) { 238 return error; 239 } 240 241 ALOGI("Created virtual display"); 242 *format = static_cast<android_pixel_format_t>(intFormat); 243 *outDisplay = getDisplayById(displayId); 244 if (!*outDisplay) { 245 ALOGE("Failed to get display by id"); 246 return Error::BadDisplay; 247 } 248 (*outDisplay)->setVirtual(); 249 return Error::None; 250} 251 252void Device::registerHotplugCallback(HotplugCallback hotplug) 253{ 254 ALOGV("registerHotplugCallback"); 255 mHotplug = hotplug; 256 for (auto& pending : mPendingHotplugs) { 257 auto& display = pending.first; 258 auto connected = pending.second; 259 ALOGV("Sending pending hotplug(%" PRIu64 ", %s)", display->getId(), 260 to_string(connected).c_str()); 261 mHotplug(std::move(display), connected); 262 } 263} 264 265void Device::registerRefreshCallback(RefreshCallback refresh) 266{ 267 mRefresh = refresh; 268 for (auto& pending : mPendingRefreshes) { 269 mRefresh(std::move(pending)); 270 } 271} 272 273void Device::registerVsyncCallback(VsyncCallback vsync) 274{ 275 mVsync = vsync; 276 for (auto& pending : mPendingVsyncs) { 277 auto& display = pending.first; 278 auto timestamp = pending.second; 279 mVsync(std::move(display), timestamp); 280 } 281} 282 283// For use by Device callbacks 284 285void Device::callHotplug(std::shared_ptr<Display> display, Connection connected) 286{ 287 if (connected == Connection::Connected) { 288 if (!display->isConnected()) { 289 display->loadConfigs(); 290 display->setConnected(true); 291 } 292 } else { 293 display->setConnected(false); 294 mDisplays.erase(display->getId()); 295 } 296 297 if (mHotplug) { 298 mHotplug(std::move(display), connected); 299 } else { 300 ALOGV("callHotplug called, but no valid callback registered, storing"); 301 mPendingHotplugs.emplace_back(std::move(display), connected); 302 } 303} 304 305void Device::callRefresh(std::shared_ptr<Display> display) 306{ 307 if (mRefresh) { 308 mRefresh(std::move(display)); 309 } else { 310 ALOGV("callRefresh called, but no valid callback registered, storing"); 311 mPendingRefreshes.emplace_back(std::move(display)); 312 } 313} 314 315void Device::callVsync(std::shared_ptr<Display> display, nsecs_t timestamp) 316{ 317 if (mVsync) { 318 mVsync(std::move(display), timestamp); 319 } else { 320 ALOGV("callVsync called, but no valid callback registered, storing"); 321 mPendingVsyncs.emplace_back(std::move(display), timestamp); 322 } 323} 324 325// Other Device methods 326 327std::shared_ptr<Display> Device::getDisplayById(hwc2_display_t id) { 328 if (mDisplays.count(id) != 0) { 329 auto strongDisplay = mDisplays[id].lock(); 330 ALOGE_IF(!strongDisplay, "Display %" PRId64 " is in mDisplays but is no" 331 " longer alive", id); 332 return strongDisplay; 333 } 334 335 auto display = std::make_shared<Display>(*this, id); 336 mDisplays.emplace(id, display); 337 return display; 338} 339 340// Device initialization methods 341 342void Device::loadCapabilities() 343{ 344 static_assert(sizeof(Capability) == sizeof(int32_t), 345 "Capability size has changed"); 346#ifdef BYPASS_IHWC 347 uint32_t numCapabilities = 0; 348 mHwcDevice->getCapabilities(mHwcDevice, &numCapabilities, nullptr); 349 std::vector<Capability> capabilities(numCapabilities); 350 auto asInt = reinterpret_cast<int32_t*>(capabilities.data()); 351 mHwcDevice->getCapabilities(mHwcDevice, &numCapabilities, asInt); 352 for (auto capability : capabilities) { 353 mCapabilities.emplace(capability); 354 } 355#else 356 auto capabilities = mComposer->getCapabilities(); 357 for (auto capability : capabilities) { 358 mCapabilities.emplace(static_cast<Capability>(capability)); 359 } 360#endif 361} 362 363bool Device::hasCapability(HWC2::Capability capability) const 364{ 365 return std::find(mCapabilities.cbegin(), mCapabilities.cend(), 366 capability) != mCapabilities.cend(); 367} 368 369void Device::loadFunctionPointers() 370{ 371#ifdef BYPASS_IHWC 372 // For all of these early returns, we log an error message inside 373 // loadFunctionPointer specifying which function failed to load 374 375 // Display function pointers 376 if (!loadFunctionPointer(FunctionDescriptor::CreateVirtualDisplay, 377 mCreateVirtualDisplay)) return; 378 if (!loadFunctionPointer(FunctionDescriptor::DestroyVirtualDisplay, 379 mDestroyVirtualDisplay)) return; 380 if (!loadFunctionPointer(FunctionDescriptor::Dump, mDump)) return; 381 if (!loadFunctionPointer(FunctionDescriptor::GetMaxVirtualDisplayCount, 382 mGetMaxVirtualDisplayCount)) return; 383 if (!loadFunctionPointer(FunctionDescriptor::RegisterCallback, 384 mRegisterCallback)) return; 385 386 // Device function pointers 387 if (!loadFunctionPointer(FunctionDescriptor::AcceptDisplayChanges, 388 mAcceptDisplayChanges)) return; 389 if (!loadFunctionPointer(FunctionDescriptor::CreateLayer, 390 mCreateLayer)) return; 391 if (!loadFunctionPointer(FunctionDescriptor::DestroyLayer, 392 mDestroyLayer)) return; 393 if (!loadFunctionPointer(FunctionDescriptor::GetActiveConfig, 394 mGetActiveConfig)) return; 395 if (!loadFunctionPointer(FunctionDescriptor::GetChangedCompositionTypes, 396 mGetChangedCompositionTypes)) return; 397 if (!loadFunctionPointer(FunctionDescriptor::GetColorModes, 398 mGetColorModes)) return; 399 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayAttribute, 400 mGetDisplayAttribute)) return; 401 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayConfigs, 402 mGetDisplayConfigs)) return; 403 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayName, 404 mGetDisplayName)) return; 405 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayRequests, 406 mGetDisplayRequests)) return; 407 if (!loadFunctionPointer(FunctionDescriptor::GetDisplayType, 408 mGetDisplayType)) return; 409 if (!loadFunctionPointer(FunctionDescriptor::GetDozeSupport, 410 mGetDozeSupport)) return; 411 if (!loadFunctionPointer(FunctionDescriptor::GetHdrCapabilities, 412 mGetHdrCapabilities)) return; 413 if (!loadFunctionPointer(FunctionDescriptor::GetReleaseFences, 414 mGetReleaseFences)) return; 415 if (!loadFunctionPointer(FunctionDescriptor::PresentDisplay, 416 mPresentDisplay)) return; 417 if (!loadFunctionPointer(FunctionDescriptor::SetActiveConfig, 418 mSetActiveConfig)) return; 419 if (!loadFunctionPointer(FunctionDescriptor::SetClientTarget, 420 mSetClientTarget)) return; 421 if (!loadFunctionPointer(FunctionDescriptor::SetColorMode, 422 mSetColorMode)) return; 423 if (!loadFunctionPointer(FunctionDescriptor::SetColorTransform, 424 mSetColorTransform)) return; 425 if (!loadFunctionPointer(FunctionDescriptor::SetOutputBuffer, 426 mSetOutputBuffer)) return; 427 if (!loadFunctionPointer(FunctionDescriptor::SetPowerMode, 428 mSetPowerMode)) return; 429 if (!loadFunctionPointer(FunctionDescriptor::SetVsyncEnabled, 430 mSetVsyncEnabled)) return; 431 if (!loadFunctionPointer(FunctionDescriptor::ValidateDisplay, 432 mValidateDisplay)) return; 433 434 // Layer function pointers 435 if (!loadFunctionPointer(FunctionDescriptor::SetCursorPosition, 436 mSetCursorPosition)) return; 437 if (!loadFunctionPointer(FunctionDescriptor::SetLayerBuffer, 438 mSetLayerBuffer)) return; 439 if (!loadFunctionPointer(FunctionDescriptor::SetLayerSurfaceDamage, 440 mSetLayerSurfaceDamage)) return; 441 if (!loadFunctionPointer(FunctionDescriptor::SetLayerBlendMode, 442 mSetLayerBlendMode)) return; 443 if (!loadFunctionPointer(FunctionDescriptor::SetLayerColor, 444 mSetLayerColor)) return; 445 if (!loadFunctionPointer(FunctionDescriptor::SetLayerCompositionType, 446 mSetLayerCompositionType)) return; 447 if (!loadFunctionPointer(FunctionDescriptor::SetLayerDataspace, 448 mSetLayerDataspace)) return; 449 if (!loadFunctionPointer(FunctionDescriptor::SetLayerDisplayFrame, 450 mSetLayerDisplayFrame)) return; 451 if (!loadFunctionPointer(FunctionDescriptor::SetLayerPlaneAlpha, 452 mSetLayerPlaneAlpha)) return; 453 if (hasCapability(Capability::SidebandStream)) { 454 if (!loadFunctionPointer(FunctionDescriptor::SetLayerSidebandStream, 455 mSetLayerSidebandStream)) return; 456 } 457 if (!loadFunctionPointer(FunctionDescriptor::SetLayerSourceCrop, 458 mSetLayerSourceCrop)) return; 459 if (!loadFunctionPointer(FunctionDescriptor::SetLayerTransform, 460 mSetLayerTransform)) return; 461 if (!loadFunctionPointer(FunctionDescriptor::SetLayerVisibleRegion, 462 mSetLayerVisibleRegion)) return; 463 if (!loadFunctionPointer(FunctionDescriptor::SetLayerZOrder, 464 mSetLayerZOrder)) return; 465#endif // BYPASS_IHWC 466} 467 468namespace { 469class ComposerCallback : public Hwc2::IComposerCallback { 470public: 471 ComposerCallback(Device* device) : mDevice(device) {} 472 473 Return<void> onHotplug(Hwc2::Display display, 474 Connection connected) override 475 { 476 hotplug_hook(mDevice, display, static_cast<int32_t>(connected)); 477 return Void(); 478 } 479 480 Return<void> onRefresh(Hwc2::Display display) override 481 { 482 refresh_hook(mDevice, display); 483 return Void(); 484 } 485 486 Return<void> onVsync(Hwc2::Display display, int64_t timestamp) override 487 { 488 vsync_hook(mDevice, display, timestamp); 489 return Void(); 490 } 491 492private: 493 Device* mDevice; 494}; 495} // namespace anonymous 496 497void Device::registerCallbacks() 498{ 499#ifdef BYPASS_IHWC 500 registerCallback<HWC2_PFN_HOTPLUG>(Callback::Hotplug, hotplug_hook); 501 registerCallback<HWC2_PFN_REFRESH>(Callback::Refresh, refresh_hook); 502 registerCallback<HWC2_PFN_VSYNC>(Callback::Vsync, vsync_hook); 503#else 504 sp<ComposerCallback> callback = new ComposerCallback(this); 505 mComposer->registerCallback(callback); 506#endif 507} 508 509 510// For use by Display 511 512void Device::destroyVirtualDisplay(hwc2_display_t display) 513{ 514 ALOGI("Destroying virtual display"); 515#ifdef BYPASS_IHWC 516 int32_t intError = mDestroyVirtualDisplay(mHwcDevice, display); 517#else 518 auto intError = mComposer->destroyVirtualDisplay(display); 519#endif 520 auto error = static_cast<Error>(intError); 521 ALOGE_IF(error != Error::None, "destroyVirtualDisplay(%" PRIu64 ") failed:" 522 " %s (%d)", display, to_string(error).c_str(), intError); 523 mDisplays.erase(display); 524} 525 526// Display methods 527 528Display::Display(Device& device, hwc2_display_t id) 529 : mDevice(device), 530 mId(id), 531 mIsConnected(false), 532 mIsVirtual(false) 533{ 534 ALOGV("Created display %" PRIu64, id); 535} 536 537Display::~Display() 538{ 539 ALOGV("Destroyed display %" PRIu64, mId); 540 if (mIsVirtual) { 541 mDevice.destroyVirtualDisplay(mId); 542 } 543} 544 545Display::Config::Config(Display& display, hwc2_config_t id) 546 : mDisplay(display), 547 mId(id), 548 mWidth(-1), 549 mHeight(-1), 550 mVsyncPeriod(-1), 551 mDpiX(-1), 552 mDpiY(-1) {} 553 554Display::Config::Builder::Builder(Display& display, hwc2_config_t id) 555 : mConfig(new Config(display, id)) {} 556 557float Display::Config::Builder::getDefaultDensity() { 558 // Default density is based on TVs: 1080p displays get XHIGH density, lower- 559 // resolution displays get TV density. Maybe eventually we'll need to update 560 // it for 4k displays, though hopefully those will just report accurate DPI 561 // information to begin with. This is also used for virtual displays and 562 // older HWC implementations, so be careful about orientation. 563 564 auto longDimension = std::max(mConfig->mWidth, mConfig->mHeight); 565 if (longDimension >= 1080) { 566 return ACONFIGURATION_DENSITY_XHIGH; 567 } else { 568 return ACONFIGURATION_DENSITY_TV; 569 } 570} 571 572// Required by HWC2 display 573 574Error Display::acceptChanges() 575{ 576#ifdef BYPASS_IHWC 577 int32_t intError = mDevice.mAcceptDisplayChanges(mDevice.mHwcDevice, mId); 578#else 579 auto intError = mDevice.mComposer->acceptDisplayChanges(mId); 580#endif 581 return static_cast<Error>(intError); 582} 583 584Error Display::createLayer(std::shared_ptr<Layer>* outLayer) 585{ 586 hwc2_layer_t layerId = 0; 587#ifdef BYPASS_IHWC 588 int32_t intError = mDevice.mCreateLayer(mDevice.mHwcDevice, mId, &layerId); 589#else 590 auto intError = mDevice.mComposer->createLayer(mId, layerId); 591#endif 592 auto error = static_cast<Error>(intError); 593 if (error != Error::None) { 594 return error; 595 } 596 597 auto layer = std::make_shared<Layer>(shared_from_this(), layerId); 598 mLayers.emplace(layerId, layer); 599 *outLayer = std::move(layer); 600 return Error::None; 601} 602 603Error Display::getActiveConfig( 604 std::shared_ptr<const Display::Config>* outConfig) const 605{ 606 ALOGV("[%" PRIu64 "] getActiveConfig", mId); 607 hwc2_config_t configId = 0; 608#ifdef BYPASS_IHWC 609 int32_t intError = mDevice.mGetActiveConfig(mDevice.mHwcDevice, mId, 610 &configId); 611#else 612 auto intError = mDevice.mComposer->getActiveConfig(mId, configId); 613#endif 614 auto error = static_cast<Error>(intError); 615 616 if (error != Error::None) { 617 ALOGE("Unable to get active config for mId:[%" PRIu64 "]", mId); 618 *outConfig = nullptr; 619 return error; 620 } 621 622 if (mConfigs.count(configId) != 0) { 623 *outConfig = mConfigs.at(configId); 624 } else { 625 ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId, 626 configId); 627 // Return no error, but the caller needs to check for a null pointer to 628 // detect this case 629 *outConfig = nullptr; 630 } 631 632 return Error::None; 633} 634 635Error Display::getChangedCompositionTypes( 636 std::unordered_map<std::shared_ptr<Layer>, Composition>* outTypes) 637{ 638#ifdef BYPASS_IHWC 639 uint32_t numElements = 0; 640 int32_t intError = mDevice.mGetChangedCompositionTypes(mDevice.mHwcDevice, 641 mId, &numElements, nullptr, nullptr); 642 auto error = static_cast<Error>(intError); 643 if (error != Error::None) { 644 return error; 645 } 646 647 std::vector<hwc2_layer_t> layerIds(numElements); 648 std::vector<int32_t> types(numElements); 649 intError = mDevice.mGetChangedCompositionTypes(mDevice.mHwcDevice, mId, 650 &numElements, layerIds.data(), types.data()); 651#else 652 std::vector<Hwc2::Layer> layerIds; 653 std::vector<Hwc2::IComposer::Composition> types; 654 auto intError = mDevice.mComposer->getChangedCompositionTypes(mId, 655 layerIds, types); 656 uint32_t numElements = layerIds.size(); 657 auto error = static_cast<Error>(intError); 658#endif 659 error = static_cast<Error>(intError); 660 if (error != Error::None) { 661 return error; 662 } 663 664 outTypes->clear(); 665 outTypes->reserve(numElements); 666 for (uint32_t element = 0; element < numElements; ++element) { 667 auto layer = getLayerById(layerIds[element]); 668 if (layer) { 669 auto type = static_cast<Composition>(types[element]); 670 ALOGV("getChangedCompositionTypes: adding %" PRIu64 " %s", 671 layer->getId(), to_string(type).c_str()); 672 outTypes->emplace(layer, type); 673 } else { 674 ALOGE("getChangedCompositionTypes: invalid layer %" PRIu64 " found" 675 " on display %" PRIu64, layerIds[element], mId); 676 } 677 } 678 679 return Error::None; 680} 681 682Error Display::getColorModes(std::vector<android_color_mode_t>* outModes) const 683{ 684#ifdef BYPASS_IHWC 685 uint32_t numModes = 0; 686 int32_t intError = mDevice.mGetColorModes(mDevice.mHwcDevice, mId, 687 &numModes, nullptr); 688 auto error = static_cast<Error>(intError); 689 if (error != Error::None) { 690 return error; 691 } 692 693 std::vector<int32_t> modes(numModes); 694 intError = mDevice.mGetColorModes(mDevice.mHwcDevice, mId, &numModes, 695 modes.data()); 696 error = static_cast<Error>(intError); 697#else 698 std::vector<Hwc2::ColorMode> modes; 699 auto intError = mDevice.mComposer->getColorModes(mId, modes); 700 uint32_t numModes = modes.size(); 701 auto error = static_cast<Error>(intError); 702#endif 703 if (error != Error::None) { 704 return error; 705 } 706 707 outModes->resize(numModes); 708 for (size_t i = 0; i < numModes; i++) { 709 (*outModes)[i] = static_cast<android_color_mode_t>(modes[i]); 710 } 711 return Error::None; 712} 713 714std::vector<std::shared_ptr<const Display::Config>> Display::getConfigs() const 715{ 716 std::vector<std::shared_ptr<const Config>> configs; 717 for (const auto& element : mConfigs) { 718 configs.emplace_back(element.second); 719 } 720 return configs; 721} 722 723Error Display::getName(std::string* outName) const 724{ 725#ifdef BYPASS_IHWC 726 uint32_t size; 727 int32_t intError = mDevice.mGetDisplayName(mDevice.mHwcDevice, mId, &size, 728 nullptr); 729 auto error = static_cast<Error>(intError); 730 if (error != Error::None) { 731 return error; 732 } 733 734 std::vector<char> rawName(size); 735 intError = mDevice.mGetDisplayName(mDevice.mHwcDevice, mId, &size, 736 rawName.data()); 737 error = static_cast<Error>(intError); 738 if (error != Error::None) { 739 return error; 740 } 741 742 *outName = std::string(rawName.cbegin(), rawName.cend()); 743 return Error::None; 744#else 745 auto intError = mDevice.mComposer->getDisplayName(mId, *outName); 746 return static_cast<Error>(intError); 747#endif 748} 749 750Error Display::getRequests(HWC2::DisplayRequest* outDisplayRequests, 751 std::unordered_map<std::shared_ptr<Layer>, LayerRequest>* 752 outLayerRequests) 753{ 754#ifdef BYPASS_IHWC 755 int32_t intDisplayRequests = 0; 756 uint32_t numElements = 0; 757 int32_t intError = mDevice.mGetDisplayRequests(mDevice.mHwcDevice, mId, 758 &intDisplayRequests, &numElements, nullptr, nullptr); 759 auto error = static_cast<Error>(intError); 760 if (error != Error::None) { 761 return error; 762 } 763 764 std::vector<hwc2_layer_t> layerIds(numElements); 765 std::vector<int32_t> layerRequests(numElements); 766 intError = mDevice.mGetDisplayRequests(mDevice.mHwcDevice, mId, 767 &intDisplayRequests, &numElements, layerIds.data(), 768 layerRequests.data()); 769 error = static_cast<Error>(intError); 770#else 771 uint32_t intDisplayRequests; 772 std::vector<Hwc2::Layer> layerIds; 773 std::vector<uint32_t> layerRequests; 774 auto intError = mDevice.mComposer->getDisplayRequests(mId, 775 intDisplayRequests, layerIds, layerRequests); 776 uint32_t numElements = layerIds.size(); 777 auto error = static_cast<Error>(intError); 778#endif 779 if (error != Error::None) { 780 return error; 781 } 782 783 *outDisplayRequests = static_cast<DisplayRequest>(intDisplayRequests); 784 outLayerRequests->clear(); 785 outLayerRequests->reserve(numElements); 786 for (uint32_t element = 0; element < numElements; ++element) { 787 auto layer = getLayerById(layerIds[element]); 788 if (layer) { 789 auto layerRequest = 790 static_cast<LayerRequest>(layerRequests[element]); 791 outLayerRequests->emplace(layer, layerRequest); 792 } else { 793 ALOGE("getRequests: invalid layer %" PRIu64 " found on display %" 794 PRIu64, layerIds[element], mId); 795 } 796 } 797 798 return Error::None; 799} 800 801Error Display::getType(DisplayType* outType) const 802{ 803#ifdef BYPASS_IHWC 804 int32_t intType = 0; 805 int32_t intError = mDevice.mGetDisplayType(mDevice.mHwcDevice, mId, 806 &intType); 807#else 808 Hwc2::IComposer::DisplayType intType = 809 Hwc2::IComposer::DisplayType::INVALID; 810 auto intError = mDevice.mComposer->getDisplayType(mId, intType); 811#endif 812 auto error = static_cast<Error>(intError); 813 if (error != Error::None) { 814 return error; 815 } 816 817 *outType = static_cast<DisplayType>(intType); 818 return Error::None; 819} 820 821Error Display::supportsDoze(bool* outSupport) const 822{ 823#ifdef BYPASS_IHWC 824 int32_t intSupport = 0; 825 int32_t intError = mDevice.mGetDozeSupport(mDevice.mHwcDevice, mId, 826 &intSupport); 827#else 828 bool intSupport = false; 829 auto intError = mDevice.mComposer->getDozeSupport(mId, intSupport); 830#endif 831 auto error = static_cast<Error>(intError); 832 if (error != Error::None) { 833 return error; 834 } 835 *outSupport = static_cast<bool>(intSupport); 836 return Error::None; 837} 838 839Error Display::getHdrCapabilities( 840 std::unique_ptr<HdrCapabilities>* outCapabilities) const 841{ 842 uint32_t numTypes = 0; 843 float maxLuminance = -1.0f; 844 float maxAverageLuminance = -1.0f; 845 float minLuminance = -1.0f; 846#ifdef BYPASS_IHWC 847 int32_t intError = mDevice.mGetHdrCapabilities(mDevice.mHwcDevice, mId, 848 &numTypes, nullptr, &maxLuminance, &maxAverageLuminance, 849 &minLuminance); 850 auto error = static_cast<HWC2::Error>(intError); 851 if (error != Error::None) { 852 return error; 853 } 854 855 std::vector<int32_t> types(numTypes); 856 intError = mDevice.mGetHdrCapabilities(mDevice.mHwcDevice, mId, &numTypes, 857 types.data(), &maxLuminance, &maxAverageLuminance, &minLuminance); 858 error = static_cast<HWC2::Error>(intError); 859#else 860 std::vector<Hwc2::Hdr> intTypes; 861 auto intError = mDevice.mComposer->getHdrCapabilities(mId, intTypes, 862 maxLuminance, maxAverageLuminance, minLuminance); 863 auto error = static_cast<HWC2::Error>(intError); 864 865 std::vector<int32_t> types; 866 for (auto type : intTypes) { 867 types.push_back(static_cast<int32_t>(type)); 868 } 869 numTypes = types.size(); 870#endif 871 if (error != Error::None) { 872 return error; 873 } 874 875 *outCapabilities = std::make_unique<HdrCapabilities>(std::move(types), 876 maxLuminance, maxAverageLuminance, minLuminance); 877 return Error::None; 878} 879 880Error Display::getReleaseFences( 881 std::unordered_map<std::shared_ptr<Layer>, sp<Fence>>* outFences) const 882{ 883#ifdef BYPASS_IHWC 884 uint32_t numElements = 0; 885 int32_t intError = mDevice.mGetReleaseFences(mDevice.mHwcDevice, mId, 886 &numElements, nullptr, nullptr); 887 auto error = static_cast<Error>(intError); 888 if (error != Error::None) { 889 return error; 890 } 891 892 std::vector<hwc2_layer_t> layerIds(numElements); 893 std::vector<int32_t> fenceFds(numElements); 894 intError = mDevice.mGetReleaseFences(mDevice.mHwcDevice, mId, &numElements, 895 layerIds.data(), fenceFds.data()); 896 error = static_cast<Error>(intError); 897#else 898 std::vector<Hwc2::Layer> layerIds; 899 std::vector<int> fenceFds; 900 auto intError = mDevice.mComposer->getReleaseFences(mId, 901 layerIds, fenceFds); 902 auto error = static_cast<Error>(intError); 903 uint32_t numElements = layerIds.size(); 904#endif 905 if (error != Error::None) { 906 return error; 907 } 908 909 std::unordered_map<std::shared_ptr<Layer>, sp<Fence>> releaseFences; 910 releaseFences.reserve(numElements); 911 for (uint32_t element = 0; element < numElements; ++element) { 912 auto layer = getLayerById(layerIds[element]); 913 if (layer) { 914 sp<Fence> fence(new Fence(fenceFds[element])); 915 releaseFences.emplace(std::move(layer), fence); 916 } else { 917 ALOGE("getReleaseFences: invalid layer %" PRIu64 918 " found on display %" PRIu64, layerIds[element], mId); 919 return Error::BadLayer; 920 } 921 } 922 923 *outFences = std::move(releaseFences); 924 return Error::None; 925} 926 927Error Display::present(sp<Fence>* outRetireFence) 928{ 929 int32_t retireFenceFd = 0; 930#ifdef BYPASS_IHWC 931 int32_t intError = mDevice.mPresentDisplay(mDevice.mHwcDevice, mId, 932 &retireFenceFd); 933#else 934 auto intError = mDevice.mComposer->presentDisplay(mId, retireFenceFd); 935#endif 936 auto error = static_cast<Error>(intError); 937 if (error != Error::None) { 938 return error; 939 } 940 941 *outRetireFence = new Fence(retireFenceFd); 942 return Error::None; 943} 944 945Error Display::setActiveConfig(const std::shared_ptr<const Config>& config) 946{ 947 if (config->getDisplayId() != mId) { 948 ALOGE("setActiveConfig received config %u for the wrong display %" 949 PRIu64 " (expected %" PRIu64 ")", config->getId(), 950 config->getDisplayId(), mId); 951 return Error::BadConfig; 952 } 953#ifdef BYPASS_IHWC 954 int32_t intError = mDevice.mSetActiveConfig(mDevice.mHwcDevice, mId, 955 config->getId()); 956#else 957 auto intError = mDevice.mComposer->setActiveConfig(mId, config->getId()); 958#endif 959 return static_cast<Error>(intError); 960} 961 962Error Display::setClientTarget(buffer_handle_t target, 963 const sp<Fence>& acquireFence, android_dataspace_t dataspace) 964{ 965 // TODO: Properly encode client target surface damage 966 int32_t fenceFd = acquireFence->dup(); 967#ifdef BYPASS_IHWC 968 int32_t intError = mDevice.mSetClientTarget(mDevice.mHwcDevice, mId, target, 969 fenceFd, static_cast<int32_t>(dataspace), {0, nullptr}); 970#else 971 auto intError = mDevice.mComposer->setClientTarget(mId, target, fenceFd, 972 static_cast<Hwc2::Dataspace>(dataspace), 973 std::vector<Hwc2::IComposer::Rect>()); 974#endif 975 return static_cast<Error>(intError); 976} 977 978Error Display::setColorMode(android_color_mode_t mode) 979{ 980#ifdef BYPASS_IHWC 981 int32_t intError = mDevice.mSetColorMode(mDevice.mHwcDevice, mId, mode); 982#else 983 auto intError = mDevice.mComposer->setColorMode(mId, 984 static_cast<Hwc2::ColorMode>(mode)); 985#endif 986 return static_cast<Error>(intError); 987} 988 989Error Display::setColorTransform(const android::mat4& matrix, 990 android_color_transform_t hint) 991{ 992#ifdef BYPASS_IHWC 993 int32_t intError = mDevice.mSetColorTransform(mDevice.mHwcDevice, mId, 994 matrix.asArray(), static_cast<int32_t>(hint)); 995#else 996 auto intError = mDevice.mComposer->setColorTransform(mId, 997 matrix.asArray(), static_cast<Hwc2::ColorTransform>(hint)); 998#endif 999 return static_cast<Error>(intError); 1000} 1001 1002Error Display::setOutputBuffer(const sp<GraphicBuffer>& buffer, 1003 const sp<Fence>& releaseFence) 1004{ 1005 int32_t fenceFd = releaseFence->dup(); 1006 auto handle = buffer->getNativeBuffer()->handle; 1007#ifdef BYPASS_IHWC 1008 int32_t intError = mDevice.mSetOutputBuffer(mDevice.mHwcDevice, mId, handle, 1009 fenceFd); 1010#else 1011 auto intError = mDevice.mComposer->setOutputBuffer(mId, handle, fenceFd); 1012#endif 1013 close(fenceFd); 1014 return static_cast<Error>(intError); 1015} 1016 1017Error Display::setPowerMode(PowerMode mode) 1018{ 1019#ifdef BYPASS_IHWC 1020 auto intMode = static_cast<int32_t>(mode); 1021 int32_t intError = mDevice.mSetPowerMode(mDevice.mHwcDevice, mId, intMode); 1022#else 1023 auto intMode = static_cast<Hwc2::IComposer::PowerMode>(mode); 1024 auto intError = mDevice.mComposer->setPowerMode(mId, intMode); 1025#endif 1026 return static_cast<Error>(intError); 1027} 1028 1029Error Display::setVsyncEnabled(Vsync enabled) 1030{ 1031#ifdef BYPASS_IHWC 1032 auto intEnabled = static_cast<int32_t>(enabled); 1033 int32_t intError = mDevice.mSetVsyncEnabled(mDevice.mHwcDevice, mId, 1034 intEnabled); 1035#else 1036 auto intEnabled = static_cast<Hwc2::IComposer::Vsync>(enabled); 1037 auto intError = mDevice.mComposer->setVsyncEnabled(mId, intEnabled); 1038#endif 1039 return static_cast<Error>(intError); 1040} 1041 1042Error Display::validate(uint32_t* outNumTypes, uint32_t* outNumRequests) 1043{ 1044 uint32_t numTypes = 0; 1045 uint32_t numRequests = 0; 1046#ifdef BYPASS_IHWC 1047 int32_t intError = mDevice.mValidateDisplay(mDevice.mHwcDevice, mId, 1048 &numTypes, &numRequests); 1049#else 1050 auto intError = mDevice.mComposer->validateDisplay(mId, 1051 numTypes, numRequests); 1052#endif 1053 auto error = static_cast<Error>(intError); 1054 if (error != Error::None && error != Error::HasChanges) { 1055 return error; 1056 } 1057 1058 *outNumTypes = numTypes; 1059 *outNumRequests = numRequests; 1060 return error; 1061} 1062 1063// For use by Device 1064 1065int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute) 1066{ 1067 int32_t value = 0; 1068#ifdef BYPASS_IHWC 1069 int32_t intError = mDevice.mGetDisplayAttribute(mDevice.mHwcDevice, mId, 1070 configId, static_cast<int32_t>(attribute), &value); 1071#else 1072 auto intError = mDevice.mComposer->getDisplayAttribute(mId, 1073 configId, static_cast<Hwc2::IComposer::Attribute>(attribute), 1074 value); 1075#endif 1076 auto error = static_cast<Error>(intError); 1077 if (error != Error::None) { 1078 ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId, 1079 configId, to_string(attribute).c_str(), 1080 to_string(error).c_str(), intError); 1081 return -1; 1082 } 1083 return value; 1084} 1085 1086void Display::loadConfig(hwc2_config_t configId) 1087{ 1088 ALOGV("[%" PRIu64 "] loadConfig(%u)", mId, configId); 1089 1090 auto config = Config::Builder(*this, configId) 1091 .setWidth(getAttribute(configId, Attribute::Width)) 1092 .setHeight(getAttribute(configId, Attribute::Height)) 1093 .setVsyncPeriod(getAttribute(configId, Attribute::VsyncPeriod)) 1094 .setDpiX(getAttribute(configId, Attribute::DpiX)) 1095 .setDpiY(getAttribute(configId, Attribute::DpiY)) 1096 .build(); 1097 mConfigs.emplace(configId, std::move(config)); 1098} 1099 1100void Display::loadConfigs() 1101{ 1102 ALOGV("[%" PRIu64 "] loadConfigs", mId); 1103 1104#ifdef BYPASS_IHWC 1105 uint32_t numConfigs = 0; 1106 int32_t intError = mDevice.mGetDisplayConfigs(mDevice.mHwcDevice, mId, 1107 &numConfigs, nullptr); 1108 auto error = static_cast<Error>(intError); 1109 if (error != Error::None) { 1110 ALOGE("[%" PRIu64 "] getDisplayConfigs [1] failed: %s (%d)", mId, 1111 to_string(error).c_str(), intError); 1112 return; 1113 } 1114 1115 std::vector<hwc2_config_t> configIds(numConfigs); 1116 intError = mDevice.mGetDisplayConfigs(mDevice.mHwcDevice, mId, &numConfigs, 1117 configIds.data()); 1118 error = static_cast<Error>(intError); 1119#else 1120 std::vector<Hwc2::Config> configIds; 1121 auto intError = mDevice.mComposer->getDisplayConfigs(mId, configIds); 1122 auto error = static_cast<Error>(intError); 1123#endif 1124 if (error != Error::None) { 1125 ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId, 1126 to_string(error).c_str(), intError); 1127 return; 1128 } 1129 1130 for (auto configId : configIds) { 1131 loadConfig(configId); 1132 } 1133} 1134 1135// For use by Layer 1136 1137void Display::destroyLayer(hwc2_layer_t layerId) 1138{ 1139#ifdef BYPASS_IHWC 1140 int32_t intError = mDevice.mDestroyLayer(mDevice.mHwcDevice, mId, layerId); 1141#else 1142 auto intError =mDevice.mComposer->destroyLayer(mId, layerId); 1143#endif 1144 auto error = static_cast<Error>(intError); 1145 ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")" 1146 " failed: %s (%d)", mId, layerId, to_string(error).c_str(), 1147 intError); 1148 mLayers.erase(layerId); 1149} 1150 1151// Other Display methods 1152 1153std::shared_ptr<Layer> Display::getLayerById(hwc2_layer_t id) const 1154{ 1155 if (mLayers.count(id) == 0) { 1156 return nullptr; 1157 } 1158 1159 auto layer = mLayers.at(id).lock(); 1160 return layer; 1161} 1162 1163// Layer methods 1164 1165Layer::Layer(const std::shared_ptr<Display>& display, hwc2_layer_t id) 1166 : mDisplay(display), 1167 mDisplayId(display->getId()), 1168 mDevice(display->getDevice()), 1169 mId(id) 1170{ 1171 ALOGV("Created layer %" PRIu64 " on display %" PRIu64, id, 1172 display->getId()); 1173} 1174 1175Layer::~Layer() 1176{ 1177 auto display = mDisplay.lock(); 1178 if (display) { 1179 display->destroyLayer(mId); 1180 } 1181} 1182 1183Error Layer::setCursorPosition(int32_t x, int32_t y) 1184{ 1185#ifdef BYPASS_IHWC 1186 int32_t intError = mDevice.mSetCursorPosition(mDevice.mHwcDevice, 1187 mDisplayId, mId, x, y); 1188#else 1189 auto intError = mDevice.mComposer->setCursorPosition(mDisplayId, 1190 mId, x, y); 1191#endif 1192 return static_cast<Error>(intError); 1193} 1194 1195Error Layer::setBuffer(buffer_handle_t buffer, 1196 const sp<Fence>& acquireFence) 1197{ 1198 int32_t fenceFd = acquireFence->dup(); 1199#ifdef BYPASS_IHWC 1200 int32_t intError = mDevice.mSetLayerBuffer(mDevice.mHwcDevice, mDisplayId, 1201 mId, buffer, fenceFd); 1202#else 1203 auto intError = mDevice.mComposer->setLayerBuffer(mDisplayId, 1204 mId, buffer, fenceFd); 1205#endif 1206 return static_cast<Error>(intError); 1207} 1208 1209Error Layer::setSurfaceDamage(const Region& damage) 1210{ 1211 // We encode default full-screen damage as INVALID_RECT upstream, but as 0 1212 // rects for HWC 1213#ifdef BYPASS_IHWC 1214 int32_t intError = 0; 1215#else 1216 Hwc2::Error intError = Hwc2::Error::NONE; 1217#endif 1218 if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) { 1219#ifdef BYPASS_IHWC 1220 intError = mDevice.mSetLayerSurfaceDamage(mDevice.mHwcDevice, 1221 mDisplayId, mId, {0, nullptr}); 1222#else 1223 intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId, 1224 mId, std::vector<Hwc2::IComposer::Rect>()); 1225#endif 1226 } else { 1227 size_t rectCount = 0; 1228 auto rectArray = damage.getArray(&rectCount); 1229 1230#ifdef BYPASS_IHWC 1231 std::vector<hwc_rect_t> hwcRects; 1232#else 1233 std::vector<Hwc2::IComposer::Rect> hwcRects; 1234#endif 1235 for (size_t rect = 0; rect < rectCount; ++rect) { 1236 hwcRects.push_back({rectArray[rect].left, rectArray[rect].top, 1237 rectArray[rect].right, rectArray[rect].bottom}); 1238 } 1239 1240#ifdef BYPASS_IHWC 1241 hwc_region_t hwcRegion = {}; 1242 hwcRegion.numRects = rectCount; 1243 hwcRegion.rects = hwcRects.data(); 1244 1245 intError = mDevice.mSetLayerSurfaceDamage(mDevice.mHwcDevice, 1246 mDisplayId, mId, hwcRegion); 1247#else 1248 intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId, 1249 mId, hwcRects); 1250#endif 1251 } 1252 1253 return static_cast<Error>(intError); 1254} 1255 1256Error Layer::setBlendMode(BlendMode mode) 1257{ 1258#ifdef BYPASS_IHWC 1259 auto intMode = static_cast<int32_t>(mode); 1260 int32_t intError = mDevice.mSetLayerBlendMode(mDevice.mHwcDevice, 1261 mDisplayId, mId, intMode); 1262#else 1263 auto intMode = static_cast<Hwc2::IComposer::BlendMode>(mode); 1264 auto intError = mDevice.mComposer->setLayerBlendMode(mDisplayId, 1265 mId, intMode); 1266#endif 1267 return static_cast<Error>(intError); 1268} 1269 1270Error Layer::setColor(hwc_color_t color) 1271{ 1272#ifdef BYPASS_IHWC 1273 int32_t intError = mDevice.mSetLayerColor(mDevice.mHwcDevice, mDisplayId, 1274 mId, color); 1275#else 1276 Hwc2::IComposer::Color hwcColor{color.r, color.g, color.b, color.a}; 1277 auto intError = mDevice.mComposer->setLayerColor(mDisplayId, 1278 mId, hwcColor); 1279#endif 1280 return static_cast<Error>(intError); 1281} 1282 1283Error Layer::setCompositionType(Composition type) 1284{ 1285#ifdef BYPASS_IHWC 1286 auto intType = static_cast<int32_t>(type); 1287 int32_t intError = mDevice.mSetLayerCompositionType(mDevice.mHwcDevice, 1288 mDisplayId, mId, intType); 1289#else 1290 auto intType = static_cast<Hwc2::IComposer::Composition>(type); 1291 auto intError = mDevice.mComposer->setLayerCompositionType(mDisplayId, 1292 mId, intType); 1293#endif 1294 return static_cast<Error>(intError); 1295} 1296 1297Error Layer::setDataspace(android_dataspace_t dataspace) 1298{ 1299#ifdef BYPASS_IHWC 1300 auto intDataspace = static_cast<int32_t>(dataspace); 1301 int32_t intError = mDevice.mSetLayerDataspace(mDevice.mHwcDevice, 1302 mDisplayId, mId, intDataspace); 1303#else 1304 auto intDataspace = static_cast<Hwc2::Dataspace>(dataspace); 1305 auto intError = mDevice.mComposer->setLayerDataspace(mDisplayId, 1306 mId, intDataspace); 1307#endif 1308 return static_cast<Error>(intError); 1309} 1310 1311Error Layer::setDisplayFrame(const Rect& frame) 1312{ 1313#ifdef BYPASS_IHWC 1314 hwc_rect_t hwcRect{frame.left, frame.top, frame.right, frame.bottom}; 1315 int32_t intError = mDevice.mSetLayerDisplayFrame(mDevice.mHwcDevice, 1316 mDisplayId, mId, hwcRect); 1317#else 1318 Hwc2::IComposer::Rect hwcRect{frame.left, frame.top, 1319 frame.right, frame.bottom}; 1320 auto intError = mDevice.mComposer->setLayerDisplayFrame(mDisplayId, 1321 mId, hwcRect); 1322#endif 1323 return static_cast<Error>(intError); 1324} 1325 1326Error Layer::setPlaneAlpha(float alpha) 1327{ 1328#ifdef BYPASS_IHWC 1329 int32_t intError = mDevice.mSetLayerPlaneAlpha(mDevice.mHwcDevice, 1330 mDisplayId, mId, alpha); 1331#else 1332 auto intError = mDevice.mComposer->setLayerPlaneAlpha(mDisplayId, 1333 mId, alpha); 1334#endif 1335 return static_cast<Error>(intError); 1336} 1337 1338Error Layer::setSidebandStream(const native_handle_t* stream) 1339{ 1340 if (!mDevice.hasCapability(Capability::SidebandStream)) { 1341 ALOGE("Attempted to call setSidebandStream without checking that the " 1342 "device supports sideband streams"); 1343 return Error::Unsupported; 1344 } 1345#ifdef BYPASS_IHWC 1346 int32_t intError = mDevice.mSetLayerSidebandStream(mDevice.mHwcDevice, 1347 mDisplayId, mId, stream); 1348#else 1349 auto intError = mDevice.mComposer->setLayerSidebandStream(mDisplayId, 1350 mId, stream); 1351#endif 1352 return static_cast<Error>(intError); 1353} 1354 1355Error Layer::setSourceCrop(const FloatRect& crop) 1356{ 1357#ifdef BYPASS_IHWC 1358 hwc_frect_t hwcRect{crop.left, crop.top, crop.right, crop.bottom}; 1359 int32_t intError = mDevice.mSetLayerSourceCrop(mDevice.mHwcDevice, 1360 mDisplayId, mId, hwcRect); 1361#else 1362 Hwc2::IComposer::FRect hwcRect{ 1363 crop.left, crop.top, crop.right, crop.bottom}; 1364 auto intError = mDevice.mComposer->setLayerSourceCrop(mDisplayId, 1365 mId, hwcRect); 1366#endif 1367 return static_cast<Error>(intError); 1368} 1369 1370Error Layer::setTransform(Transform transform) 1371{ 1372#ifdef BYPASS_IHWC 1373 auto intTransform = static_cast<int32_t>(transform); 1374 int32_t intError = mDevice.mSetLayerTransform(mDevice.mHwcDevice, 1375 mDisplayId, mId, intTransform); 1376#else 1377 auto intTransform = static_cast<Hwc2::Transform>(transform); 1378 auto intError = mDevice.mComposer->setLayerTransform(mDisplayId, 1379 mId, intTransform); 1380#endif 1381 return static_cast<Error>(intError); 1382} 1383 1384Error Layer::setVisibleRegion(const Region& region) 1385{ 1386 size_t rectCount = 0; 1387 auto rectArray = region.getArray(&rectCount); 1388 1389#ifdef BYPASS_IHWC 1390 std::vector<hwc_rect_t> hwcRects; 1391#else 1392 std::vector<Hwc2::IComposer::Rect> hwcRects; 1393#endif 1394 for (size_t rect = 0; rect < rectCount; ++rect) { 1395 hwcRects.push_back({rectArray[rect].left, rectArray[rect].top, 1396 rectArray[rect].right, rectArray[rect].bottom}); 1397 } 1398 1399#ifdef BYPASS_IHWC 1400 hwc_region_t hwcRegion = {}; 1401 hwcRegion.numRects = rectCount; 1402 hwcRegion.rects = hwcRects.data(); 1403 1404 int32_t intError = mDevice.mSetLayerVisibleRegion(mDevice.mHwcDevice, 1405 mDisplayId, mId, hwcRegion); 1406#else 1407 auto intError = mDevice.mComposer->setLayerVisibleRegion(mDisplayId, 1408 mId, hwcRects); 1409#endif 1410 return static_cast<Error>(intError); 1411} 1412 1413Error Layer::setZOrder(uint32_t z) 1414{ 1415#ifdef BYPASS_IHWC 1416 int32_t intError = mDevice.mSetLayerZOrder(mDevice.mHwcDevice, mDisplayId, 1417 mId, z); 1418#else 1419 auto intError = mDevice.mComposer->setLayerZOrder(mDisplayId, mId, z); 1420#endif 1421 return static_cast<Error>(intError); 1422} 1423 1424} // namespace HWC2 1425