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