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