HWC2On1Adapter.cpp revision c6998d2391e6e54cf0664bb664e0fba2f2fce1da
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 "HWC2On1Adapter" 21#define ATRACE_TAG ATRACE_TAG_GRAPHICS 22 23#include "HWC2On1Adapter.h" 24 25#include <hardware/hwcomposer.h> 26#include <log/log.h> 27#include <utils/Trace.h> 28 29#include <cstdlib> 30#include <chrono> 31#include <inttypes.h> 32#include <sstream> 33 34using namespace std::chrono_literals; 35 36static bool operator==(const hwc_color_t& lhs, const hwc_color_t& rhs) { 37 return lhs.r == rhs.r && 38 lhs.g == rhs.g && 39 lhs.b == rhs.b && 40 lhs.a == rhs.a; 41} 42 43static bool operator==(const hwc_rect_t& lhs, const hwc_rect_t& rhs) { 44 return lhs.left == rhs.left && 45 lhs.top == rhs.top && 46 lhs.right == rhs.right && 47 lhs.bottom == rhs.bottom; 48} 49 50static bool operator==(const hwc_frect_t& lhs, const hwc_frect_t& rhs) { 51 return lhs.left == rhs.left && 52 lhs.top == rhs.top && 53 lhs.right == rhs.right && 54 lhs.bottom == rhs.bottom; 55} 56 57template <typename T> 58static inline bool operator!=(const T& lhs, const T& rhs) 59{ 60 return !(lhs == rhs); 61} 62 63static uint8_t getMinorVersion(struct hwc_composer_device_1* device) 64{ 65 auto version = device->common.version & HARDWARE_API_VERSION_2_MAJ_MIN_MASK; 66 return (version >> 16) & 0xF; 67} 68 69template <typename PFN, typename T> 70static hwc2_function_pointer_t asFP(T function) 71{ 72 static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer"); 73 return reinterpret_cast<hwc2_function_pointer_t>(function); 74} 75 76using namespace HWC2; 77 78namespace android { 79 80void HWC2On1Adapter::DisplayContentsDeleter::operator()( 81 hwc_display_contents_1_t* contents) 82{ 83 if (contents != nullptr) { 84 for (size_t l = 0; l < contents->numHwLayers; ++l) { 85 auto& layer = contents->hwLayers[l]; 86 std::free(const_cast<hwc_rect_t*>(layer.visibleRegionScreen.rects)); 87 } 88 } 89 std::free(contents); 90} 91 92class HWC2On1Adapter::Callbacks : public hwc_procs_t { 93 public: 94 Callbacks(HWC2On1Adapter& adapter) : mAdapter(adapter) { 95 invalidate = &invalidateHook; 96 vsync = &vsyncHook; 97 hotplug = &hotplugHook; 98 } 99 100 static void invalidateHook(const hwc_procs_t* procs) { 101 auto callbacks = static_cast<const Callbacks*>(procs); 102 callbacks->mAdapter.hwc1Invalidate(); 103 } 104 105 static void vsyncHook(const hwc_procs_t* procs, int display, 106 int64_t timestamp) { 107 auto callbacks = static_cast<const Callbacks*>(procs); 108 callbacks->mAdapter.hwc1Vsync(display, timestamp); 109 } 110 111 static void hotplugHook(const hwc_procs_t* procs, int display, 112 int connected) { 113 auto callbacks = static_cast<const Callbacks*>(procs); 114 callbacks->mAdapter.hwc1Hotplug(display, connected); 115 } 116 117 private: 118 HWC2On1Adapter& mAdapter; 119}; 120 121static int closeHook(hw_device_t* /*device*/) 122{ 123 // Do nothing, since the real work is done in the class destructor, but we 124 // need to provide a valid function pointer for hwc2_close to call 125 return 0; 126} 127 128HWC2On1Adapter::HWC2On1Adapter(hwc_composer_device_1_t* hwc1Device) 129 : mDumpString(), 130 mHwc1Device(hwc1Device), 131 mHwc1MinorVersion(getMinorVersion(hwc1Device)), 132 mHwc1SupportsVirtualDisplays(false), 133 mHwc1Callbacks(std::make_unique<Callbacks>(*this)), 134 mCapabilities(), 135 mLayers(), 136 mHwc1VirtualDisplay(), 137 mStateMutex(), 138 mCallbacks(), 139 mHasPendingInvalidate(false), 140 mPendingVsyncs(), 141 mPendingHotplugs(), 142 mDisplays(), 143 mHwc1DisplayMap() 144{ 145 common.close = closeHook; 146 getCapabilities = getCapabilitiesHook; 147 getFunction = getFunctionHook; 148 populateCapabilities(); 149 populatePrimary(); 150 mHwc1Device->registerProcs(mHwc1Device, 151 static_cast<const hwc_procs_t*>(mHwc1Callbacks.get())); 152} 153 154HWC2On1Adapter::~HWC2On1Adapter() { 155 hwc_close_1(mHwc1Device); 156} 157 158void HWC2On1Adapter::doGetCapabilities(uint32_t* outCount, 159 int32_t* outCapabilities) 160{ 161 if (outCapabilities == nullptr) { 162 *outCount = mCapabilities.size(); 163 return; 164 } 165 166 auto capabilityIter = mCapabilities.cbegin(); 167 for (size_t written = 0; written < *outCount; ++written) { 168 if (capabilityIter == mCapabilities.cend()) { 169 return; 170 } 171 outCapabilities[written] = static_cast<int32_t>(*capabilityIter); 172 ++capabilityIter; 173 } 174} 175 176hwc2_function_pointer_t HWC2On1Adapter::doGetFunction( 177 FunctionDescriptor descriptor) 178{ 179 switch (descriptor) { 180 // Device functions 181 case FunctionDescriptor::CreateVirtualDisplay: 182 return asFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>( 183 createVirtualDisplayHook); 184 case FunctionDescriptor::DestroyVirtualDisplay: 185 return asFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>( 186 destroyVirtualDisplayHook); 187 case FunctionDescriptor::Dump: 188 return asFP<HWC2_PFN_DUMP>(dumpHook); 189 case FunctionDescriptor::GetMaxVirtualDisplayCount: 190 return asFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>( 191 getMaxVirtualDisplayCountHook); 192 case FunctionDescriptor::RegisterCallback: 193 return asFP<HWC2_PFN_REGISTER_CALLBACK>(registerCallbackHook); 194 195 // Display functions 196 case FunctionDescriptor::AcceptDisplayChanges: 197 return asFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>( 198 displayHook<decltype(&Display::acceptChanges), 199 &Display::acceptChanges>); 200 case FunctionDescriptor::CreateLayer: 201 return asFP<HWC2_PFN_CREATE_LAYER>( 202 displayHook<decltype(&Display::createLayer), 203 &Display::createLayer, hwc2_layer_t*>); 204 case FunctionDescriptor::DestroyLayer: 205 return asFP<HWC2_PFN_DESTROY_LAYER>( 206 displayHook<decltype(&Display::destroyLayer), 207 &Display::destroyLayer, hwc2_layer_t>); 208 case FunctionDescriptor::GetActiveConfig: 209 return asFP<HWC2_PFN_GET_ACTIVE_CONFIG>( 210 displayHook<decltype(&Display::getActiveConfig), 211 &Display::getActiveConfig, hwc2_config_t*>); 212 case FunctionDescriptor::GetChangedCompositionTypes: 213 return asFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>( 214 displayHook<decltype(&Display::getChangedCompositionTypes), 215 &Display::getChangedCompositionTypes, uint32_t*, 216 hwc2_layer_t*, int32_t*>); 217 case FunctionDescriptor::GetDisplayAttribute: 218 return asFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>( 219 getDisplayAttributeHook); 220 case FunctionDescriptor::GetDisplayConfigs: 221 return asFP<HWC2_PFN_GET_DISPLAY_CONFIGS>( 222 displayHook<decltype(&Display::getConfigs), 223 &Display::getConfigs, uint32_t*, hwc2_config_t*>); 224 case FunctionDescriptor::GetDisplayName: 225 return asFP<HWC2_PFN_GET_DISPLAY_NAME>( 226 displayHook<decltype(&Display::getName), 227 &Display::getName, uint32_t*, char*>); 228 case FunctionDescriptor::GetDisplayRequests: 229 return asFP<HWC2_PFN_GET_DISPLAY_REQUESTS>( 230 displayHook<decltype(&Display::getRequests), 231 &Display::getRequests, int32_t*, uint32_t*, hwc2_layer_t*, 232 int32_t*>); 233 case FunctionDescriptor::GetDisplayType: 234 return asFP<HWC2_PFN_GET_DISPLAY_TYPE>( 235 displayHook<decltype(&Display::getType), 236 &Display::getType, int32_t*>); 237 case FunctionDescriptor::GetDozeSupport: 238 return asFP<HWC2_PFN_GET_DOZE_SUPPORT>( 239 displayHook<decltype(&Display::getDozeSupport), 240 &Display::getDozeSupport, int32_t*>); 241 case FunctionDescriptor::GetReleaseFences: 242 return asFP<HWC2_PFN_GET_RELEASE_FENCES>( 243 displayHook<decltype(&Display::getReleaseFences), 244 &Display::getReleaseFences, uint32_t*, hwc2_layer_t*, 245 int32_t*>); 246 case FunctionDescriptor::PresentDisplay: 247 return asFP<HWC2_PFN_PRESENT_DISPLAY>( 248 displayHook<decltype(&Display::present), 249 &Display::present, int32_t*>); 250 case FunctionDescriptor::SetActiveConfig: 251 return asFP<HWC2_PFN_SET_ACTIVE_CONFIG>( 252 displayHook<decltype(&Display::setActiveConfig), 253 &Display::setActiveConfig, hwc2_config_t>); 254 case FunctionDescriptor::SetClientTarget: 255 return asFP<HWC2_PFN_SET_CLIENT_TARGET>( 256 displayHook<decltype(&Display::setClientTarget), 257 &Display::setClientTarget, buffer_handle_t, int32_t, 258 int32_t>); 259 case FunctionDescriptor::SetOutputBuffer: 260 return asFP<HWC2_PFN_SET_OUTPUT_BUFFER>( 261 displayHook<decltype(&Display::setOutputBuffer), 262 &Display::setOutputBuffer, buffer_handle_t, int32_t>); 263 case FunctionDescriptor::SetPowerMode: 264 return asFP<HWC2_PFN_SET_POWER_MODE>(setPowerModeHook); 265 case FunctionDescriptor::SetVsyncEnabled: 266 return asFP<HWC2_PFN_SET_VSYNC_ENABLED>(setVsyncEnabledHook); 267 case FunctionDescriptor::ValidateDisplay: 268 return asFP<HWC2_PFN_VALIDATE_DISPLAY>( 269 displayHook<decltype(&Display::validate), 270 &Display::validate, uint32_t*, uint32_t*>); 271 272 // Layer functions 273 case FunctionDescriptor::SetCursorPosition: 274 return asFP<HWC2_PFN_SET_CURSOR_POSITION>( 275 layerHook<decltype(&Layer::setCursorPosition), 276 &Layer::setCursorPosition, int32_t, int32_t>); 277 case FunctionDescriptor::SetLayerBuffer: 278 return asFP<HWC2_PFN_SET_LAYER_BUFFER>( 279 layerHook<decltype(&Layer::setBuffer), &Layer::setBuffer, 280 buffer_handle_t, int32_t>); 281 case FunctionDescriptor::SetLayerSurfaceDamage: 282 return asFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>( 283 layerHook<decltype(&Layer::setSurfaceDamage), 284 &Layer::setSurfaceDamage, hwc_region_t>); 285 286 // Layer state functions 287 case FunctionDescriptor::SetLayerBlendMode: 288 return asFP<HWC2_PFN_SET_LAYER_BLEND_MODE>( 289 setLayerBlendModeHook); 290 case FunctionDescriptor::SetLayerColor: 291 return asFP<HWC2_PFN_SET_LAYER_COLOR>( 292 layerHook<decltype(&Layer::setColor), &Layer::setColor, 293 hwc_color_t>); 294 case FunctionDescriptor::SetLayerCompositionType: 295 return asFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>( 296 setLayerCompositionTypeHook); 297 case FunctionDescriptor::SetLayerDisplayFrame: 298 return asFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>( 299 layerHook<decltype(&Layer::setDisplayFrame), 300 &Layer::setDisplayFrame, hwc_rect_t>); 301 case FunctionDescriptor::SetLayerPlaneAlpha: 302 return asFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>( 303 layerHook<decltype(&Layer::setPlaneAlpha), 304 &Layer::setPlaneAlpha, float>); 305 case FunctionDescriptor::SetLayerSidebandStream: 306 return asFP<HWC2_PFN_SET_LAYER_SIDEBAND_STREAM>( 307 layerHook<decltype(&Layer::setSidebandStream), 308 &Layer::setSidebandStream, const native_handle_t*>); 309 case FunctionDescriptor::SetLayerSourceCrop: 310 return asFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>( 311 layerHook<decltype(&Layer::setSourceCrop), 312 &Layer::setSourceCrop, hwc_frect_t>); 313 case FunctionDescriptor::SetLayerTransform: 314 return asFP<HWC2_PFN_SET_LAYER_TRANSFORM>(setLayerTransformHook); 315 case FunctionDescriptor::SetLayerVisibleRegion: 316 return asFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>( 317 layerHook<decltype(&Layer::setVisibleRegion), 318 &Layer::setVisibleRegion, hwc_region_t>); 319 case FunctionDescriptor::SetLayerZOrder: 320 return asFP<HWC2_PFN_SET_LAYER_Z_ORDER>(setLayerZOrderHook); 321 322 default: 323 ALOGE("doGetFunction: Unknown function descriptor: %d (%s)", 324 static_cast<int32_t>(descriptor), 325 to_string(descriptor).c_str()); 326 return nullptr; 327 } 328} 329 330// Device functions 331 332Error HWC2On1Adapter::createVirtualDisplay(uint32_t width, 333 uint32_t height, hwc2_display_t* outDisplay) 334{ 335 std::unique_lock<std::timed_mutex> lock(mStateMutex); 336 337 if (mHwc1VirtualDisplay) { 338 // We have already allocated our only HWC1 virtual display 339 ALOGE("createVirtualDisplay: HWC1 virtual display already allocated"); 340 return Error::NoResources; 341 } 342 343 if (MAX_VIRTUAL_DISPLAY_DIMENSION != 0 && 344 (width > MAX_VIRTUAL_DISPLAY_DIMENSION || 345 height > MAX_VIRTUAL_DISPLAY_DIMENSION)) { 346 ALOGE("createVirtualDisplay: Can't create a virtual display with" 347 " a dimension > %u (tried %u x %u)", 348 MAX_VIRTUAL_DISPLAY_DIMENSION, width, height); 349 return Error::NoResources; 350 } 351 352 mHwc1VirtualDisplay = std::make_shared<HWC2On1Adapter::Display>(*this, 353 HWC2::DisplayType::Virtual); 354 mHwc1VirtualDisplay->populateConfigs(width, height); 355 const auto displayId = mHwc1VirtualDisplay->getId(); 356 mHwc1DisplayMap[HWC_DISPLAY_VIRTUAL] = displayId; 357 mHwc1VirtualDisplay->setHwc1Id(HWC_DISPLAY_VIRTUAL); 358 mDisplays.emplace(displayId, mHwc1VirtualDisplay); 359 *outDisplay = displayId; 360 361 return Error::None; 362} 363 364Error HWC2On1Adapter::destroyVirtualDisplay(hwc2_display_t displayId) 365{ 366 std::unique_lock<std::timed_mutex> lock(mStateMutex); 367 368 if (!mHwc1VirtualDisplay || (mHwc1VirtualDisplay->getId() != displayId)) { 369 return Error::BadDisplay; 370 } 371 372 mHwc1VirtualDisplay.reset(); 373 mHwc1DisplayMap.erase(HWC_DISPLAY_VIRTUAL); 374 mDisplays.erase(displayId); 375 376 return Error::None; 377} 378 379void HWC2On1Adapter::dump(uint32_t* outSize, char* outBuffer) 380{ 381 if (outBuffer != nullptr) { 382 auto copiedBytes = mDumpString.copy(outBuffer, *outSize); 383 *outSize = static_cast<uint32_t>(copiedBytes); 384 return; 385 } 386 387 std::stringstream output; 388 389 output << "-- HWC2On1Adapter --\n"; 390 391 output << "Adapting to a HWC 1." << static_cast<int>(mHwc1MinorVersion) << 392 " device\n"; 393 394 // Attempt to acquire the lock for 1 second, but proceed without the lock 395 // after that, so we can still get some information if we're deadlocked 396 std::unique_lock<std::timed_mutex> lock(mStateMutex, std::defer_lock); 397 lock.try_lock_for(1s); 398 399 if (mCapabilities.empty()) { 400 output << "Capabilities: None\n"; 401 } else { 402 output << "Capabilities:\n"; 403 for (auto capability : mCapabilities) { 404 output << " " << to_string(capability) << '\n'; 405 } 406 } 407 408 output << "Displays:\n"; 409 for (const auto& element : mDisplays) { 410 const auto& display = element.second; 411 output << display->dump(); 412 } 413 output << '\n'; 414 415 if (mHwc1Device->dump) { 416 output << "HWC1 dump:\n"; 417 std::vector<char> hwc1Dump(4096); 418 // Call with size - 1 to preserve a null character at the end 419 mHwc1Device->dump(mHwc1Device, hwc1Dump.data(), 420 static_cast<int>(hwc1Dump.size() - 1)); 421 output << hwc1Dump.data(); 422 } 423 424 mDumpString = output.str(); 425 *outSize = static_cast<uint32_t>(mDumpString.size()); 426} 427 428uint32_t HWC2On1Adapter::getMaxVirtualDisplayCount() 429{ 430 return mHwc1SupportsVirtualDisplays ? 1 : 0; 431} 432 433static bool isValid(Callback descriptor) { 434 switch (descriptor) { 435 case Callback::Hotplug: // Fall-through 436 case Callback::Refresh: // Fall-through 437 case Callback::Vsync: return true; 438 default: return false; 439 } 440} 441 442Error HWC2On1Adapter::registerCallback(Callback descriptor, 443 hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer) 444{ 445 if (!isValid(descriptor)) { 446 return Error::BadParameter; 447 } 448 449 ALOGV("registerCallback(%s, %p, %p)", to_string(descriptor).c_str(), 450 callbackData, pointer); 451 452 std::unique_lock<std::timed_mutex> lock(mStateMutex); 453 454 mCallbacks[descriptor] = {callbackData, pointer}; 455 456 bool hasPendingInvalidate = false; 457 std::vector<hwc2_display_t> displayIds; 458 std::vector<std::pair<hwc2_display_t, int64_t>> pendingVsyncs; 459 std::vector<std::pair<hwc2_display_t, int>> pendingHotplugs; 460 461 if (descriptor == Callback::Refresh) { 462 hasPendingInvalidate = mHasPendingInvalidate; 463 if (hasPendingInvalidate) { 464 for (auto& displayPair : mDisplays) { 465 displayIds.emplace_back(displayPair.first); 466 } 467 } 468 mHasPendingInvalidate = false; 469 } else if (descriptor == Callback::Vsync) { 470 for (auto pending : mPendingVsyncs) { 471 auto hwc1DisplayId = pending.first; 472 if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) { 473 ALOGE("hwc1Vsync: Couldn't find display for HWC1 id %d", 474 hwc1DisplayId); 475 continue; 476 } 477 auto displayId = mHwc1DisplayMap[hwc1DisplayId]; 478 auto timestamp = pending.second; 479 pendingVsyncs.emplace_back(displayId, timestamp); 480 } 481 mPendingVsyncs.clear(); 482 } else if (descriptor == Callback::Hotplug) { 483 // Hotplug the primary display 484 pendingHotplugs.emplace_back(mHwc1DisplayMap[HWC_DISPLAY_PRIMARY], 485 static_cast<int32_t>(Connection::Connected)); 486 487 for (auto pending : mPendingHotplugs) { 488 auto hwc1DisplayId = pending.first; 489 if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) { 490 ALOGE("hwc1Hotplug: Couldn't find display for HWC1 id %d", 491 hwc1DisplayId); 492 continue; 493 } 494 auto displayId = mHwc1DisplayMap[hwc1DisplayId]; 495 auto connected = pending.second; 496 pendingHotplugs.emplace_back(displayId, connected); 497 } 498 } 499 500 // Call pending callbacks without the state lock held 501 lock.unlock(); 502 503 if (hasPendingInvalidate) { 504 auto refresh = reinterpret_cast<HWC2_PFN_REFRESH>(pointer); 505 for (auto displayId : displayIds) { 506 refresh(callbackData, displayId); 507 } 508 } 509 if (!pendingVsyncs.empty()) { 510 auto vsync = reinterpret_cast<HWC2_PFN_VSYNC>(pointer); 511 for (auto& pendingVsync : pendingVsyncs) { 512 vsync(callbackData, pendingVsync.first, pendingVsync.second); 513 } 514 } 515 if (!pendingHotplugs.empty()) { 516 auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(pointer); 517 for (auto& pendingHotplug : pendingHotplugs) { 518 hotplug(callbackData, pendingHotplug.first, pendingHotplug.second); 519 } 520 } 521 return Error::None; 522} 523 524// Display functions 525 526std::atomic<hwc2_display_t> HWC2On1Adapter::Display::sNextId(1); 527 528HWC2On1Adapter::Display::Display(HWC2On1Adapter& device, HWC2::DisplayType type) 529 : mId(sNextId++), 530 mDevice(device), 531 mDirtyCount(0), 532 mStateMutex(), 533 mZIsDirty(false), 534 mHwc1RequestedContents(nullptr), 535 mHwc1ReceivedContents(nullptr), 536 mRetireFence(), 537 mChanges(), 538 mHwc1Id(-1), 539 mConfigs(), 540 mActiveConfig(nullptr), 541 mName(), 542 mType(type), 543 mPowerMode(PowerMode::Off), 544 mVsyncEnabled(Vsync::Invalid), 545 mClientTarget(), 546 mOutputBuffer(), 547 mLayers() {} 548 549Error HWC2On1Adapter::Display::acceptChanges() 550{ 551 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 552 553 if (!mChanges) { 554 ALOGV("[%" PRIu64 "] acceptChanges failed, not validated", mId); 555 return Error::NotValidated; 556 } 557 558 ALOGV("[%" PRIu64 "] acceptChanges", mId); 559 560 for (auto& change : mChanges->getTypeChanges()) { 561 auto layerId = change.first; 562 auto type = change.second; 563 auto layer = mDevice.mLayers[layerId]; 564 layer->setCompositionType(type); 565 } 566 567 mChanges->clearTypeChanges(); 568 569 mHwc1RequestedContents = std::move(mHwc1ReceivedContents); 570 571 return Error::None; 572} 573 574Error HWC2On1Adapter::Display::createLayer(hwc2_layer_t* outLayerId) 575{ 576 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 577 578 auto layer = *mLayers.emplace(std::make_shared<Layer>(*this)); 579 mDevice.mLayers.emplace(std::make_pair(layer->getId(), layer)); 580 *outLayerId = layer->getId(); 581 ALOGV("[%" PRIu64 "] created layer %" PRIu64, mId, *outLayerId); 582 return Error::None; 583} 584 585Error HWC2On1Adapter::Display::destroyLayer(hwc2_layer_t layerId) 586{ 587 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 588 589 const auto mapLayer = mDevice.mLayers.find(layerId); 590 if (mapLayer == mDevice.mLayers.end()) { 591 ALOGV("[%" PRIu64 "] destroyLayer(%" PRIu64 ") failed: no such layer", 592 mId, layerId); 593 return Error::BadLayer; 594 } 595 const auto layer = mapLayer->second; 596 mDevice.mLayers.erase(mapLayer); 597 const auto zRange = mLayers.equal_range(layer); 598 for (auto current = zRange.first; current != zRange.second; ++current) { 599 if (**current == *layer) { 600 current = mLayers.erase(current); 601 break; 602 } 603 } 604 ALOGV("[%" PRIu64 "] destroyed layer %" PRIu64, mId, layerId); 605 return Error::None; 606} 607 608Error HWC2On1Adapter::Display::getActiveConfig(hwc2_config_t* outConfig) 609{ 610 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 611 612 if (!mActiveConfig) { 613 ALOGV("[%" PRIu64 "] getActiveConfig --> %s", mId, 614 to_string(Error::BadConfig).c_str()); 615 return Error::BadConfig; 616 } 617 auto configId = mActiveConfig->getId(); 618 ALOGV("[%" PRIu64 "] getActiveConfig --> %u", mId, configId); 619 *outConfig = configId; 620 return Error::None; 621} 622 623Error HWC2On1Adapter::Display::getAttribute(hwc2_config_t configId, 624 Attribute attribute, int32_t* outValue) 625{ 626 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 627 628 if (configId > mConfigs.size() || !mConfigs[configId]->isOnDisplay(*this)) { 629 ALOGV("[%" PRIu64 "] getAttribute failed: bad config (%u)", mId, 630 configId); 631 return Error::BadConfig; 632 } 633 *outValue = mConfigs[configId]->getAttribute(attribute); 634 ALOGV("[%" PRIu64 "] getAttribute(%u, %s) --> %d", mId, configId, 635 to_string(attribute).c_str(), *outValue); 636 return Error::None; 637} 638 639Error HWC2On1Adapter::Display::getChangedCompositionTypes( 640 uint32_t* outNumElements, hwc2_layer_t* outLayers, int32_t* outTypes) 641{ 642 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 643 644 if (!mChanges) { 645 ALOGE("[%" PRIu64 "] getChangedCompositionTypes failed: not validated", 646 mId); 647 return Error::NotValidated; 648 } 649 650 if ((outLayers == nullptr) || (outTypes == nullptr)) { 651 *outNumElements = mChanges->getTypeChanges().size(); 652 return Error::None; 653 } 654 655 uint32_t numWritten = 0; 656 for (const auto& element : mChanges->getTypeChanges()) { 657 if (numWritten == *outNumElements) { 658 break; 659 } 660 auto layerId = element.first; 661 auto intType = static_cast<int32_t>(element.second); 662 ALOGV("Adding %" PRIu64 " %s", layerId, 663 to_string(element.second).c_str()); 664 outLayers[numWritten] = layerId; 665 outTypes[numWritten] = intType; 666 ++numWritten; 667 } 668 *outNumElements = numWritten; 669 670 return Error::None; 671} 672 673Error HWC2On1Adapter::Display::getConfigs(uint32_t* outNumConfigs, 674 hwc2_config_t* outConfigs) 675{ 676 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 677 678 if (!outConfigs) { 679 *outNumConfigs = mConfigs.size(); 680 return Error::None; 681 } 682 uint32_t numWritten = 0; 683 for (const auto& config : mConfigs) { 684 if (numWritten == *outNumConfigs) { 685 break; 686 } 687 outConfigs[numWritten] = config->getId(); 688 ++numWritten; 689 } 690 *outNumConfigs = numWritten; 691 return Error::None; 692} 693 694Error HWC2On1Adapter::Display::getDozeSupport(int32_t* outSupport) 695{ 696 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 697 698 if (mDevice.mHwc1MinorVersion < 4 || mHwc1Id != 0) { 699 *outSupport = 0; 700 } else { 701 *outSupport = 1; 702 } 703 return Error::None; 704} 705 706Error HWC2On1Adapter::Display::getName(uint32_t* outSize, char* outName) 707{ 708 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 709 710 if (!outName) { 711 *outSize = mName.size(); 712 return Error::None; 713 } 714 auto numCopied = mName.copy(outName, *outSize); 715 *outSize = numCopied; 716 return Error::None; 717} 718 719Error HWC2On1Adapter::Display::getReleaseFences(uint32_t* outNumElements, 720 hwc2_layer_t* outLayers, int32_t* outFences) 721{ 722 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 723 724 uint32_t numWritten = 0; 725 bool outputsNonNull = (outLayers != nullptr) && (outFences != nullptr); 726 for (const auto& layer : mLayers) { 727 if (outputsNonNull && (numWritten == *outNumElements)) { 728 break; 729 } 730 731 auto releaseFence = layer->getReleaseFence(); 732 if (releaseFence != Fence::NO_FENCE) { 733 if (outputsNonNull) { 734 outLayers[numWritten] = layer->getId(); 735 outFences[numWritten] = releaseFence->dup(); 736 } 737 ++numWritten; 738 } 739 } 740 *outNumElements = numWritten; 741 742 return Error::None; 743} 744 745Error HWC2On1Adapter::Display::getRequests(int32_t* outDisplayRequests, 746 uint32_t* outNumElements, hwc2_layer_t* outLayers, 747 int32_t* outLayerRequests) 748{ 749 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 750 751 if (!mChanges) { 752 return Error::NotValidated; 753 } 754 755 if (outLayers == nullptr || outLayerRequests == nullptr) { 756 *outNumElements = mChanges->getNumLayerRequests(); 757 return Error::None; 758 } 759 760 *outDisplayRequests = mChanges->getDisplayRequests(); 761 uint32_t numWritten = 0; 762 for (const auto& request : mChanges->getLayerRequests()) { 763 if (numWritten == *outNumElements) { 764 break; 765 } 766 outLayers[numWritten] = request.first; 767 outLayerRequests[numWritten] = static_cast<int32_t>(request.second); 768 ++numWritten; 769 } 770 771 return Error::None; 772} 773 774Error HWC2On1Adapter::Display::getType(int32_t* outType) 775{ 776 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 777 778 *outType = static_cast<int32_t>(mType); 779 return Error::None; 780} 781 782Error HWC2On1Adapter::Display::present(int32_t* outRetireFence) 783{ 784 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 785 786 if (mChanges) { 787 Error error = mDevice.setAllDisplays(); 788 if (error != Error::None) { 789 ALOGE("[%" PRIu64 "] present: setAllDisplaysFailed (%s)", mId, 790 to_string(error).c_str()); 791 return error; 792 } 793 } 794 795 *outRetireFence = mRetireFence.get()->dup(); 796 ALOGV("[%" PRIu64 "] present returning retire fence %d", mId, 797 *outRetireFence); 798 799 return Error::None; 800} 801 802Error HWC2On1Adapter::Display::setActiveConfig(hwc2_config_t configId) 803{ 804 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 805 806 auto config = getConfig(configId); 807 if (!config) { 808 return Error::BadConfig; 809 } 810 mActiveConfig = config; 811 if (mDevice.mHwc1MinorVersion >= 4) { 812 int error = mDevice.mHwc1Device->setActiveConfig(mDevice.mHwc1Device, 813 mHwc1Id, static_cast<int>(configId)); 814 ALOGE_IF(error != 0, 815 "setActiveConfig: Failed to set active config on HWC1 (%d)", 816 error); 817 } 818 return Error::None; 819} 820 821Error HWC2On1Adapter::Display::setClientTarget(buffer_handle_t target, 822 int32_t acquireFence, int32_t /*dataspace*/) 823{ 824 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 825 826 ALOGV("[%" PRIu64 "] setClientTarget(%p, %d)", mId, target, acquireFence); 827 mClientTarget.setBuffer(target); 828 mClientTarget.setFence(acquireFence); 829 // dataspace can't be used by HWC1, so ignore it 830 return Error::None; 831} 832 833Error HWC2On1Adapter::Display::setOutputBuffer(buffer_handle_t buffer, 834 int32_t releaseFence) 835{ 836 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 837 838 ALOGV("[%" PRIu64 "] setOutputBuffer(%p, %d)", mId, buffer, releaseFence); 839 mOutputBuffer.setBuffer(buffer); 840 mOutputBuffer.setFence(releaseFence); 841 return Error::None; 842} 843 844static bool isValid(PowerMode mode) 845{ 846 switch (mode) { 847 case PowerMode::Off: // Fall-through 848 case PowerMode::DozeSuspend: // Fall-through 849 case PowerMode::Doze: // Fall-through 850 case PowerMode::On: return true; 851 default: return false; 852 } 853} 854 855static int getHwc1PowerMode(PowerMode mode) 856{ 857 switch (mode) { 858 case PowerMode::Off: return HWC_POWER_MODE_OFF; 859 case PowerMode::DozeSuspend: return HWC_POWER_MODE_DOZE_SUSPEND; 860 case PowerMode::Doze: return HWC_POWER_MODE_DOZE; 861 case PowerMode::On: return HWC_POWER_MODE_NORMAL; 862 default: return HWC_POWER_MODE_OFF; 863 } 864} 865 866Error HWC2On1Adapter::Display::setPowerMode(PowerMode mode) 867{ 868 if (!isValid(mode)) { 869 return Error::BadParameter; 870 } 871 if (mode == mPowerMode) { 872 return Error::None; 873 } 874 875 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 876 877 int error = 0; 878 if (mDevice.mHwc1MinorVersion < 4) { 879 error = mDevice.mHwc1Device->blank(mDevice.mHwc1Device, mHwc1Id, 880 mode == PowerMode::Off); 881 } else { 882 error = mDevice.mHwc1Device->setPowerMode(mDevice.mHwc1Device, 883 mHwc1Id, getHwc1PowerMode(mode)); 884 } 885 ALOGE_IF(error != 0, "setPowerMode: Failed to set power mode on HWC1 (%d)", 886 error); 887 888 ALOGV("[%" PRIu64 "] setPowerMode(%s)", mId, to_string(mode).c_str()); 889 mPowerMode = mode; 890 return Error::None; 891} 892 893static bool isValid(Vsync enable) { 894 switch (enable) { 895 case Vsync::Enable: // Fall-through 896 case Vsync::Disable: return true; 897 default: return false; 898 } 899} 900 901Error HWC2On1Adapter::Display::setVsyncEnabled(Vsync enable) 902{ 903 if (!isValid(enable)) { 904 return Error::BadParameter; 905 } 906 if (enable == mVsyncEnabled) { 907 return Error::None; 908 } 909 910 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 911 912 int error = mDevice.mHwc1Device->eventControl(mDevice.mHwc1Device, 913 mHwc1Id, HWC_EVENT_VSYNC, enable == Vsync::Enable); 914 ALOGE_IF(error != 0, "setVsyncEnabled: Failed to set vsync on HWC1 (%d)", 915 error); 916 917 mVsyncEnabled = enable; 918 return Error::None; 919} 920 921Error HWC2On1Adapter::Display::validate(uint32_t* outNumTypes, 922 uint32_t* outNumRequests) 923{ 924 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 925 926 ALOGV("[%" PRIu64 "] Entering validate", mId); 927 928 if (!mChanges) { 929 if (!mDevice.prepareAllDisplays()) { 930 return Error::BadDisplay; 931 } 932 } 933 934 *outNumTypes = mChanges->getNumTypes(); 935 *outNumRequests = mChanges->getNumLayerRequests(); 936 ALOGV("[%" PRIu64 "] validate --> %u types, %u requests", mId, *outNumTypes, 937 *outNumRequests); 938 for (auto request : mChanges->getTypeChanges()) { 939 ALOGV("Layer %" PRIu64 " --> %s", request.first, 940 to_string(request.second).c_str()); 941 } 942 return *outNumTypes > 0 ? Error::HasChanges : Error::None; 943} 944 945// Display helpers 946 947Error HWC2On1Adapter::Display::updateLayerZ(hwc2_layer_t layerId, uint32_t z) 948{ 949 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 950 951 const auto mapLayer = mDevice.mLayers.find(layerId); 952 if (mapLayer == mDevice.mLayers.end()) { 953 ALOGE("[%" PRIu64 "] updateLayerZ failed to find layer", mId); 954 return Error::BadLayer; 955 } 956 957 const auto layer = mapLayer->second; 958 const auto zRange = mLayers.equal_range(layer); 959 bool layerOnDisplay = false; 960 for (auto current = zRange.first; current != zRange.second; ++current) { 961 if (**current == *layer) { 962 if ((*current)->getZ() == z) { 963 // Don't change anything if the Z hasn't changed 964 return Error::None; 965 } 966 current = mLayers.erase(current); 967 layerOnDisplay = true; 968 break; 969 } 970 } 971 972 if (!layerOnDisplay) { 973 ALOGE("[%" PRIu64 "] updateLayerZ failed to find layer on display", 974 mId); 975 return Error::BadLayer; 976 } 977 978 layer->setZ(z); 979 mLayers.emplace(std::move(layer)); 980 mZIsDirty = true; 981 982 return Error::None; 983} 984 985static constexpr uint32_t ATTRIBUTES[] = { 986 HWC_DISPLAY_VSYNC_PERIOD, 987 HWC_DISPLAY_WIDTH, 988 HWC_DISPLAY_HEIGHT, 989 HWC_DISPLAY_DPI_X, 990 HWC_DISPLAY_DPI_Y, 991 HWC_DISPLAY_NO_ATTRIBUTE, 992}; 993static constexpr size_t NUM_ATTRIBUTES = sizeof(ATTRIBUTES) / sizeof(uint32_t); 994 995static constexpr uint32_t ATTRIBUTE_MAP[] = { 996 5, // HWC_DISPLAY_NO_ATTRIBUTE = 0 997 0, // HWC_DISPLAY_VSYNC_PERIOD = 1, 998 1, // HWC_DISPLAY_WIDTH = 2, 999 2, // HWC_DISPLAY_HEIGHT = 3, 1000 3, // HWC_DISPLAY_DPI_X = 4, 1001 4, // HWC_DISPLAY_DPI_Y = 5, 1002}; 1003 1004template <uint32_t attribute> 1005static constexpr bool attributesMatch() 1006{ 1007 return ATTRIBUTES[ATTRIBUTE_MAP[attribute]] == attribute; 1008} 1009static_assert(attributesMatch<HWC_DISPLAY_VSYNC_PERIOD>(), 1010 "Tables out of sync"); 1011static_assert(attributesMatch<HWC_DISPLAY_WIDTH>(), "Tables out of sync"); 1012static_assert(attributesMatch<HWC_DISPLAY_HEIGHT>(), "Tables out of sync"); 1013static_assert(attributesMatch<HWC_DISPLAY_DPI_X>(), "Tables out of sync"); 1014static_assert(attributesMatch<HWC_DISPLAY_DPI_Y>(), "Tables out of sync"); 1015 1016void HWC2On1Adapter::Display::populateConfigs() 1017{ 1018 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 1019 1020 ALOGV("[%" PRIu64 "] populateConfigs", mId); 1021 1022 if (mHwc1Id == -1) { 1023 ALOGE("populateConfigs: HWC1 ID not set"); 1024 return; 1025 } 1026 1027 const size_t MAX_NUM_CONFIGS = 128; 1028 uint32_t configs[MAX_NUM_CONFIGS] = {}; 1029 size_t numConfigs = MAX_NUM_CONFIGS; 1030 mDevice.mHwc1Device->getDisplayConfigs(mDevice.mHwc1Device, mHwc1Id, 1031 configs, &numConfigs); 1032 1033 for (size_t c = 0; c < numConfigs; ++c) { 1034 uint32_t hwc1ConfigId = configs[c]; 1035 hwc2_config_t id = static_cast<hwc2_config_t>(mConfigs.size()); 1036 mConfigs.emplace_back( 1037 std::make_shared<Config>(*this, id, hwc1ConfigId)); 1038 auto& config = mConfigs[id]; 1039 1040 int32_t values[NUM_ATTRIBUTES] = {}; 1041 mDevice.mHwc1Device->getDisplayAttributes(mDevice.mHwc1Device, mHwc1Id, 1042 hwc1ConfigId, ATTRIBUTES, values); 1043 1044 config->setAttribute(Attribute::VsyncPeriod, 1045 values[ATTRIBUTE_MAP[HWC_DISPLAY_VSYNC_PERIOD]]); 1046 config->setAttribute(Attribute::Width, 1047 values[ATTRIBUTE_MAP[HWC_DISPLAY_WIDTH]]); 1048 config->setAttribute(Attribute::Height, 1049 values[ATTRIBUTE_MAP[HWC_DISPLAY_HEIGHT]]); 1050 config->setAttribute(Attribute::DpiX, 1051 values[ATTRIBUTE_MAP[HWC_DISPLAY_DPI_X]]); 1052 config->setAttribute(Attribute::DpiY, 1053 values[ATTRIBUTE_MAP[HWC_DISPLAY_DPI_Y]]); 1054 1055 ALOGV("Found config: %s", config->toString().c_str()); 1056 } 1057 1058 ALOGV("Getting active config"); 1059 if (mDevice.mHwc1Device->getActiveConfig != nullptr) { 1060 auto activeConfig = mDevice.mHwc1Device->getActiveConfig( 1061 mDevice.mHwc1Device, mHwc1Id); 1062 if (activeConfig >= 0) { 1063 ALOGV("Setting active config to %d", activeConfig); 1064 mActiveConfig = mConfigs[activeConfig]; 1065 } 1066 } else { 1067 ALOGV("getActiveConfig is null, choosing config 0"); 1068 mActiveConfig = mConfigs[0]; 1069 } 1070} 1071 1072void HWC2On1Adapter::Display::populateConfigs(uint32_t width, uint32_t height) 1073{ 1074 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 1075 1076 mConfigs.emplace_back(std::make_shared<Config>(*this, 0, 0)); 1077 auto& config = mConfigs[0]; 1078 1079 config->setAttribute(Attribute::Width, static_cast<int32_t>(width)); 1080 config->setAttribute(Attribute::Height, static_cast<int32_t>(height)); 1081 mActiveConfig = config; 1082} 1083 1084bool HWC2On1Adapter::Display::prepare() 1085{ 1086 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 1087 1088 // Only prepare display contents for displays HWC1 knows about 1089 if (mHwc1Id == -1) { 1090 return true; 1091 } 1092 1093 // It doesn't make sense to prepare a display for which there is no active 1094 // config, so return early 1095 if (!mActiveConfig) { 1096 ALOGE("[%" PRIu64 "] Attempted to prepare, but no config active", mId); 1097 return false; 1098 } 1099 1100 ALOGV("[%" PRIu64 "] Entering prepare", mId); 1101 1102 auto currentCount = mHwc1RequestedContents ? 1103 mHwc1RequestedContents->numHwLayers : 0; 1104 auto requiredCount = mLayers.size() + 1; 1105 ALOGV("[%" PRIu64 "] Requires %zd layers, %zd allocated in %p", mId, 1106 requiredCount, currentCount, mHwc1RequestedContents.get()); 1107 1108 bool layerCountChanged = (currentCount != requiredCount); 1109 if (layerCountChanged) { 1110 reallocateHwc1Contents(); 1111 } 1112 1113 bool applyAllState = false; 1114 if (layerCountChanged || mZIsDirty) { 1115 assignHwc1LayerIds(); 1116 mZIsDirty = false; 1117 applyAllState = true; 1118 } 1119 1120 mHwc1RequestedContents->retireFenceFd = -1; 1121 mHwc1RequestedContents->flags = 0; 1122 if (isDirty() || applyAllState) { 1123 mHwc1RequestedContents->flags |= HWC_GEOMETRY_CHANGED; 1124 } 1125 1126 for (auto& layer : mLayers) { 1127 auto& hwc1Layer = mHwc1RequestedContents->hwLayers[layer->getHwc1Id()]; 1128 hwc1Layer.releaseFenceFd = -1; 1129 layer->applyState(hwc1Layer, applyAllState); 1130 } 1131 1132 mHwc1RequestedContents->outbuf = mOutputBuffer.getBuffer(); 1133 mHwc1RequestedContents->outbufAcquireFenceFd = mOutputBuffer.getFence(); 1134 1135 prepareFramebufferTarget(); 1136 1137 return true; 1138} 1139 1140static void cloneHWCRegion(hwc_region_t& region) 1141{ 1142 auto size = sizeof(hwc_rect_t) * region.numRects; 1143 auto newRects = static_cast<hwc_rect_t*>(std::malloc(size)); 1144 std::copy_n(region.rects, region.numRects, newRects); 1145 region.rects = newRects; 1146} 1147 1148HWC2On1Adapter::Display::HWC1Contents 1149 HWC2On1Adapter::Display::cloneRequestedContents() const 1150{ 1151 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 1152 1153 size_t size = sizeof(hwc_display_contents_1_t) + 1154 sizeof(hwc_layer_1_t) * (mHwc1RequestedContents->numHwLayers); 1155 auto contents = static_cast<hwc_display_contents_1_t*>(std::malloc(size)); 1156 std::memcpy(contents, mHwc1RequestedContents.get(), size); 1157 for (size_t layerId = 0; layerId < contents->numHwLayers; ++layerId) { 1158 auto& layer = contents->hwLayers[layerId]; 1159 // Deep copy the regions to avoid double-frees 1160 cloneHWCRegion(layer.visibleRegionScreen); 1161 cloneHWCRegion(layer.surfaceDamage); 1162 } 1163 return HWC1Contents(contents); 1164} 1165 1166void HWC2On1Adapter::Display::setReceivedContents(HWC1Contents contents) 1167{ 1168 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 1169 1170 mHwc1ReceivedContents = std::move(contents); 1171 1172 mChanges.reset(new Changes); 1173 1174 size_t numLayers = mHwc1ReceivedContents->numHwLayers; 1175 for (size_t hwc1Id = 0; hwc1Id < numLayers; ++hwc1Id) { 1176 const auto& receivedLayer = mHwc1ReceivedContents->hwLayers[hwc1Id]; 1177 if (mHwc1LayerMap.count(hwc1Id) == 0) { 1178 ALOGE_IF(receivedLayer.compositionType != HWC_FRAMEBUFFER_TARGET, 1179 "setReceivedContents: HWC1 layer %zd doesn't have a" 1180 " matching HWC2 layer, and isn't the framebuffer target", 1181 hwc1Id); 1182 continue; 1183 } 1184 1185 Layer& layer = *mHwc1LayerMap[hwc1Id]; 1186 updateTypeChanges(receivedLayer, layer); 1187 updateLayerRequests(receivedLayer, layer); 1188 } 1189} 1190 1191bool HWC2On1Adapter::Display::hasChanges() const 1192{ 1193 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 1194 return mChanges != nullptr; 1195} 1196 1197Error HWC2On1Adapter::Display::set(hwc_display_contents_1& hwcContents) 1198{ 1199 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 1200 1201 if (!mChanges || (mChanges->getNumTypes() > 0)) { 1202 ALOGE("[%" PRIu64 "] set failed: not validated", mId); 1203 return Error::NotValidated; 1204 } 1205 1206 // Set up the client/framebuffer target 1207 auto numLayers = hwcContents.numHwLayers; 1208 1209 // Close acquire fences on FRAMEBUFFER layers, since they will not be used 1210 // by HWC 1211 for (size_t l = 0; l < numLayers - 1; ++l) { 1212 auto& layer = hwcContents.hwLayers[l]; 1213 if (layer.compositionType == HWC_FRAMEBUFFER) { 1214 ALOGV("Closing fence %d for layer %zd", layer.acquireFenceFd, l); 1215 close(layer.acquireFenceFd); 1216 layer.acquireFenceFd = -1; 1217 } 1218 } 1219 1220 auto& clientTargetLayer = hwcContents.hwLayers[numLayers - 1]; 1221 if (clientTargetLayer.compositionType == HWC_FRAMEBUFFER_TARGET) { 1222 clientTargetLayer.handle = mClientTarget.getBuffer(); 1223 clientTargetLayer.acquireFenceFd = mClientTarget.getFence(); 1224 } else { 1225 ALOGE("[%" PRIu64 "] set: last HWC layer wasn't FRAMEBUFFER_TARGET", 1226 mId); 1227 } 1228 1229 mChanges.reset(); 1230 1231 return Error::None; 1232} 1233 1234void HWC2On1Adapter::Display::addRetireFence(int fenceFd) 1235{ 1236 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 1237 mRetireFence.add(fenceFd); 1238} 1239 1240void HWC2On1Adapter::Display::addReleaseFences( 1241 const hwc_display_contents_1_t& hwcContents) 1242{ 1243 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 1244 1245 size_t numLayers = hwcContents.numHwLayers; 1246 for (size_t hwc1Id = 0; hwc1Id < numLayers; ++hwc1Id) { 1247 const auto& receivedLayer = hwcContents.hwLayers[hwc1Id]; 1248 if (mHwc1LayerMap.count(hwc1Id) == 0) { 1249 if (receivedLayer.compositionType != HWC_FRAMEBUFFER_TARGET) { 1250 ALOGE("addReleaseFences: HWC1 layer %zd doesn't have a" 1251 " matching HWC2 layer, and isn't the framebuffer" 1252 " target", hwc1Id); 1253 } 1254 // Close the framebuffer target release fence since we will use the 1255 // display retire fence instead 1256 if (receivedLayer.releaseFenceFd != -1) { 1257 close(receivedLayer.releaseFenceFd); 1258 } 1259 continue; 1260 } 1261 1262 Layer& layer = *mHwc1LayerMap[hwc1Id]; 1263 ALOGV("Adding release fence %d to layer %" PRIu64, 1264 receivedLayer.releaseFenceFd, layer.getId()); 1265 layer.addReleaseFence(receivedLayer.releaseFenceFd); 1266 } 1267} 1268 1269static std::string hwc1CompositionString(int32_t type) 1270{ 1271 switch (type) { 1272 case HWC_FRAMEBUFFER: return "Framebuffer"; 1273 case HWC_OVERLAY: return "Overlay"; 1274 case HWC_BACKGROUND: return "Background"; 1275 case HWC_FRAMEBUFFER_TARGET: return "FramebufferTarget"; 1276 case HWC_SIDEBAND: return "Sideband"; 1277 case HWC_CURSOR_OVERLAY: return "CursorOverlay"; 1278 default: 1279 return std::string("Unknown (") + std::to_string(type) + ")"; 1280 } 1281} 1282 1283static std::string hwc1TransformString(int32_t transform) 1284{ 1285 switch (transform) { 1286 case 0: return "None"; 1287 case HWC_TRANSFORM_FLIP_H: return "FlipH"; 1288 case HWC_TRANSFORM_FLIP_V: return "FlipV"; 1289 case HWC_TRANSFORM_ROT_90: return "Rotate90"; 1290 case HWC_TRANSFORM_ROT_180: return "Rotate180"; 1291 case HWC_TRANSFORM_ROT_270: return "Rotate270"; 1292 case HWC_TRANSFORM_FLIP_H_ROT_90: return "FlipHRotate90"; 1293 case HWC_TRANSFORM_FLIP_V_ROT_90: return "FlipVRotate90"; 1294 default: 1295 return std::string("Unknown (") + std::to_string(transform) + ")"; 1296 } 1297} 1298 1299static std::string hwc1BlendModeString(int32_t mode) 1300{ 1301 switch (mode) { 1302 case HWC_BLENDING_NONE: return "None"; 1303 case HWC_BLENDING_PREMULT: return "Premultiplied"; 1304 case HWC_BLENDING_COVERAGE: return "Coverage"; 1305 default: 1306 return std::string("Unknown (") + std::to_string(mode) + ")"; 1307 } 1308} 1309 1310static std::string rectString(hwc_rect_t rect) 1311{ 1312 std::stringstream output; 1313 output << "[" << rect.left << ", " << rect.top << ", "; 1314 output << rect.right << ", " << rect.bottom << "]"; 1315 return output.str(); 1316} 1317 1318static std::string approximateFloatString(float f) 1319{ 1320 if (static_cast<int32_t>(f) == f) { 1321 return std::to_string(static_cast<int32_t>(f)); 1322 } 1323 int32_t truncated = static_cast<int32_t>(f * 10); 1324 bool approximate = (static_cast<float>(truncated) != f * 10); 1325 const size_t BUFFER_SIZE = 32; 1326 char buffer[BUFFER_SIZE] = {}; 1327 auto bytesWritten = snprintf(buffer, BUFFER_SIZE, 1328 "%s%.1f", approximate ? "~" : "", f); 1329 return std::string(buffer, bytesWritten); 1330} 1331 1332static std::string frectString(hwc_frect_t frect) 1333{ 1334 std::stringstream output; 1335 output << "[" << approximateFloatString(frect.left) << ", "; 1336 output << approximateFloatString(frect.top) << ", "; 1337 output << approximateFloatString(frect.right) << ", "; 1338 output << approximateFloatString(frect.bottom) << "]"; 1339 return output.str(); 1340} 1341 1342static std::string colorString(hwc_color_t color) 1343{ 1344 std::stringstream output; 1345 output << "RGBA ["; 1346 output << static_cast<int32_t>(color.r) << ", "; 1347 output << static_cast<int32_t>(color.g) << ", "; 1348 output << static_cast<int32_t>(color.b) << ", "; 1349 output << static_cast<int32_t>(color.a) << "]"; 1350 return output.str(); 1351} 1352 1353static std::string alphaString(float f) 1354{ 1355 const size_t BUFFER_SIZE = 8; 1356 char buffer[BUFFER_SIZE] = {}; 1357 auto bytesWritten = snprintf(buffer, BUFFER_SIZE, "%.3f", f); 1358 return std::string(buffer, bytesWritten); 1359} 1360 1361static std::string to_string(const hwc_layer_1_t& hwcLayer, 1362 int32_t hwc1MinorVersion) 1363{ 1364 const char* fill = " "; 1365 1366 std::stringstream output; 1367 1368 output << " Composition: " << 1369 hwc1CompositionString(hwcLayer.compositionType); 1370 1371 if (hwcLayer.compositionType == HWC_BACKGROUND) { 1372 output << " Color: " << colorString(hwcLayer.backgroundColor) << '\n'; 1373 } else if (hwcLayer.compositionType == HWC_SIDEBAND) { 1374 output << " Stream: " << hwcLayer.sidebandStream << '\n'; 1375 } else { 1376 output << " Buffer: " << hwcLayer.handle << "/" << 1377 hwcLayer.acquireFenceFd << '\n'; 1378 } 1379 1380 output << fill << "Display frame: " << rectString(hwcLayer.displayFrame) << 1381 '\n'; 1382 1383 output << fill << "Source crop: "; 1384 if (hwc1MinorVersion >= 3) { 1385 output << frectString(hwcLayer.sourceCropf) << '\n'; 1386 } else { 1387 output << rectString(hwcLayer.sourceCropi) << '\n'; 1388 } 1389 1390 output << fill << "Transform: " << hwc1TransformString(hwcLayer.transform); 1391 output << " Blend mode: " << hwc1BlendModeString(hwcLayer.blending); 1392 if (hwcLayer.planeAlpha != 0xFF) { 1393 output << " Alpha: " << alphaString(hwcLayer.planeAlpha / 255.0f); 1394 } 1395 output << '\n'; 1396 1397 if (hwcLayer.hints != 0) { 1398 output << fill << "Hints:"; 1399 if ((hwcLayer.hints & HWC_HINT_TRIPLE_BUFFER) != 0) { 1400 output << " TripleBuffer"; 1401 } 1402 if ((hwcLayer.hints & HWC_HINT_CLEAR_FB) != 0) { 1403 output << " ClearFB"; 1404 } 1405 output << '\n'; 1406 } 1407 1408 if (hwcLayer.flags != 0) { 1409 output << fill << "Flags:"; 1410 if ((hwcLayer.flags & HWC_SKIP_LAYER) != 0) { 1411 output << " SkipLayer"; 1412 } 1413 if ((hwcLayer.flags & HWC_IS_CURSOR_LAYER) != 0) { 1414 output << " IsCursorLayer"; 1415 } 1416 output << '\n'; 1417 } 1418 1419 return output.str(); 1420} 1421 1422static std::string to_string(const hwc_display_contents_1_t& hwcContents, 1423 int32_t hwc1MinorVersion) 1424{ 1425 const char* fill = " "; 1426 1427 std::stringstream output; 1428 output << fill << "Geometry changed: " << 1429 ((hwcContents.flags & HWC_GEOMETRY_CHANGED) != 0 ? "Y\n" : "N\n"); 1430 1431 output << fill << hwcContents.numHwLayers << " Layer" << 1432 ((hwcContents.numHwLayers == 1) ? "\n" : "s\n"); 1433 for (size_t layer = 0; layer < hwcContents.numHwLayers; ++layer) { 1434 output << fill << " Layer " << layer; 1435 output << to_string(hwcContents.hwLayers[layer], hwc1MinorVersion); 1436 } 1437 1438 if (hwcContents.outbuf != nullptr) { 1439 output << fill << "Output buffer: " << hwcContents.outbuf << "/" << 1440 hwcContents.outbufAcquireFenceFd << '\n'; 1441 } 1442 1443 return output.str(); 1444} 1445 1446std::string HWC2On1Adapter::Display::dump() const 1447{ 1448 std::unique_lock<std::recursive_mutex> lock(mStateMutex); 1449 1450 std::stringstream output; 1451 1452 output << " Display " << mId << ": "; 1453 output << to_string(mType) << " "; 1454 output << "HWC1 ID: " << mHwc1Id << " "; 1455 output << "Power mode: " << to_string(mPowerMode) << " "; 1456 output << "Vsync: " << to_string(mVsyncEnabled) << '\n'; 1457 1458 output << " " << mConfigs.size() << " Config" << 1459 (mConfigs.size() == 1 ? "" : "s") << " (* Active)\n"; 1460 for (const auto& config : mConfigs) { 1461 if (config == mActiveConfig) { 1462 output << " * " << config->toString(); 1463 } else { 1464 output << " " << config->toString(); 1465 } 1466 } 1467 output << '\n'; 1468 1469 output << " " << mLayers.size() << " Layer" << 1470 (mLayers.size() == 1 ? "" : "s") << '\n'; 1471 for (const auto& layer : mLayers) { 1472 output << layer->dump(); 1473 } 1474 1475 output << " Client target: " << mClientTarget.getBuffer() << '\n'; 1476 1477 if (mOutputBuffer.getBuffer() != nullptr) { 1478 output << " Output buffer: " << mOutputBuffer.getBuffer() << '\n'; 1479 } 1480 1481 if (mHwc1ReceivedContents) { 1482 output << " Last received HWC1 state\n"; 1483 output << to_string(*mHwc1ReceivedContents, mDevice.mHwc1MinorVersion); 1484 } else if (mHwc1RequestedContents) { 1485 output << " Last requested HWC1 state\n"; 1486 output << to_string(*mHwc1RequestedContents, mDevice.mHwc1MinorVersion); 1487 } 1488 1489 return output.str(); 1490} 1491 1492void HWC2On1Adapter::Display::Config::setAttribute(HWC2::Attribute attribute, 1493 int32_t value) 1494{ 1495 mAttributes[attribute] = value; 1496} 1497 1498int32_t HWC2On1Adapter::Display::Config::getAttribute(Attribute attribute) const 1499{ 1500 if (mAttributes.count(attribute) == 0) { 1501 return -1; 1502 } 1503 return mAttributes.at(attribute); 1504} 1505 1506std::string HWC2On1Adapter::Display::Config::toString() const 1507{ 1508 std::string output; 1509 1510 const size_t BUFFER_SIZE = 100; 1511 char buffer[BUFFER_SIZE] = {}; 1512 auto writtenBytes = snprintf(buffer, BUFFER_SIZE, 1513 "[%u] %u x %u", mHwcId, 1514 mAttributes.at(HWC2::Attribute::Width), 1515 mAttributes.at(HWC2::Attribute::Height)); 1516 output.append(buffer, writtenBytes); 1517 1518 if (mAttributes.count(HWC2::Attribute::VsyncPeriod) != 0) { 1519 std::memset(buffer, 0, BUFFER_SIZE); 1520 writtenBytes = snprintf(buffer, BUFFER_SIZE, " @ %.1f Hz", 1521 1e9 / mAttributes.at(HWC2::Attribute::VsyncPeriod)); 1522 output.append(buffer, writtenBytes); 1523 } 1524 1525 if (mAttributes.count(HWC2::Attribute::DpiX) != 0 && 1526 mAttributes.at(HWC2::Attribute::DpiX) != -1) { 1527 std::memset(buffer, 0, BUFFER_SIZE); 1528 writtenBytes = snprintf(buffer, BUFFER_SIZE, 1529 ", DPI: %.1f x %.1f", 1530 mAttributes.at(HWC2::Attribute::DpiX) / 1000.0f, 1531 mAttributes.at(HWC2::Attribute::DpiY) / 1000.0f); 1532 output.append(buffer, writtenBytes); 1533 } 1534 1535 return output; 1536} 1537 1538std::shared_ptr<const HWC2On1Adapter::Display::Config> 1539 HWC2On1Adapter::Display::getConfig(hwc2_config_t configId) const 1540{ 1541 if (configId > mConfigs.size() || !mConfigs[configId]->isOnDisplay(*this)) { 1542 return nullptr; 1543 } 1544 return mConfigs[configId]; 1545} 1546 1547void HWC2On1Adapter::Display::reallocateHwc1Contents() 1548{ 1549 // Allocate an additional layer for the framebuffer target 1550 auto numLayers = mLayers.size() + 1; 1551 size_t size = sizeof(hwc_display_contents_1_t) + 1552 sizeof(hwc_layer_1_t) * numLayers; 1553 ALOGV("[%" PRIu64 "] reallocateHwc1Contents creating %zd layer%s", mId, 1554 numLayers, numLayers != 1 ? "s" : ""); 1555 auto contents = 1556 static_cast<hwc_display_contents_1_t*>(std::calloc(size, 1)); 1557 contents->numHwLayers = numLayers; 1558 mHwc1RequestedContents.reset(contents); 1559} 1560 1561void HWC2On1Adapter::Display::assignHwc1LayerIds() 1562{ 1563 mHwc1LayerMap.clear(); 1564 size_t nextHwc1Id = 0; 1565 for (auto& layer : mLayers) { 1566 mHwc1LayerMap[nextHwc1Id] = layer; 1567 layer->setHwc1Id(nextHwc1Id++); 1568 } 1569} 1570 1571void HWC2On1Adapter::Display::updateTypeChanges(const hwc_layer_1_t& hwc1Layer, 1572 const Layer& layer) 1573{ 1574 auto layerId = layer.getId(); 1575 switch (hwc1Layer.compositionType) { 1576 case HWC_FRAMEBUFFER: 1577 if (layer.getCompositionType() != Composition::Client) { 1578 mChanges->addTypeChange(layerId, Composition::Client); 1579 } 1580 break; 1581 case HWC_OVERLAY: 1582 if (layer.getCompositionType() != Composition::Device) { 1583 mChanges->addTypeChange(layerId, Composition::Device); 1584 } 1585 break; 1586 case HWC_BACKGROUND: 1587 ALOGE_IF(layer.getCompositionType() != Composition::SolidColor, 1588 "updateTypeChanges: HWC1 requested BACKGROUND, but HWC2" 1589 " wasn't expecting SolidColor"); 1590 break; 1591 case HWC_FRAMEBUFFER_TARGET: 1592 // Do nothing, since it shouldn't be modified by HWC1 1593 break; 1594 case HWC_SIDEBAND: 1595 ALOGE_IF(layer.getCompositionType() != Composition::Sideband, 1596 "updateTypeChanges: HWC1 requested SIDEBAND, but HWC2" 1597 " wasn't expecting Sideband"); 1598 break; 1599 case HWC_CURSOR_OVERLAY: 1600 ALOGE_IF(layer.getCompositionType() != Composition::Cursor, 1601 "updateTypeChanges: HWC1 requested CURSOR_OVERLAY, but" 1602 " HWC2 wasn't expecting Cursor"); 1603 break; 1604 } 1605} 1606 1607void HWC2On1Adapter::Display::updateLayerRequests( 1608 const hwc_layer_1_t& hwc1Layer, const Layer& layer) 1609{ 1610 if ((hwc1Layer.hints & HWC_HINT_CLEAR_FB) != 0) { 1611 mChanges->addLayerRequest(layer.getId(), 1612 LayerRequest::ClearClientTarget); 1613 } 1614} 1615 1616void HWC2On1Adapter::Display::prepareFramebufferTarget() 1617{ 1618 // We check that mActiveConfig is valid in Display::prepare 1619 int32_t width = mActiveConfig->getAttribute(Attribute::Width); 1620 int32_t height = mActiveConfig->getAttribute(Attribute::Height); 1621 1622 auto& hwc1Target = mHwc1RequestedContents->hwLayers[mLayers.size()]; 1623 hwc1Target.compositionType = HWC_FRAMEBUFFER_TARGET; 1624 hwc1Target.releaseFenceFd = -1; 1625 hwc1Target.hints = 0; 1626 hwc1Target.flags = 0; 1627 hwc1Target.transform = 0; 1628 hwc1Target.blending = HWC_BLENDING_PREMULT; 1629 if (mDevice.getHwc1MinorVersion() < 3) { 1630 hwc1Target.sourceCropi = {0, 0, width, height}; 1631 } else { 1632 hwc1Target.sourceCropf = {0.0f, 0.0f, static_cast<float>(width), 1633 static_cast<float>(height)}; 1634 } 1635 hwc1Target.displayFrame = {0, 0, width, height}; 1636 hwc1Target.planeAlpha = 255; 1637 hwc1Target.visibleRegionScreen.numRects = 1; 1638 auto rects = static_cast<hwc_rect_t*>(std::malloc(sizeof(hwc_rect_t))); 1639 rects[0].left = 0; 1640 rects[0].top = 0; 1641 rects[0].right = width; 1642 rects[0].bottom = height; 1643 hwc1Target.visibleRegionScreen.rects = rects; 1644 1645 // We will set this to the correct value in set 1646 hwc1Target.acquireFenceFd = -1; 1647} 1648 1649// Layer functions 1650 1651std::atomic<hwc2_layer_t> HWC2On1Adapter::Layer::sNextId(1); 1652 1653HWC2On1Adapter::Layer::Layer(Display& display) 1654 : mId(sNextId++), 1655 mDisplay(display), 1656 mBlendMode(*this, BlendMode::None), 1657 mColor(*this, {0, 0, 0, 0}), 1658 mCompositionType(*this, Composition::Invalid), 1659 mDisplayFrame(*this, {0, 0, -1, -1}), 1660 mPlaneAlpha(*this, 0.0f), 1661 mSidebandStream(*this, nullptr), 1662 mSourceCrop(*this, {0.0f, 0.0f, -1.0f, -1.0f}), 1663 mTransform(*this, Transform::None), 1664 mVisibleRegion(*this, std::vector<hwc_rect_t>()), 1665 mZ(0), 1666 mHwc1Id(0), 1667 mHasUnsupportedPlaneAlpha(false) {} 1668 1669bool HWC2On1Adapter::SortLayersByZ::operator()( 1670 const std::shared_ptr<Layer>& lhs, const std::shared_ptr<Layer>& rhs) 1671{ 1672 return lhs->getZ() < rhs->getZ(); 1673} 1674 1675Error HWC2On1Adapter::Layer::setBuffer(buffer_handle_t buffer, 1676 int32_t acquireFence) 1677{ 1678 ALOGV("Setting acquireFence to %d for layer %" PRIu64, acquireFence, mId); 1679 mBuffer.setBuffer(buffer); 1680 mBuffer.setFence(acquireFence); 1681 return Error::None; 1682} 1683 1684Error HWC2On1Adapter::Layer::setCursorPosition(int32_t x, int32_t y) 1685{ 1686 if (mCompositionType.getValue() != Composition::Cursor) { 1687 return Error::BadLayer; 1688 } 1689 1690 if (mDisplay.hasChanges()) { 1691 return Error::NotValidated; 1692 } 1693 1694 auto displayId = mDisplay.getHwc1Id(); 1695 auto hwc1Device = mDisplay.getDevice().getHwc1Device(); 1696 hwc1Device->setCursorPositionAsync(hwc1Device, displayId, x, y); 1697 return Error::None; 1698} 1699 1700Error HWC2On1Adapter::Layer::setSurfaceDamage(hwc_region_t damage) 1701{ 1702 mSurfaceDamage.resize(damage.numRects); 1703 std::copy_n(damage.rects, damage.numRects, mSurfaceDamage.begin()); 1704 return Error::None; 1705} 1706 1707// Layer state functions 1708 1709Error HWC2On1Adapter::Layer::setBlendMode(BlendMode mode) 1710{ 1711 mBlendMode.setPending(mode); 1712 return Error::None; 1713} 1714 1715Error HWC2On1Adapter::Layer::setColor(hwc_color_t color) 1716{ 1717 mColor.setPending(color); 1718 return Error::None; 1719} 1720 1721Error HWC2On1Adapter::Layer::setCompositionType(Composition type) 1722{ 1723 mCompositionType.setPending(type); 1724 return Error::None; 1725} 1726 1727Error HWC2On1Adapter::Layer::setDisplayFrame(hwc_rect_t frame) 1728{ 1729 mDisplayFrame.setPending(frame); 1730 return Error::None; 1731} 1732 1733Error HWC2On1Adapter::Layer::setPlaneAlpha(float alpha) 1734{ 1735 mPlaneAlpha.setPending(alpha); 1736 return Error::None; 1737} 1738 1739Error HWC2On1Adapter::Layer::setSidebandStream(const native_handle_t* stream) 1740{ 1741 mSidebandStream.setPending(stream); 1742 return Error::None; 1743} 1744 1745Error HWC2On1Adapter::Layer::setSourceCrop(hwc_frect_t crop) 1746{ 1747 mSourceCrop.setPending(crop); 1748 return Error::None; 1749} 1750 1751Error HWC2On1Adapter::Layer::setTransform(Transform transform) 1752{ 1753 mTransform.setPending(transform); 1754 return Error::None; 1755} 1756 1757Error HWC2On1Adapter::Layer::setVisibleRegion(hwc_region_t rawVisible) 1758{ 1759 std::vector<hwc_rect_t> visible(rawVisible.rects, 1760 rawVisible.rects + rawVisible.numRects); 1761 mVisibleRegion.setPending(std::move(visible)); 1762 return Error::None; 1763} 1764 1765Error HWC2On1Adapter::Layer::setZ(uint32_t z) 1766{ 1767 mZ = z; 1768 return Error::None; 1769} 1770 1771void HWC2On1Adapter::Layer::addReleaseFence(int fenceFd) 1772{ 1773 ALOGV("addReleaseFence %d to layer %" PRIu64, fenceFd, mId); 1774 mReleaseFence.add(fenceFd); 1775} 1776 1777const sp<Fence>& HWC2On1Adapter::Layer::getReleaseFence() const 1778{ 1779 return mReleaseFence.get(); 1780} 1781 1782void HWC2On1Adapter::Layer::applyState(hwc_layer_1_t& hwc1Layer, 1783 bool applyAllState) 1784{ 1785 applyCommonState(hwc1Layer, applyAllState); 1786 auto compositionType = mCompositionType.getPendingValue(); 1787 if (compositionType == Composition::SolidColor) { 1788 applySolidColorState(hwc1Layer, applyAllState); 1789 } else if (compositionType == Composition::Sideband) { 1790 applySidebandState(hwc1Layer, applyAllState); 1791 } else { 1792 applyBufferState(hwc1Layer); 1793 } 1794 applyCompositionType(hwc1Layer, applyAllState); 1795} 1796 1797// Layer dump helpers 1798 1799static std::string regionStrings(const std::vector<hwc_rect_t>& visibleRegion, 1800 const std::vector<hwc_rect_t>& surfaceDamage) 1801{ 1802 std::string regions; 1803 regions += " Visible Region"; 1804 regions.resize(40, ' '); 1805 regions += "Surface Damage\n"; 1806 1807 size_t numPrinted = 0; 1808 size_t maxSize = std::max(visibleRegion.size(), surfaceDamage.size()); 1809 while (numPrinted < maxSize) { 1810 std::string line(" "); 1811 if (visibleRegion.empty() && numPrinted == 0) { 1812 line += "None"; 1813 } else if (numPrinted < visibleRegion.size()) { 1814 line += rectString(visibleRegion[numPrinted]); 1815 } 1816 line.resize(40, ' '); 1817 if (surfaceDamage.empty() && numPrinted == 0) { 1818 line += "None"; 1819 } else if (numPrinted < surfaceDamage.size()) { 1820 line += rectString(surfaceDamage[numPrinted]); 1821 } 1822 line += '\n'; 1823 regions += line; 1824 ++numPrinted; 1825 } 1826 return regions; 1827} 1828 1829std::string HWC2On1Adapter::Layer::dump() const 1830{ 1831 std::stringstream output; 1832 const char* fill = " "; 1833 1834 output << fill << to_string(mCompositionType.getPendingValue()); 1835 output << " Layer HWC2/1: " << mId << "/" << mHwc1Id << " "; 1836 output << "Z: " << mZ; 1837 if (mCompositionType.getValue() == HWC2::Composition::SolidColor) { 1838 output << " " << colorString(mColor.getValue()); 1839 } else if (mCompositionType.getValue() == HWC2::Composition::Sideband) { 1840 output << " Handle: " << mSidebandStream.getValue() << '\n'; 1841 } else { 1842 output << " Buffer: " << mBuffer.getBuffer() << "/" << 1843 mBuffer.getFence() << '\n'; 1844 output << fill << " Display frame [LTRB]: " << 1845 rectString(mDisplayFrame.getValue()) << '\n'; 1846 output << fill << " Source crop: " << 1847 frectString(mSourceCrop.getValue()) << '\n'; 1848 output << fill << " Transform: " << to_string(mTransform.getValue()); 1849 output << " Blend mode: " << to_string(mBlendMode.getValue()); 1850 if (mPlaneAlpha.getValue() != 1.0f) { 1851 output << " Alpha: " << 1852 alphaString(mPlaneAlpha.getValue()) << '\n'; 1853 } else { 1854 output << '\n'; 1855 } 1856 output << regionStrings(mVisibleRegion.getValue(), mSurfaceDamage); 1857 } 1858 return output.str(); 1859} 1860 1861static int getHwc1Blending(HWC2::BlendMode blendMode) 1862{ 1863 switch (blendMode) { 1864 case BlendMode::Coverage: return HWC_BLENDING_COVERAGE; 1865 case BlendMode::Premultiplied: return HWC_BLENDING_PREMULT; 1866 default: return HWC_BLENDING_NONE; 1867 } 1868} 1869 1870void HWC2On1Adapter::Layer::applyCommonState(hwc_layer_1_t& hwc1Layer, 1871 bool applyAllState) 1872{ 1873 auto minorVersion = mDisplay.getDevice().getHwc1MinorVersion(); 1874 if (applyAllState || mBlendMode.isDirty()) { 1875 hwc1Layer.blending = getHwc1Blending(mBlendMode.getPendingValue()); 1876 mBlendMode.latch(); 1877 } 1878 if (applyAllState || mDisplayFrame.isDirty()) { 1879 hwc1Layer.displayFrame = mDisplayFrame.getPendingValue(); 1880 mDisplayFrame.latch(); 1881 } 1882 if (applyAllState || mPlaneAlpha.isDirty()) { 1883 auto pendingAlpha = mPlaneAlpha.getPendingValue(); 1884 if (minorVersion < 2) { 1885 mHasUnsupportedPlaneAlpha = pendingAlpha < 1.0f; 1886 } else { 1887 hwc1Layer.planeAlpha = 1888 static_cast<uint8_t>(255.0f * pendingAlpha + 0.5f); 1889 } 1890 mPlaneAlpha.latch(); 1891 } 1892 if (applyAllState || mSourceCrop.isDirty()) { 1893 if (minorVersion < 3) { 1894 auto pending = mSourceCrop.getPendingValue(); 1895 hwc1Layer.sourceCropi.left = 1896 static_cast<int32_t>(std::ceil(pending.left)); 1897 hwc1Layer.sourceCropi.top = 1898 static_cast<int32_t>(std::ceil(pending.top)); 1899 hwc1Layer.sourceCropi.right = 1900 static_cast<int32_t>(std::floor(pending.right)); 1901 hwc1Layer.sourceCropi.bottom = 1902 static_cast<int32_t>(std::floor(pending.bottom)); 1903 } else { 1904 hwc1Layer.sourceCropf = mSourceCrop.getPendingValue(); 1905 } 1906 mSourceCrop.latch(); 1907 } 1908 if (applyAllState || mTransform.isDirty()) { 1909 hwc1Layer.transform = 1910 static_cast<uint32_t>(mTransform.getPendingValue()); 1911 mTransform.latch(); 1912 } 1913 if (applyAllState || mVisibleRegion.isDirty()) { 1914 auto& hwc1VisibleRegion = hwc1Layer.visibleRegionScreen; 1915 1916 std::free(const_cast<hwc_rect_t*>(hwc1VisibleRegion.rects)); 1917 1918 auto pending = mVisibleRegion.getPendingValue(); 1919 hwc_rect_t* newRects = static_cast<hwc_rect_t*>( 1920 std::malloc(sizeof(hwc_rect_t) * pending.size())); 1921 std::copy(pending.begin(), pending.end(), newRects); 1922 hwc1VisibleRegion.rects = const_cast<const hwc_rect_t*>(newRects); 1923 hwc1VisibleRegion.numRects = pending.size(); 1924 mVisibleRegion.latch(); 1925 } 1926} 1927 1928void HWC2On1Adapter::Layer::applySolidColorState(hwc_layer_1_t& hwc1Layer, 1929 bool applyAllState) 1930{ 1931 if (applyAllState || mColor.isDirty()) { 1932 hwc1Layer.backgroundColor = mColor.getPendingValue(); 1933 mColor.latch(); 1934 } 1935} 1936 1937void HWC2On1Adapter::Layer::applySidebandState(hwc_layer_1_t& hwc1Layer, 1938 bool applyAllState) 1939{ 1940 if (applyAllState || mSidebandStream.isDirty()) { 1941 hwc1Layer.sidebandStream = mSidebandStream.getPendingValue(); 1942 mSidebandStream.latch(); 1943 } 1944} 1945 1946void HWC2On1Adapter::Layer::applyBufferState(hwc_layer_1_t& hwc1Layer) 1947{ 1948 hwc1Layer.handle = mBuffer.getBuffer(); 1949 hwc1Layer.acquireFenceFd = mBuffer.getFence(); 1950} 1951 1952void HWC2On1Adapter::Layer::applyCompositionType(hwc_layer_1_t& hwc1Layer, 1953 bool applyAllState) 1954{ 1955 if (mHasUnsupportedPlaneAlpha) { 1956 hwc1Layer.compositionType = HWC_FRAMEBUFFER; 1957 hwc1Layer.flags = HWC_SKIP_LAYER; 1958 return; 1959 } 1960 1961 if (applyAllState || mCompositionType.isDirty()) { 1962 hwc1Layer.flags = 0; 1963 switch (mCompositionType.getPendingValue()) { 1964 case Composition::Client: 1965 hwc1Layer.compositionType = HWC_FRAMEBUFFER; 1966 hwc1Layer.flags |= HWC_SKIP_LAYER; 1967 break; 1968 case Composition::Device: 1969 hwc1Layer.compositionType = HWC_FRAMEBUFFER; 1970 break; 1971 case Composition::SolidColor: 1972 hwc1Layer.compositionType = HWC_BACKGROUND; 1973 break; 1974 case Composition::Cursor: 1975 hwc1Layer.compositionType = HWC_FRAMEBUFFER; 1976 if (mDisplay.getDevice().getHwc1MinorVersion() >= 4) { 1977 hwc1Layer.hints |= HWC_IS_CURSOR_LAYER; 1978 } 1979 break; 1980 case Composition::Sideband: 1981 if (mDisplay.getDevice().getHwc1MinorVersion() < 4) { 1982 hwc1Layer.compositionType = HWC_SIDEBAND; 1983 } else { 1984 hwc1Layer.compositionType = HWC_FRAMEBUFFER; 1985 hwc1Layer.flags |= HWC_SKIP_LAYER; 1986 } 1987 break; 1988 default: 1989 hwc1Layer.compositionType = HWC_FRAMEBUFFER; 1990 hwc1Layer.flags |= HWC_SKIP_LAYER; 1991 break; 1992 } 1993 ALOGV("Layer %" PRIu64 " %s set to %d", mId, 1994 to_string(mCompositionType.getPendingValue()).c_str(), 1995 hwc1Layer.compositionType); 1996 ALOGV_IF(hwc1Layer.flags & HWC_SKIP_LAYER, " and skipping"); 1997 mCompositionType.latch(); 1998 } 1999} 2000 2001// Adapter helpers 2002 2003void HWC2On1Adapter::populateCapabilities() 2004{ 2005 ALOGV("populateCapabilities"); 2006 if (mHwc1MinorVersion >= 3U) { 2007 int supportedTypes = 0; 2008 auto result = mHwc1Device->query(mHwc1Device, 2009 HWC_DISPLAY_TYPES_SUPPORTED, &supportedTypes); 2010 if ((result == 0) && ((supportedTypes & HWC_DISPLAY_VIRTUAL) != 0)) { 2011 ALOGI("Found support for HWC virtual displays"); 2012 mHwc1SupportsVirtualDisplays = true; 2013 } 2014 } 2015 if (mHwc1MinorVersion >= 4U) { 2016 mCapabilities.insert(Capability::SidebandStream); 2017 } 2018} 2019 2020HWC2On1Adapter::Display* HWC2On1Adapter::getDisplay(hwc2_display_t id) 2021{ 2022 std::unique_lock<std::timed_mutex> lock(mStateMutex); 2023 2024 auto display = mDisplays.find(id); 2025 if (display == mDisplays.end()) { 2026 return nullptr; 2027 } 2028 2029 return display->second.get(); 2030} 2031 2032std::tuple<HWC2On1Adapter::Layer*, Error> HWC2On1Adapter::getLayer( 2033 hwc2_display_t displayId, hwc2_layer_t layerId) 2034{ 2035 auto display = getDisplay(displayId); 2036 if (!display) { 2037 return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadDisplay); 2038 } 2039 2040 auto layerEntry = mLayers.find(layerId); 2041 if (layerEntry == mLayers.end()) { 2042 return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadLayer); 2043 } 2044 2045 auto layer = layerEntry->second; 2046 if (layer->getDisplay().getId() != displayId) { 2047 return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadLayer); 2048 } 2049 return std::make_tuple(layer.get(), Error::None); 2050} 2051 2052void HWC2On1Adapter::populatePrimary() 2053{ 2054 ALOGV("populatePrimary"); 2055 2056 std::unique_lock<std::timed_mutex> lock(mStateMutex); 2057 2058 auto display = 2059 std::make_shared<Display>(*this, HWC2::DisplayType::Physical); 2060 mHwc1DisplayMap[HWC_DISPLAY_PRIMARY] = display->getId(); 2061 display->setHwc1Id(HWC_DISPLAY_PRIMARY); 2062 display->populateConfigs(); 2063 mDisplays.emplace(display->getId(), std::move(display)); 2064} 2065 2066bool HWC2On1Adapter::prepareAllDisplays() 2067{ 2068 ATRACE_CALL(); 2069 2070 std::unique_lock<std::timed_mutex> lock(mStateMutex); 2071 2072 for (const auto& displayPair : mDisplays) { 2073 auto& display = displayPair.second; 2074 if (!display->prepare()) { 2075 return false; 2076 } 2077 } 2078 2079 if (mHwc1DisplayMap.count(0) == 0) { 2080 ALOGE("prepareAllDisplays: Unable to find primary HWC1 display"); 2081 return false; 2082 } 2083 2084 // Always push the primary display 2085 std::vector<HWC2On1Adapter::Display::HWC1Contents> requestedContents; 2086 auto primaryDisplayId = mHwc1DisplayMap[HWC_DISPLAY_PRIMARY]; 2087 auto& primaryDisplay = mDisplays[primaryDisplayId]; 2088 auto primaryDisplayContents = primaryDisplay->cloneRequestedContents(); 2089 requestedContents.push_back(std::move(primaryDisplayContents)); 2090 2091 // Push the external display, if present 2092 if (mHwc1DisplayMap.count(HWC_DISPLAY_EXTERNAL) != 0) { 2093 auto externalDisplayId = mHwc1DisplayMap[HWC_DISPLAY_EXTERNAL]; 2094 auto& externalDisplay = mDisplays[externalDisplayId]; 2095 auto externalDisplayContents = 2096 externalDisplay->cloneRequestedContents(); 2097 requestedContents.push_back(std::move(externalDisplayContents)); 2098 } else { 2099 // Even if an external display isn't present, we still need to send 2100 // at least two displays down to HWC1 2101 requestedContents.push_back(nullptr); 2102 } 2103 2104 // Push the hardware virtual display, if supported and present 2105 if (mHwc1MinorVersion >= 3) { 2106 if (mHwc1DisplayMap.count(HWC_DISPLAY_VIRTUAL) != 0) { 2107 auto virtualDisplayId = mHwc1DisplayMap[HWC_DISPLAY_VIRTUAL]; 2108 auto& virtualDisplay = mDisplays[virtualDisplayId]; 2109 auto virtualDisplayContents = 2110 virtualDisplay->cloneRequestedContents(); 2111 requestedContents.push_back(std::move(virtualDisplayContents)); 2112 } else { 2113 requestedContents.push_back(nullptr); 2114 } 2115 } 2116 2117 mHwc1Contents.clear(); 2118 for (auto& displayContents : requestedContents) { 2119 mHwc1Contents.push_back(displayContents.get()); 2120 if (!displayContents) { 2121 continue; 2122 } 2123 2124 ALOGV("Display %zd layers:", mHwc1Contents.size() - 1); 2125 for (size_t l = 0; l < displayContents->numHwLayers; ++l) { 2126 auto& layer = displayContents->hwLayers[l]; 2127 ALOGV(" %zd: %d", l, layer.compositionType); 2128 } 2129 } 2130 2131 ALOGV("Calling HWC1 prepare"); 2132 { 2133 ATRACE_NAME("HWC1 prepare"); 2134 mHwc1Device->prepare(mHwc1Device, mHwc1Contents.size(), 2135 mHwc1Contents.data()); 2136 } 2137 2138 for (size_t c = 0; c < mHwc1Contents.size(); ++c) { 2139 auto& contents = mHwc1Contents[c]; 2140 if (!contents) { 2141 continue; 2142 } 2143 ALOGV("Display %zd layers:", c); 2144 for (size_t l = 0; l < contents->numHwLayers; ++l) { 2145 ALOGV(" %zd: %d", l, contents->hwLayers[l].compositionType); 2146 } 2147 } 2148 2149 // Return the received contents to their respective displays 2150 for (size_t hwc1Id = 0; hwc1Id < mHwc1Contents.size(); ++hwc1Id) { 2151 if (mHwc1Contents[hwc1Id] == nullptr) { 2152 continue; 2153 } 2154 2155 auto displayId = mHwc1DisplayMap[hwc1Id]; 2156 auto& display = mDisplays[displayId]; 2157 display->setReceivedContents(std::move(requestedContents[hwc1Id])); 2158 } 2159 2160 return true; 2161} 2162 2163Error HWC2On1Adapter::setAllDisplays() 2164{ 2165 ATRACE_CALL(); 2166 2167 std::unique_lock<std::timed_mutex> lock(mStateMutex); 2168 2169 // Make sure we're ready to validate 2170 for (size_t hwc1Id = 0; hwc1Id < mHwc1Contents.size(); ++hwc1Id) { 2171 if (mHwc1Contents[hwc1Id] == nullptr) { 2172 continue; 2173 } 2174 2175 auto displayId = mHwc1DisplayMap[hwc1Id]; 2176 auto& display = mDisplays[displayId]; 2177 Error error = display->set(*mHwc1Contents[hwc1Id]); 2178 if (error != Error::None) { 2179 ALOGE("setAllDisplays: Failed to set display %zd: %s", hwc1Id, 2180 to_string(error).c_str()); 2181 return error; 2182 } 2183 } 2184 2185 ALOGV("Calling HWC1 set"); 2186 { 2187 ATRACE_NAME("HWC1 set"); 2188 mHwc1Device->set(mHwc1Device, mHwc1Contents.size(), 2189 mHwc1Contents.data()); 2190 } 2191 2192 // Add retire and release fences 2193 for (size_t hwc1Id = 0; hwc1Id < mHwc1Contents.size(); ++hwc1Id) { 2194 if (mHwc1Contents[hwc1Id] == nullptr) { 2195 continue; 2196 } 2197 2198 auto displayId = mHwc1DisplayMap[hwc1Id]; 2199 auto& display = mDisplays[displayId]; 2200 auto retireFenceFd = mHwc1Contents[hwc1Id]->retireFenceFd; 2201 ALOGV("setAllDisplays: Adding retire fence %d to display %zd", 2202 retireFenceFd, hwc1Id); 2203 display->addRetireFence(mHwc1Contents[hwc1Id]->retireFenceFd); 2204 display->addReleaseFences(*mHwc1Contents[hwc1Id]); 2205 } 2206 2207 return Error::None; 2208} 2209 2210void HWC2On1Adapter::hwc1Invalidate() 2211{ 2212 ALOGV("Received hwc1Invalidate"); 2213 2214 std::unique_lock<std::timed_mutex> lock(mStateMutex); 2215 2216 // If the HWC2-side callback hasn't been registered yet, buffer this until 2217 // it is registered 2218 if (mCallbacks.count(Callback::Refresh) == 0) { 2219 mHasPendingInvalidate = true; 2220 return; 2221 } 2222 2223 const auto& callbackInfo = mCallbacks[Callback::Refresh]; 2224 std::vector<hwc2_display_t> displays; 2225 for (const auto& displayPair : mDisplays) { 2226 displays.emplace_back(displayPair.first); 2227 } 2228 2229 // Call back without the state lock held 2230 lock.unlock(); 2231 2232 auto refresh = reinterpret_cast<HWC2_PFN_REFRESH>(callbackInfo.pointer); 2233 for (auto display : displays) { 2234 refresh(callbackInfo.data, display); 2235 } 2236} 2237 2238void HWC2On1Adapter::hwc1Vsync(int hwc1DisplayId, int64_t timestamp) 2239{ 2240 ALOGV("Received hwc1Vsync(%d, %" PRId64 ")", hwc1DisplayId, timestamp); 2241 2242 std::unique_lock<std::timed_mutex> lock(mStateMutex); 2243 2244 // If the HWC2-side callback hasn't been registered yet, buffer this until 2245 // it is registered 2246 if (mCallbacks.count(Callback::Vsync) == 0) { 2247 mPendingVsyncs.emplace_back(hwc1DisplayId, timestamp); 2248 return; 2249 } 2250 2251 if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) { 2252 ALOGE("hwc1Vsync: Couldn't find display for HWC1 id %d", hwc1DisplayId); 2253 return; 2254 } 2255 2256 const auto& callbackInfo = mCallbacks[Callback::Vsync]; 2257 auto displayId = mHwc1DisplayMap[hwc1DisplayId]; 2258 2259 // Call back without the state lock held 2260 lock.unlock(); 2261 2262 auto vsync = reinterpret_cast<HWC2_PFN_VSYNC>(callbackInfo.pointer); 2263 vsync(callbackInfo.data, displayId, timestamp); 2264} 2265 2266void HWC2On1Adapter::hwc1Hotplug(int hwc1DisplayId, int connected) 2267{ 2268 ALOGV("Received hwc1Hotplug(%d, %d)", hwc1DisplayId, connected); 2269 2270 if (hwc1DisplayId != HWC_DISPLAY_EXTERNAL) { 2271 ALOGE("hwc1Hotplug: Received hotplug for non-external display"); 2272 return; 2273 } 2274 2275 std::unique_lock<std::timed_mutex> lock(mStateMutex); 2276 2277 // If the HWC2-side callback hasn't been registered yet, buffer this until 2278 // it is registered 2279 if (mCallbacks.count(Callback::Hotplug) == 0) { 2280 mPendingHotplugs.emplace_back(hwc1DisplayId, connected); 2281 return; 2282 } 2283 2284 hwc2_display_t displayId = UINT64_MAX; 2285 if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) { 2286 if (connected == 0) { 2287 ALOGW("hwc1Hotplug: Received disconnect for unconnected display"); 2288 return; 2289 } 2290 2291 // Create a new display on connect 2292 auto display = std::make_shared<HWC2On1Adapter::Display>(*this, 2293 HWC2::DisplayType::Physical); 2294 display->setHwc1Id(HWC_DISPLAY_EXTERNAL); 2295 display->populateConfigs(); 2296 displayId = display->getId(); 2297 mHwc1DisplayMap[HWC_DISPLAY_EXTERNAL] = displayId; 2298 mDisplays.emplace(displayId, std::move(display)); 2299 } else { 2300 if (connected != 0) { 2301 ALOGW("hwc1Hotplug: Received connect for previously connected " 2302 "display"); 2303 return; 2304 } 2305 2306 // Disconnect an existing display 2307 displayId = mHwc1DisplayMap[hwc1DisplayId]; 2308 mHwc1DisplayMap.erase(HWC_DISPLAY_EXTERNAL); 2309 mDisplays.erase(displayId); 2310 } 2311 2312 const auto& callbackInfo = mCallbacks[Callback::Hotplug]; 2313 2314 // Call back without the state lock held 2315 lock.unlock(); 2316 2317 auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(callbackInfo.pointer); 2318 auto hwc2Connected = (connected == 0) ? 2319 HWC2::Connection::Disconnected : HWC2::Connection::Connected; 2320 hotplug(callbackInfo.data, displayId, static_cast<int32_t>(hwc2Connected)); 2321} 2322 2323} // namespace android 2324