1 /* 2 * Copyright 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 // #define LOG_NDEBUG 0 18 19 #undef LOG_TAG 20 #define LOG_TAG "HWC2" 21 #define ATRACE_TAG ATRACE_TAG_GRAPHICS 22 23 #include "HWC2.h" 24 #include "ComposerHal.h" 25 26 #include <ui/Fence.h> 27 #include <ui/FloatRect.h> 28 #include <ui/GraphicBuffer.h> 29 30 #include <android/configuration.h> 31 32 #include <inttypes.h> 33 #include <algorithm> 34 #include <iterator> 35 #include <set> 36 37 using android::Fence; 38 using android::FloatRect; 39 using android::GraphicBuffer; 40 using android::HdrCapabilities; 41 using android::HdrMetadata; 42 using android::Rect; 43 using android::Region; 44 using android::sp; 45 using android::hardware::Return; 46 using android::hardware::Void; 47 48 namespace HWC2 { 49 50 namespace Hwc2 = android::Hwc2; 51 using android::ui::ColorMode; 52 using android::ui::Dataspace; 53 using android::ui::PixelFormat; 54 using android::ui::RenderIntent; 55 56 namespace { 57 58 inline bool hasMetadataKey(const std::set<Hwc2::PerFrameMetadataKey>& keys, 59 const Hwc2::PerFrameMetadataKey& key) { 60 return keys.find(key) != keys.end(); 61 } 62 63 class ComposerCallbackBridge : public Hwc2::IComposerCallback { 64 public: 65 ComposerCallbackBridge(ComposerCallback* callback, int32_t sequenceId) 66 : mCallback(callback), mSequenceId(sequenceId) {} 67 68 Return<void> onHotplug(Hwc2::Display display, 69 IComposerCallback::Connection conn) override 70 { 71 HWC2::Connection connection = static_cast<HWC2::Connection>(conn); 72 mCallback->onHotplugReceived(mSequenceId, display, connection); 73 return Void(); 74 } 75 76 Return<void> onRefresh(Hwc2::Display display) override 77 { 78 mCallback->onRefreshReceived(mSequenceId, display); 79 return Void(); 80 } 81 82 Return<void> onVsync(Hwc2::Display display, int64_t timestamp) override 83 { 84 mCallback->onVsyncReceived(mSequenceId, display, timestamp); 85 return Void(); 86 } 87 88 private: 89 ComposerCallback* mCallback; 90 int32_t mSequenceId; 91 }; 92 93 } // namespace anonymous 94 95 96 // Device methods 97 98 Device::Device(std::unique_ptr<android::Hwc2::Composer> composer) : mComposer(std::move(composer)) { 99 loadCapabilities(); 100 } 101 102 void Device::registerCallback(ComposerCallback* callback, int32_t sequenceId) { 103 if (mRegisteredCallback) { 104 ALOGW("Callback already registered. Ignored extra registration " 105 "attempt."); 106 return; 107 } 108 mRegisteredCallback = true; 109 sp<ComposerCallbackBridge> callbackBridge( 110 new ComposerCallbackBridge(callback, sequenceId)); 111 mComposer->registerCallback(callbackBridge); 112 } 113 114 // Required by HWC2 device 115 116 std::string Device::dump() const 117 { 118 return mComposer->dumpDebugInfo(); 119 } 120 121 uint32_t Device::getMaxVirtualDisplayCount() const 122 { 123 return mComposer->getMaxVirtualDisplayCount(); 124 } 125 126 Error Device::getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort, 127 std::vector<uint8_t>* outData) const { 128 auto intError = mComposer->getDisplayIdentificationData(hwcDisplayId, outPort, outData); 129 return static_cast<Error>(intError); 130 } 131 132 Error Device::createVirtualDisplay(uint32_t width, uint32_t height, 133 PixelFormat* format, Display** outDisplay) 134 { 135 ALOGI("Creating virtual display"); 136 137 hwc2_display_t displayId = 0; 138 auto intError = mComposer->createVirtualDisplay(width, height, 139 format, &displayId); 140 auto error = static_cast<Error>(intError); 141 if (error != Error::None) { 142 return error; 143 } 144 145 auto display = std::make_unique<impl::Display>(*mComposer.get(), mCapabilities, displayId, 146 DisplayType::Virtual); 147 display->setConnected(true); 148 *outDisplay = display.get(); 149 mDisplays.emplace(displayId, std::move(display)); 150 ALOGI("Created virtual display"); 151 return Error::None; 152 } 153 154 void Device::destroyDisplay(hwc2_display_t displayId) 155 { 156 ALOGI("Destroying display %" PRIu64, displayId); 157 mDisplays.erase(displayId); 158 } 159 160 void Device::onHotplug(hwc2_display_t displayId, Connection connection) { 161 if (connection == Connection::Connected) { 162 // If we get a hotplug connected event for a display we already have, 163 // destroy the display and recreate it. This will force us to requery 164 // the display params and recreate all layers on that display. 165 auto oldDisplay = getDisplayById(displayId); 166 if (oldDisplay != nullptr && oldDisplay->isConnected()) { 167 ALOGI("Hotplug connecting an already connected display." 168 " Clearing old display state."); 169 } 170 mDisplays.erase(displayId); 171 172 DisplayType displayType; 173 auto intError = mComposer->getDisplayType(displayId, 174 reinterpret_cast<Hwc2::IComposerClient::DisplayType *>( 175 &displayType)); 176 auto error = static_cast<Error>(intError); 177 if (error != Error::None) { 178 ALOGE("getDisplayType(%" PRIu64 ") failed: %s (%d). " 179 "Aborting hotplug attempt.", 180 displayId, to_string(error).c_str(), intError); 181 return; 182 } 183 184 auto newDisplay = std::make_unique<impl::Display>(*mComposer.get(), mCapabilities, 185 displayId, displayType); 186 newDisplay->setConnected(true); 187 mDisplays.emplace(displayId, std::move(newDisplay)); 188 } else if (connection == Connection::Disconnected) { 189 // The display will later be destroyed by a call to 190 // destroyDisplay(). For now we just mark it disconnected. 191 auto display = getDisplayById(displayId); 192 if (display) { 193 display->setConnected(false); 194 } else { 195 ALOGW("Attempted to disconnect unknown display %" PRIu64, 196 displayId); 197 } 198 } 199 } 200 201 // Other Device methods 202 203 Display* Device::getDisplayById(hwc2_display_t id) { 204 auto iter = mDisplays.find(id); 205 return iter == mDisplays.end() ? nullptr : iter->second.get(); 206 } 207 208 // Device initialization methods 209 210 void Device::loadCapabilities() 211 { 212 static_assert(sizeof(Capability) == sizeof(int32_t), 213 "Capability size has changed"); 214 auto capabilities = mComposer->getCapabilities(); 215 for (auto capability : capabilities) { 216 mCapabilities.emplace(static_cast<Capability>(capability)); 217 } 218 } 219 220 Error Device::flushCommands() 221 { 222 return static_cast<Error>(mComposer->executeCommands()); 223 } 224 225 // Display methods 226 Display::~Display() = default; 227 228 Display::Config::Config(Display& display, hwc2_config_t id) 229 : mDisplay(display), 230 mId(id), 231 mWidth(-1), 232 mHeight(-1), 233 mVsyncPeriod(-1), 234 mDpiX(-1), 235 mDpiY(-1) {} 236 237 Display::Config::Builder::Builder(Display& display, hwc2_config_t id) 238 : mConfig(new Config(display, id)) {} 239 240 float Display::Config::Builder::getDefaultDensity() { 241 // Default density is based on TVs: 1080p displays get XHIGH density, lower- 242 // resolution displays get TV density. Maybe eventually we'll need to update 243 // it for 4k displays, though hopefully those will just report accurate DPI 244 // information to begin with. This is also used for virtual displays and 245 // older HWC implementations, so be careful about orientation. 246 247 auto longDimension = std::max(mConfig->mWidth, mConfig->mHeight); 248 if (longDimension >= 1080) { 249 return ACONFIGURATION_DENSITY_XHIGH; 250 } else { 251 return ACONFIGURATION_DENSITY_TV; 252 } 253 } 254 255 namespace impl { 256 Display::Display(android::Hwc2::Composer& composer, 257 const std::unordered_set<Capability>& capabilities, hwc2_display_t id, 258 DisplayType type) 259 : mComposer(composer), 260 mCapabilities(capabilities), 261 mId(id), 262 mIsConnected(false), 263 mType(type) { 264 ALOGV("Created display %" PRIu64, id); 265 } 266 267 Display::~Display() { 268 mLayers.clear(); 269 270 if (mType == DisplayType::Virtual) { 271 ALOGV("Destroying virtual display"); 272 auto intError = mComposer.destroyVirtualDisplay(mId); 273 auto error = static_cast<Error>(intError); 274 ALOGE_IF(error != Error::None, "destroyVirtualDisplay(%" PRIu64 275 ") failed: %s (%d)", mId, to_string(error).c_str(), intError); 276 } else if (mType == DisplayType::Physical) { 277 auto error = setVsyncEnabled(HWC2::Vsync::Disable); 278 if (error != Error::None) { 279 ALOGE("~Display: Failed to disable vsync for display %" PRIu64 280 ": %s (%d)", mId, to_string(error).c_str(), 281 static_cast<int32_t>(error)); 282 } 283 } 284 } 285 286 // Required by HWC2 display 287 Error Display::acceptChanges() 288 { 289 auto intError = mComposer.acceptDisplayChanges(mId); 290 return static_cast<Error>(intError); 291 } 292 293 Error Display::createLayer(HWC2::Layer** outLayer) { 294 if (!outLayer) { 295 return Error::BadParameter; 296 } 297 hwc2_layer_t layerId = 0; 298 auto intError = mComposer.createLayer(mId, &layerId); 299 auto error = static_cast<Error>(intError); 300 if (error != Error::None) { 301 return error; 302 } 303 304 auto layer = std::make_unique<impl::Layer>(mComposer, mCapabilities, mId, layerId); 305 *outLayer = layer.get(); 306 mLayers.emplace(layerId, std::move(layer)); 307 return Error::None; 308 } 309 310 Error Display::destroyLayer(HWC2::Layer* layer) { 311 if (!layer) { 312 return Error::BadParameter; 313 } 314 mLayers.erase(layer->getId()); 315 return Error::None; 316 } 317 318 Error Display::getActiveConfig( 319 std::shared_ptr<const Display::Config>* outConfig) const 320 { 321 ALOGV("[%" PRIu64 "] getActiveConfig", mId); 322 hwc2_config_t configId = 0; 323 auto intError = mComposer.getActiveConfig(mId, &configId); 324 auto error = static_cast<Error>(intError); 325 326 if (error != Error::None) { 327 ALOGE("Unable to get active config for mId:[%" PRIu64 "]", mId); 328 *outConfig = nullptr; 329 return error; 330 } 331 332 if (mConfigs.count(configId) != 0) { 333 *outConfig = mConfigs.at(configId); 334 } else { 335 ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId, 336 configId); 337 // Return no error, but the caller needs to check for a null pointer to 338 // detect this case 339 *outConfig = nullptr; 340 } 341 342 return Error::None; 343 } 344 345 Error Display::getActiveConfigIndex(int* outIndex) const { 346 ALOGV("[%" PRIu64 "] getActiveConfigIndex", mId); 347 hwc2_config_t configId = 0; 348 auto intError = mComposer.getActiveConfig(mId, &configId); 349 auto error = static_cast<Error>(intError); 350 351 if (error != Error::None) { 352 ALOGE("Unable to get active config for mId:[%" PRIu64 "]", mId); 353 *outIndex = -1; 354 return error; 355 } 356 357 auto pos = mConfigs.find(configId); 358 if (pos != mConfigs.end()) { 359 *outIndex = std::distance(mConfigs.begin(), pos); 360 } else { 361 ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId, configId); 362 // Return no error, but the caller needs to check for a negative index 363 // to detect this case 364 *outIndex = -1; 365 } 366 367 return Error::None; 368 } 369 370 Error Display::getChangedCompositionTypes(std::unordered_map<HWC2::Layer*, Composition>* outTypes) { 371 std::vector<Hwc2::Layer> layerIds; 372 std::vector<Hwc2::IComposerClient::Composition> types; 373 auto intError = mComposer.getChangedCompositionTypes( 374 mId, &layerIds, &types); 375 uint32_t numElements = layerIds.size(); 376 auto error = static_cast<Error>(intError); 377 error = static_cast<Error>(intError); 378 if (error != Error::None) { 379 return error; 380 } 381 382 outTypes->clear(); 383 outTypes->reserve(numElements); 384 for (uint32_t element = 0; element < numElements; ++element) { 385 auto layer = getLayerById(layerIds[element]); 386 if (layer) { 387 auto type = static_cast<Composition>(types[element]); 388 ALOGV("getChangedCompositionTypes: adding %" PRIu64 " %s", 389 layer->getId(), to_string(type).c_str()); 390 outTypes->emplace(layer, type); 391 } else { 392 ALOGE("getChangedCompositionTypes: invalid layer %" PRIu64 " found" 393 " on display %" PRIu64, layerIds[element], mId); 394 } 395 } 396 397 return Error::None; 398 } 399 400 Error Display::getColorModes(std::vector<ColorMode>* outModes) const 401 { 402 auto intError = mComposer.getColorModes(mId, outModes); 403 return static_cast<Error>(intError); 404 } 405 406 int32_t Display::getSupportedPerFrameMetadata() const 407 { 408 int32_t supportedPerFrameMetadata = 0; 409 410 std::vector<Hwc2::PerFrameMetadataKey> tmpKeys = mComposer.getPerFrameMetadataKeys(mId); 411 std::set<Hwc2::PerFrameMetadataKey> keys(tmpKeys.begin(), tmpKeys.end()); 412 413 // Check whether a specific metadata type is supported. A metadata type is considered 414 // supported if and only if all required fields are supported. 415 416 // SMPTE2086 417 if (hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X) && 418 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y) && 419 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X) && 420 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y) && 421 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X) && 422 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y) && 423 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::WHITE_POINT_X) && 424 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::WHITE_POINT_Y) && 425 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MAX_LUMINANCE) && 426 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MIN_LUMINANCE)) { 427 supportedPerFrameMetadata |= HdrMetadata::Type::SMPTE2086; 428 } 429 // CTA861_3 430 if (hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL) && 431 hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL)) { 432 supportedPerFrameMetadata |= HdrMetadata::Type::CTA861_3; 433 } 434 435 // HDR10PLUS 436 if (hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::HDR10_PLUS_SEI)) { 437 supportedPerFrameMetadata |= HdrMetadata::Type::HDR10PLUS; 438 } 439 440 return supportedPerFrameMetadata; 441 } 442 443 Error Display::getRenderIntents(ColorMode colorMode, 444 std::vector<RenderIntent>* outRenderIntents) const 445 { 446 auto intError = mComposer.getRenderIntents(mId, colorMode, outRenderIntents); 447 return static_cast<Error>(intError); 448 } 449 450 Error Display::getDataspaceSaturationMatrix(Dataspace dataspace, android::mat4* outMatrix) 451 { 452 auto intError = mComposer.getDataspaceSaturationMatrix(dataspace, outMatrix); 453 return static_cast<Error>(intError); 454 } 455 456 std::vector<std::shared_ptr<const Display::Config>> Display::getConfigs() const 457 { 458 std::vector<std::shared_ptr<const Config>> configs; 459 for (const auto& element : mConfigs) { 460 configs.emplace_back(element.second); 461 } 462 return configs; 463 } 464 465 Error Display::getName(std::string* outName) const 466 { 467 auto intError = mComposer.getDisplayName(mId, outName); 468 return static_cast<Error>(intError); 469 } 470 471 Error Display::getRequests(HWC2::DisplayRequest* outDisplayRequests, 472 std::unordered_map<HWC2::Layer*, LayerRequest>* outLayerRequests) { 473 uint32_t intDisplayRequests; 474 std::vector<Hwc2::Layer> layerIds; 475 std::vector<uint32_t> layerRequests; 476 auto intError = mComposer.getDisplayRequests( 477 mId, &intDisplayRequests, &layerIds, &layerRequests); 478 uint32_t numElements = layerIds.size(); 479 auto error = static_cast<Error>(intError); 480 if (error != Error::None) { 481 return error; 482 } 483 484 *outDisplayRequests = static_cast<DisplayRequest>(intDisplayRequests); 485 outLayerRequests->clear(); 486 outLayerRequests->reserve(numElements); 487 for (uint32_t element = 0; element < numElements; ++element) { 488 auto layer = getLayerById(layerIds[element]); 489 if (layer) { 490 auto layerRequest = 491 static_cast<LayerRequest>(layerRequests[element]); 492 outLayerRequests->emplace(layer, layerRequest); 493 } else { 494 ALOGE("getRequests: invalid layer %" PRIu64 " found on display %" 495 PRIu64, layerIds[element], mId); 496 } 497 } 498 499 return Error::None; 500 } 501 502 Error Display::getType(DisplayType* outType) const 503 { 504 *outType = mType; 505 return Error::None; 506 } 507 508 Error Display::supportsDoze(bool* outSupport) const { 509 *outSupport = mDisplayCapabilities.count(DisplayCapability::Doze) > 0; 510 return Error::None; 511 } 512 513 Error Display::getHdrCapabilities(HdrCapabilities* outCapabilities) const 514 { 515 float maxLuminance = -1.0f; 516 float maxAverageLuminance = -1.0f; 517 float minLuminance = -1.0f; 518 std::vector<Hwc2::Hdr> types; 519 auto intError = mComposer.getHdrCapabilities(mId, &types, 520 &maxLuminance, &maxAverageLuminance, &minLuminance); 521 auto error = static_cast<HWC2::Error>(intError); 522 523 if (error != Error::None) { 524 return error; 525 } 526 527 *outCapabilities = HdrCapabilities(std::move(types), 528 maxLuminance, maxAverageLuminance, minLuminance); 529 return Error::None; 530 } 531 532 Error Display::getDisplayedContentSamplingAttributes(PixelFormat* outFormat, 533 Dataspace* outDataspace, 534 uint8_t* outComponentMask) const { 535 auto intError = mComposer.getDisplayedContentSamplingAttributes(mId, outFormat, outDataspace, 536 outComponentMask); 537 return static_cast<Error>(intError); 538 } 539 540 Error Display::setDisplayContentSamplingEnabled(bool enabled, uint8_t componentMask, 541 uint64_t maxFrames) const { 542 auto intError = 543 mComposer.setDisplayContentSamplingEnabled(mId, enabled, componentMask, maxFrames); 544 return static_cast<Error>(intError); 545 } 546 547 Error Display::getDisplayedContentSample(uint64_t maxFrames, uint64_t timestamp, 548 android::DisplayedFrameStats* outStats) const { 549 auto intError = mComposer.getDisplayedContentSample(mId, maxFrames, timestamp, outStats); 550 return static_cast<Error>(intError); 551 } 552 553 Error Display::getReleaseFences(std::unordered_map<HWC2::Layer*, sp<Fence>>* outFences) const { 554 std::vector<Hwc2::Layer> layerIds; 555 std::vector<int> fenceFds; 556 auto intError = mComposer.getReleaseFences(mId, &layerIds, &fenceFds); 557 auto error = static_cast<Error>(intError); 558 uint32_t numElements = layerIds.size(); 559 if (error != Error::None) { 560 return error; 561 } 562 563 std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences; 564 releaseFences.reserve(numElements); 565 for (uint32_t element = 0; element < numElements; ++element) { 566 auto layer = getLayerById(layerIds[element]); 567 if (layer) { 568 sp<Fence> fence(new Fence(fenceFds[element])); 569 releaseFences.emplace(layer, fence); 570 } else { 571 ALOGE("getReleaseFences: invalid layer %" PRIu64 572 " found on display %" PRIu64, layerIds[element], mId); 573 for (; element < numElements; ++element) { 574 close(fenceFds[element]); 575 } 576 return Error::BadLayer; 577 } 578 } 579 580 *outFences = std::move(releaseFences); 581 return Error::None; 582 } 583 584 Error Display::present(sp<Fence>* outPresentFence) 585 { 586 int32_t presentFenceFd = -1; 587 auto intError = mComposer.presentDisplay(mId, &presentFenceFd); 588 auto error = static_cast<Error>(intError); 589 if (error != Error::None) { 590 return error; 591 } 592 593 *outPresentFence = new Fence(presentFenceFd); 594 return Error::None; 595 } 596 597 Error Display::setActiveConfig(const std::shared_ptr<const Config>& config) 598 { 599 if (config->getDisplayId() != mId) { 600 ALOGE("setActiveConfig received config %u for the wrong display %" 601 PRIu64 " (expected %" PRIu64 ")", config->getId(), 602 config->getDisplayId(), mId); 603 return Error::BadConfig; 604 } 605 auto intError = mComposer.setActiveConfig(mId, config->getId()); 606 return static_cast<Error>(intError); 607 } 608 609 Error Display::setClientTarget(uint32_t slot, const sp<GraphicBuffer>& target, 610 const sp<Fence>& acquireFence, Dataspace dataspace) 611 { 612 // TODO: Properly encode client target surface damage 613 int32_t fenceFd = acquireFence->dup(); 614 auto intError = mComposer.setClientTarget(mId, slot, target, 615 fenceFd, dataspace, std::vector<Hwc2::IComposerClient::Rect>()); 616 return static_cast<Error>(intError); 617 } 618 619 Error Display::setColorMode(ColorMode mode, RenderIntent renderIntent) 620 { 621 auto intError = mComposer.setColorMode(mId, mode, renderIntent); 622 return static_cast<Error>(intError); 623 } 624 625 Error Display::setColorTransform(const android::mat4& matrix, 626 android_color_transform_t hint) 627 { 628 auto intError = mComposer.setColorTransform(mId, 629 matrix.asArray(), static_cast<Hwc2::ColorTransform>(hint)); 630 return static_cast<Error>(intError); 631 } 632 633 Error Display::setOutputBuffer(const sp<GraphicBuffer>& buffer, 634 const sp<Fence>& releaseFence) 635 { 636 int32_t fenceFd = releaseFence->dup(); 637 auto handle = buffer->getNativeBuffer()->handle; 638 auto intError = mComposer.setOutputBuffer(mId, handle, fenceFd); 639 close(fenceFd); 640 return static_cast<Error>(intError); 641 } 642 643 Error Display::setPowerMode(PowerMode mode) 644 { 645 auto intMode = static_cast<Hwc2::IComposerClient::PowerMode>(mode); 646 auto intError = mComposer.setPowerMode(mId, intMode); 647 648 if (mode == PowerMode::On) { 649 std::call_once(mDisplayCapabilityQueryFlag, [this]() { 650 std::vector<Hwc2::DisplayCapability> tmpCapabilities; 651 auto error = 652 static_cast<Error>(mComposer.getDisplayCapabilities(mId, &tmpCapabilities)); 653 if (error == Error::None) { 654 for (auto capability : tmpCapabilities) { 655 mDisplayCapabilities.emplace(static_cast<DisplayCapability>(capability)); 656 } 657 } else if (error == Error::Unsupported) { 658 if (mCapabilities.count(Capability::SkipClientColorTransform)) { 659 mDisplayCapabilities.emplace(DisplayCapability::SkipClientColorTransform); 660 } 661 bool dozeSupport = false; 662 error = static_cast<Error>(mComposer.getDozeSupport(mId, &dozeSupport)); 663 if (error == Error::None && dozeSupport) { 664 mDisplayCapabilities.emplace(DisplayCapability::Doze); 665 } 666 } 667 }); 668 } 669 670 return static_cast<Error>(intError); 671 } 672 673 Error Display::setVsyncEnabled(Vsync enabled) 674 { 675 auto intEnabled = static_cast<Hwc2::IComposerClient::Vsync>(enabled); 676 auto intError = mComposer.setVsyncEnabled(mId, intEnabled); 677 return static_cast<Error>(intError); 678 } 679 680 Error Display::validate(uint32_t* outNumTypes, uint32_t* outNumRequests) 681 { 682 uint32_t numTypes = 0; 683 uint32_t numRequests = 0; 684 auto intError = mComposer.validateDisplay(mId, &numTypes, &numRequests); 685 auto error = static_cast<Error>(intError); 686 if (error != Error::None && error != Error::HasChanges) { 687 return error; 688 } 689 690 *outNumTypes = numTypes; 691 *outNumRequests = numRequests; 692 return error; 693 } 694 695 Error Display::presentOrValidate(uint32_t* outNumTypes, uint32_t* outNumRequests, 696 sp<android::Fence>* outPresentFence, uint32_t* state) { 697 698 uint32_t numTypes = 0; 699 uint32_t numRequests = 0; 700 int32_t presentFenceFd = -1; 701 auto intError = mComposer.presentOrValidateDisplay( 702 mId, &numTypes, &numRequests, &presentFenceFd, state); 703 auto error = static_cast<Error>(intError); 704 if (error != Error::None && error != Error::HasChanges) { 705 return error; 706 } 707 708 if (*state == 1) { 709 *outPresentFence = new Fence(presentFenceFd); 710 } 711 712 if (*state == 0) { 713 *outNumTypes = numTypes; 714 *outNumRequests = numRequests; 715 } 716 return error; 717 } 718 719 Error Display::setDisplayBrightness(float brightness) const { 720 auto intError = mComposer.setDisplayBrightness(mId, brightness); 721 return static_cast<Error>(intError); 722 } 723 724 // For use by Device 725 726 void Display::setConnected(bool connected) { 727 if (!mIsConnected && connected) { 728 mComposer.setClientTargetSlotCount(mId); 729 if (mType == DisplayType::Physical) { 730 loadConfigs(); 731 } 732 } 733 mIsConnected = connected; 734 } 735 736 int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute) 737 { 738 int32_t value = 0; 739 auto intError = mComposer.getDisplayAttribute(mId, configId, 740 static_cast<Hwc2::IComposerClient::Attribute>(attribute), 741 &value); 742 auto error = static_cast<Error>(intError); 743 if (error != Error::None) { 744 ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId, 745 configId, to_string(attribute).c_str(), 746 to_string(error).c_str(), intError); 747 return -1; 748 } 749 return value; 750 } 751 752 void Display::loadConfig(hwc2_config_t configId) 753 { 754 ALOGV("[%" PRIu64 "] loadConfig(%u)", mId, configId); 755 756 auto config = Config::Builder(*this, configId) 757 .setWidth(getAttribute(configId, Attribute::Width)) 758 .setHeight(getAttribute(configId, Attribute::Height)) 759 .setVsyncPeriod(getAttribute(configId, Attribute::VsyncPeriod)) 760 .setDpiX(getAttribute(configId, Attribute::DpiX)) 761 .setDpiY(getAttribute(configId, Attribute::DpiY)) 762 .build(); 763 mConfigs.emplace(configId, std::move(config)); 764 } 765 766 void Display::loadConfigs() 767 { 768 ALOGV("[%" PRIu64 "] loadConfigs", mId); 769 770 std::vector<Hwc2::Config> configIds; 771 auto intError = mComposer.getDisplayConfigs(mId, &configIds); 772 auto error = static_cast<Error>(intError); 773 if (error != Error::None) { 774 ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId, 775 to_string(error).c_str(), intError); 776 return; 777 } 778 779 for (auto configId : configIds) { 780 loadConfig(configId); 781 } 782 } 783 784 // Other Display methods 785 786 HWC2::Layer* Display::getLayerById(hwc2_layer_t id) const { 787 if (mLayers.count(id) == 0) { 788 return nullptr; 789 } 790 791 return mLayers.at(id).get(); 792 } 793 } // namespace impl 794 795 // Layer methods 796 797 Layer::~Layer() = default; 798 799 namespace impl { 800 801 Layer::Layer(android::Hwc2::Composer& composer, const std::unordered_set<Capability>& capabilities, 802 hwc2_display_t displayId, hwc2_layer_t layerId) 803 : mComposer(composer), 804 mCapabilities(capabilities), 805 mDisplayId(displayId), 806 mId(layerId), 807 mColorMatrix(android::mat4()) 808 { 809 ALOGV("Created layer %" PRIu64 " on display %" PRIu64, layerId, displayId); 810 } 811 812 Layer::~Layer() 813 { 814 auto intError = mComposer.destroyLayer(mDisplayId, mId); 815 auto error = static_cast<Error>(intError); 816 ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")" 817 " failed: %s (%d)", mDisplayId, mId, to_string(error).c_str(), 818 intError); 819 } 820 821 Error Layer::setCursorPosition(int32_t x, int32_t y) 822 { 823 auto intError = mComposer.setCursorPosition(mDisplayId, mId, x, y); 824 return static_cast<Error>(intError); 825 } 826 827 Error Layer::setBuffer(uint32_t slot, const sp<GraphicBuffer>& buffer, 828 const sp<Fence>& acquireFence) 829 { 830 if (buffer == nullptr && mBufferSlot == slot) { 831 return Error::None; 832 } 833 mBufferSlot = slot; 834 835 int32_t fenceFd = acquireFence->dup(); 836 auto intError = mComposer.setLayerBuffer(mDisplayId, mId, slot, buffer, 837 fenceFd); 838 return static_cast<Error>(intError); 839 } 840 841 Error Layer::setSurfaceDamage(const Region& damage) 842 { 843 if (damage.isRect() && mDamageRegion.isRect() && 844 (damage.getBounds() == mDamageRegion.getBounds())) { 845 return Error::None; 846 } 847 mDamageRegion = damage; 848 849 // We encode default full-screen damage as INVALID_RECT upstream, but as 0 850 // rects for HWC 851 Hwc2::Error intError = Hwc2::Error::NONE; 852 if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) { 853 intError = mComposer.setLayerSurfaceDamage(mDisplayId, 854 mId, std::vector<Hwc2::IComposerClient::Rect>()); 855 } else { 856 size_t rectCount = 0; 857 auto rectArray = damage.getArray(&rectCount); 858 859 std::vector<Hwc2::IComposerClient::Rect> hwcRects; 860 for (size_t rect = 0; rect < rectCount; ++rect) { 861 hwcRects.push_back({rectArray[rect].left, rectArray[rect].top, 862 rectArray[rect].right, rectArray[rect].bottom}); 863 } 864 865 intError = mComposer.setLayerSurfaceDamage(mDisplayId, mId, hwcRects); 866 } 867 868 return static_cast<Error>(intError); 869 } 870 871 Error Layer::setBlendMode(BlendMode mode) 872 { 873 auto intMode = static_cast<Hwc2::IComposerClient::BlendMode>(mode); 874 auto intError = mComposer.setLayerBlendMode(mDisplayId, mId, intMode); 875 return static_cast<Error>(intError); 876 } 877 878 Error Layer::setColor(hwc_color_t color) 879 { 880 Hwc2::IComposerClient::Color hwcColor{color.r, color.g, color.b, color.a}; 881 auto intError = mComposer.setLayerColor(mDisplayId, mId, hwcColor); 882 return static_cast<Error>(intError); 883 } 884 885 Error Layer::setCompositionType(Composition type) 886 { 887 auto intType = static_cast<Hwc2::IComposerClient::Composition>(type); 888 auto intError = mComposer.setLayerCompositionType( 889 mDisplayId, mId, intType); 890 return static_cast<Error>(intError); 891 } 892 893 Error Layer::setDataspace(Dataspace dataspace) 894 { 895 if (dataspace == mDataSpace) { 896 return Error::None; 897 } 898 mDataSpace = dataspace; 899 auto intError = mComposer.setLayerDataspace(mDisplayId, mId, mDataSpace); 900 return static_cast<Error>(intError); 901 } 902 903 Error Layer::setPerFrameMetadata(const int32_t supportedPerFrameMetadata, 904 const android::HdrMetadata& metadata) 905 { 906 if (metadata == mHdrMetadata) { 907 return Error::None; 908 } 909 910 mHdrMetadata = metadata; 911 int validTypes = mHdrMetadata.validTypes & supportedPerFrameMetadata; 912 std::vector<Hwc2::PerFrameMetadata> perFrameMetadatas; 913 if (validTypes & HdrMetadata::SMPTE2086) { 914 perFrameMetadatas.insert(perFrameMetadatas.end(), 915 {{Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X, 916 mHdrMetadata.smpte2086.displayPrimaryRed.x}, 917 {Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y, 918 mHdrMetadata.smpte2086.displayPrimaryRed.y}, 919 {Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X, 920 mHdrMetadata.smpte2086.displayPrimaryGreen.x}, 921 {Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y, 922 mHdrMetadata.smpte2086.displayPrimaryGreen.y}, 923 {Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X, 924 mHdrMetadata.smpte2086.displayPrimaryBlue.x}, 925 {Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y, 926 mHdrMetadata.smpte2086.displayPrimaryBlue.y}, 927 {Hwc2::PerFrameMetadataKey::WHITE_POINT_X, 928 mHdrMetadata.smpte2086.whitePoint.x}, 929 {Hwc2::PerFrameMetadataKey::WHITE_POINT_Y, 930 mHdrMetadata.smpte2086.whitePoint.y}, 931 {Hwc2::PerFrameMetadataKey::MAX_LUMINANCE, 932 mHdrMetadata.smpte2086.maxLuminance}, 933 {Hwc2::PerFrameMetadataKey::MIN_LUMINANCE, 934 mHdrMetadata.smpte2086.minLuminance}}); 935 } 936 937 if (validTypes & HdrMetadata::CTA861_3) { 938 perFrameMetadatas.insert(perFrameMetadatas.end(), 939 {{Hwc2::PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL, 940 mHdrMetadata.cta8613.maxContentLightLevel}, 941 {Hwc2::PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL, 942 mHdrMetadata.cta8613.maxFrameAverageLightLevel}}); 943 } 944 945 Error error = static_cast<Error>( 946 mComposer.setLayerPerFrameMetadata(mDisplayId, mId, perFrameMetadatas)); 947 948 if (validTypes & HdrMetadata::HDR10PLUS) { 949 std::vector<Hwc2::PerFrameMetadataBlob> perFrameMetadataBlobs; 950 perFrameMetadataBlobs.push_back( 951 {Hwc2::PerFrameMetadataKey::HDR10_PLUS_SEI, mHdrMetadata.hdr10plus}); 952 Error setMetadataBlobsError = static_cast<Error>( 953 mComposer.setLayerPerFrameMetadataBlobs(mDisplayId, mId, perFrameMetadataBlobs)); 954 if (error == Error::None) { 955 return setMetadataBlobsError; 956 } 957 } 958 return error; 959 } 960 961 Error Layer::setDisplayFrame(const Rect& frame) 962 { 963 Hwc2::IComposerClient::Rect hwcRect{frame.left, frame.top, 964 frame.right, frame.bottom}; 965 auto intError = mComposer.setLayerDisplayFrame(mDisplayId, mId, hwcRect); 966 return static_cast<Error>(intError); 967 } 968 969 Error Layer::setPlaneAlpha(float alpha) 970 { 971 auto intError = mComposer.setLayerPlaneAlpha(mDisplayId, mId, alpha); 972 return static_cast<Error>(intError); 973 } 974 975 Error Layer::setSidebandStream(const native_handle_t* stream) 976 { 977 if (mCapabilities.count(Capability::SidebandStream) == 0) { 978 ALOGE("Attempted to call setSidebandStream without checking that the " 979 "device supports sideband streams"); 980 return Error::Unsupported; 981 } 982 auto intError = mComposer.setLayerSidebandStream(mDisplayId, mId, stream); 983 return static_cast<Error>(intError); 984 } 985 986 Error Layer::setSourceCrop(const FloatRect& crop) 987 { 988 Hwc2::IComposerClient::FRect hwcRect{ 989 crop.left, crop.top, crop.right, crop.bottom}; 990 auto intError = mComposer.setLayerSourceCrop(mDisplayId, mId, hwcRect); 991 return static_cast<Error>(intError); 992 } 993 994 Error Layer::setTransform(Transform transform) 995 { 996 auto intTransform = static_cast<Hwc2::Transform>(transform); 997 auto intError = mComposer.setLayerTransform(mDisplayId, mId, intTransform); 998 return static_cast<Error>(intError); 999 } 1000 1001 Error Layer::setVisibleRegion(const Region& region) 1002 { 1003 if (region.isRect() && mVisibleRegion.isRect() && 1004 (region.getBounds() == mVisibleRegion.getBounds())) { 1005 return Error::None; 1006 } 1007 mVisibleRegion = region; 1008 1009 size_t rectCount = 0; 1010 auto rectArray = region.getArray(&rectCount); 1011 1012 std::vector<Hwc2::IComposerClient::Rect> hwcRects; 1013 for (size_t rect = 0; rect < rectCount; ++rect) { 1014 hwcRects.push_back({rectArray[rect].left, rectArray[rect].top, 1015 rectArray[rect].right, rectArray[rect].bottom}); 1016 } 1017 1018 auto intError = mComposer.setLayerVisibleRegion(mDisplayId, mId, hwcRects); 1019 return static_cast<Error>(intError); 1020 } 1021 1022 Error Layer::setZOrder(uint32_t z) 1023 { 1024 auto intError = mComposer.setLayerZOrder(mDisplayId, mId, z); 1025 return static_cast<Error>(intError); 1026 } 1027 1028 Error Layer::setInfo(uint32_t type, uint32_t appId) 1029 { 1030 auto intError = mComposer.setLayerInfo(mDisplayId, mId, type, appId); 1031 return static_cast<Error>(intError); 1032 } 1033 1034 // Composer HAL 2.3 1035 Error Layer::setColorTransform(const android::mat4& matrix) { 1036 if (matrix == mColorMatrix) { 1037 return Error::None; 1038 } 1039 auto intError = mComposer.setLayerColorTransform(mDisplayId, mId, matrix.asArray()); 1040 Error error = static_cast<Error>(intError); 1041 if (error != Error::None) { 1042 return error; 1043 } 1044 mColorMatrix = matrix; 1045 return error; 1046 } 1047 1048 } // namespace impl 1049 } // namespace HWC2 1050