1 /* 2 * Copyright (C) 2010 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 "HWComposer" 21 #define ATRACE_TAG ATRACE_TAG_GRAPHICS 22 23 #include <inttypes.h> 24 #include <math.h> 25 #include <stdint.h> 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <string.h> 29 #include <sys/types.h> 30 31 #include <utils/Errors.h> 32 #include <utils/misc.h> 33 #include <utils/NativeHandle.h> 34 #include <utils/String8.h> 35 #include <utils/Thread.h> 36 #include <utils/Trace.h> 37 #include <utils/Vector.h> 38 39 #include <ui/DebugUtils.h> 40 #include <ui/GraphicBuffer.h> 41 42 #include <hardware/hardware.h> 43 #include <hardware/hwcomposer.h> 44 45 #include <android/configuration.h> 46 47 #include <cutils/properties.h> 48 #include <log/log.h> 49 50 #include "HWComposer.h" 51 #include "HWC2.h" 52 #include "ComposerHal.h" 53 54 #include "../Layer.h" // needed only for debugging 55 #include "../SurfaceFlinger.h" 56 57 #define LOG_DISPLAY_ERROR(displayId, msg) \ 58 ALOGE("%s failed for display %d: %s", __FUNCTION__, displayId, msg) 59 60 #define LOG_HWC_ERROR(what, error, displayId) \ 61 ALOGE("%s: %s failed for display %d: %s (%d)", __FUNCTION__, what, displayId, \ 62 to_string(error).c_str(), static_cast<int32_t>(error)) 63 64 #define RETURN_IF_INVALID_DISPLAY(displayId, ...) \ 65 do { \ 66 if (!isValidDisplay(displayId)) { \ 67 LOG_DISPLAY_ERROR(displayId, "Invalid display"); \ 68 return __VA_ARGS__; \ 69 } \ 70 } while (false) 71 72 #define RETURN_IF_HWC_ERROR_FOR(what, error, displayId, ...) \ 73 do { \ 74 if (error != HWC2::Error::None) { \ 75 LOG_HWC_ERROR(what, error, displayId); \ 76 return __VA_ARGS__; \ 77 } \ 78 } while (false) 79 80 #define RETURN_IF_HWC_ERROR(error, displayId, ...) \ 81 RETURN_IF_HWC_ERROR_FOR(__FUNCTION__, error, displayId, __VA_ARGS__) 82 83 namespace android { 84 85 #define MIN_HWC_HEADER_VERSION HWC_HEADER_VERSION 86 87 // --------------------------------------------------------------------------- 88 89 HWComposer::HWComposer(std::unique_ptr<android::Hwc2::Composer> composer) 90 : mHwcDevice(std::make_unique<HWC2::Device>(std::move(composer))) {} 91 92 HWComposer::~HWComposer() = default; 93 94 void HWComposer::registerCallback(HWC2::ComposerCallback* callback, 95 int32_t sequenceId) { 96 mHwcDevice->registerCallback(callback, sequenceId); 97 } 98 99 bool HWComposer::hasCapability(HWC2::Capability capability) const 100 { 101 return mHwcDevice->getCapabilities().count(capability) > 0; 102 } 103 104 bool HWComposer::isValidDisplay(int32_t displayId) const { 105 return static_cast<size_t>(displayId) < mDisplayData.size() && 106 mDisplayData[displayId].hwcDisplay; 107 } 108 109 void HWComposer::validateChange(HWC2::Composition from, HWC2::Composition to) { 110 bool valid = true; 111 switch (from) { 112 case HWC2::Composition::Client: 113 valid = false; 114 break; 115 case HWC2::Composition::Device: 116 case HWC2::Composition::SolidColor: 117 valid = (to == HWC2::Composition::Client); 118 break; 119 case HWC2::Composition::Cursor: 120 case HWC2::Composition::Sideband: 121 valid = (to == HWC2::Composition::Client || 122 to == HWC2::Composition::Device); 123 break; 124 default: 125 break; 126 } 127 128 if (!valid) { 129 ALOGE("Invalid layer type change: %s --> %s", to_string(from).c_str(), 130 to_string(to).c_str()); 131 } 132 } 133 134 void HWComposer::onHotplug(hwc2_display_t displayId, int32_t displayType, 135 HWC2::Connection connection) { 136 if (displayType >= HWC_NUM_PHYSICAL_DISPLAY_TYPES) { 137 ALOGE("Invalid display type of %d", displayType); 138 return; 139 } 140 141 ALOGV("hotplug: %" PRIu64 ", %s %s", displayId, 142 displayType == DisplayDevice::DISPLAY_PRIMARY ? "primary" : "external", 143 to_string(connection).c_str()); 144 mHwcDevice->onHotplug(displayId, connection); 145 // Disconnect is handled through HWComposer::disconnectDisplay via 146 // SurfaceFlinger's onHotplugReceived callback handling 147 if (connection == HWC2::Connection::Connected) { 148 mDisplayData[displayType].hwcDisplay = mHwcDevice->getDisplayById(displayId); 149 mHwcDisplaySlots[displayId] = displayType; 150 } 151 } 152 153 bool HWComposer::onVsync(hwc2_display_t displayId, int64_t timestamp, 154 int32_t* outDisplay) { 155 auto display = mHwcDevice->getDisplayById(displayId); 156 if (!display) { 157 ALOGE("onVsync Failed to find display %" PRIu64, displayId); 158 return false; 159 } 160 auto displayType = HWC2::DisplayType::Invalid; 161 auto error = display->getType(&displayType); 162 if (error != HWC2::Error::None) { 163 ALOGE("onVsync: Failed to determine type of display %" PRIu64, 164 display->getId()); 165 return false; 166 } 167 168 if (displayType == HWC2::DisplayType::Virtual) { 169 ALOGE("Virtual display %" PRIu64 " passed to vsync callback", 170 display->getId()); 171 return false; 172 } 173 174 if (mHwcDisplaySlots.count(display->getId()) == 0) { 175 ALOGE("Unknown physical display %" PRIu64 " passed to vsync callback", 176 display->getId()); 177 return false; 178 } 179 180 int32_t disp = mHwcDisplaySlots[display->getId()]; 181 { 182 Mutex::Autolock _l(mLock); 183 184 // There have been reports of HWCs that signal several vsync events 185 // with the same timestamp when turning the display off and on. This 186 // is a bug in the HWC implementation, but filter the extra events 187 // out here so they don't cause havoc downstream. 188 if (timestamp == mLastHwVSync[disp]) { 189 ALOGW("Ignoring duplicate VSYNC event from HWC (t=%" PRId64 ")", 190 timestamp); 191 return false; 192 } 193 194 mLastHwVSync[disp] = timestamp; 195 } 196 197 if (outDisplay) { 198 *outDisplay = disp; 199 } 200 201 char tag[16]; 202 snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", disp); 203 ATRACE_INT(tag, ++mVSyncCounts[disp] & 1); 204 205 return true; 206 } 207 208 status_t HWComposer::allocateVirtualDisplay(uint32_t width, uint32_t height, 209 ui::PixelFormat* format, int32_t *outId) { 210 if (mRemainingHwcVirtualDisplays == 0) { 211 ALOGE("allocateVirtualDisplay: No remaining virtual displays"); 212 return NO_MEMORY; 213 } 214 215 if (SurfaceFlinger::maxVirtualDisplaySize != 0 && 216 (width > SurfaceFlinger::maxVirtualDisplaySize || 217 height > SurfaceFlinger::maxVirtualDisplaySize)) { 218 ALOGE("createVirtualDisplay: Can't create a virtual display with" 219 " a dimension > %" PRIu64 " (tried %u x %u)", 220 SurfaceFlinger::maxVirtualDisplaySize, width, height); 221 return INVALID_OPERATION; 222 } 223 224 HWC2::Display* display; 225 auto error = mHwcDevice->createVirtualDisplay(width, height, format, 226 &display); 227 if (error != HWC2::Error::None) { 228 ALOGE("allocateVirtualDisplay: Failed to create HWC virtual display"); 229 return NO_MEMORY; 230 } 231 232 size_t displaySlot = 0; 233 if (!mFreeDisplaySlots.empty()) { 234 displaySlot = *mFreeDisplaySlots.begin(); 235 mFreeDisplaySlots.erase(displaySlot); 236 } else if (mDisplayData.size() < INT32_MAX) { 237 // Don't bother allocating a slot larger than we can return 238 displaySlot = mDisplayData.size(); 239 mDisplayData.resize(displaySlot + 1); 240 } else { 241 ALOGE("allocateVirtualDisplay: Unable to allocate a display slot"); 242 return NO_MEMORY; 243 } 244 245 mDisplayData[displaySlot].hwcDisplay = display; 246 247 --mRemainingHwcVirtualDisplays; 248 *outId = static_cast<int32_t>(displaySlot); 249 250 return NO_ERROR; 251 } 252 253 HWC2::Layer* HWComposer::createLayer(int32_t displayId) { 254 RETURN_IF_INVALID_DISPLAY(displayId, nullptr); 255 256 auto display = mDisplayData[displayId].hwcDisplay; 257 HWC2::Layer* layer; 258 auto error = display->createLayer(&layer); 259 RETURN_IF_HWC_ERROR(error, displayId, nullptr); 260 return layer; 261 } 262 263 void HWComposer::destroyLayer(int32_t displayId, HWC2::Layer* layer) { 264 RETURN_IF_INVALID_DISPLAY(displayId); 265 266 auto display = mDisplayData[displayId].hwcDisplay; 267 auto error = display->destroyLayer(layer); 268 RETURN_IF_HWC_ERROR(error, displayId); 269 } 270 271 nsecs_t HWComposer::getRefreshTimestamp(int32_t displayId) const { 272 // this returns the last refresh timestamp. 273 // if the last one is not available, we estimate it based on 274 // the refresh period and whatever closest timestamp we have. 275 Mutex::Autolock _l(mLock); 276 nsecs_t now = systemTime(CLOCK_MONOTONIC); 277 auto vsyncPeriod = getActiveConfig(displayId)->getVsyncPeriod(); 278 return now - ((now - mLastHwVSync[displayId]) % vsyncPeriod); 279 } 280 281 bool HWComposer::isConnected(int32_t displayId) const { 282 RETURN_IF_INVALID_DISPLAY(displayId, false); 283 return mDisplayData[displayId].hwcDisplay->isConnected(); 284 } 285 286 std::vector<std::shared_ptr<const HWC2::Display::Config>> 287 HWComposer::getConfigs(int32_t displayId) const { 288 RETURN_IF_INVALID_DISPLAY(displayId, {}); 289 290 auto& displayData = mDisplayData[displayId]; 291 auto configs = mDisplayData[displayId].hwcDisplay->getConfigs(); 292 if (displayData.configMap.empty()) { 293 for (size_t i = 0; i < configs.size(); ++i) { 294 displayData.configMap[i] = configs[i]; 295 } 296 } 297 return configs; 298 } 299 300 std::shared_ptr<const HWC2::Display::Config> 301 HWComposer::getActiveConfig(int32_t displayId) const { 302 RETURN_IF_INVALID_DISPLAY(displayId, nullptr); 303 304 std::shared_ptr<const HWC2::Display::Config> config; 305 auto error = mDisplayData[displayId].hwcDisplay->getActiveConfig(&config); 306 if (error == HWC2::Error::BadConfig) { 307 LOG_DISPLAY_ERROR(displayId, "No active config"); 308 return nullptr; 309 } 310 311 RETURN_IF_HWC_ERROR(error, displayId, nullptr); 312 313 if (!config) { 314 LOG_DISPLAY_ERROR(displayId, "Unknown config"); 315 return nullptr; 316 } 317 318 return config; 319 } 320 321 int HWComposer::getActiveConfigIndex(int32_t displayId) const { 322 if (!isValidDisplay(displayId)) { 323 ALOGV("getActiveConfigIndex: Attempted to access invalid display %d", displayId); 324 return -1; 325 } 326 int index; 327 auto error = mDisplayData[displayId].hwcDisplay->getActiveConfigIndex(&index); 328 if (error == HWC2::Error::BadConfig) { 329 ALOGE("getActiveConfigIndex: No config active, returning -1"); 330 return -1; 331 } else if (error != HWC2::Error::None) { 332 ALOGE("getActiveConfigIndex failed for display %d: %s (%d)", displayId, 333 to_string(error).c_str(), static_cast<int32_t>(error)); 334 return -1; 335 } else if (index < 0) { 336 ALOGE("getActiveConfigIndex returned an unknown config for display %d", displayId); 337 return -1; 338 } 339 340 return index; 341 } 342 343 std::vector<ui::ColorMode> HWComposer::getColorModes(int32_t displayId) const { 344 RETURN_IF_INVALID_DISPLAY(displayId, {}); 345 346 std::vector<ui::ColorMode> modes; 347 auto error = mDisplayData[displayId].hwcDisplay->getColorModes(&modes); 348 RETURN_IF_HWC_ERROR(error, displayId, {}); 349 return modes; 350 } 351 352 status_t HWComposer::setActiveColorMode(int32_t displayId, ui::ColorMode mode, 353 ui::RenderIntent renderIntent) { 354 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); 355 356 auto& displayData = mDisplayData[displayId]; 357 auto error = displayData.hwcDisplay->setColorMode(mode, renderIntent); 358 RETURN_IF_HWC_ERROR_FOR(("setColorMode(" + decodeColorMode(mode) + ", " + 359 decodeRenderIntent(renderIntent) + ")") 360 .c_str(), 361 error, displayId, UNKNOWN_ERROR); 362 363 return NO_ERROR; 364 } 365 366 367 void HWComposer::setVsyncEnabled(int32_t displayId, HWC2::Vsync enabled) { 368 if (displayId < 0 || displayId >= HWC_DISPLAY_VIRTUAL) { 369 ALOGD("setVsyncEnabled: Ignoring for virtual display %d", displayId); 370 return; 371 } 372 373 RETURN_IF_INVALID_DISPLAY(displayId); 374 375 // NOTE: we use our own internal lock here because we have to call 376 // into the HWC with the lock held, and we want to make sure 377 // that even if HWC blocks (which it shouldn't), it won't 378 // affect other threads. 379 Mutex::Autolock _l(mVsyncLock); 380 auto& displayData = mDisplayData[displayId]; 381 if (enabled != displayData.vsyncEnabled) { 382 ATRACE_CALL(); 383 auto error = displayData.hwcDisplay->setVsyncEnabled(enabled); 384 RETURN_IF_HWC_ERROR(error, displayId); 385 386 displayData.vsyncEnabled = enabled; 387 388 char tag[16]; 389 snprintf(tag, sizeof(tag), "HW_VSYNC_ON_%1u", displayId); 390 ATRACE_INT(tag, enabled == HWC2::Vsync::Enable ? 1 : 0); 391 } 392 } 393 394 status_t HWComposer::setClientTarget(int32_t displayId, uint32_t slot, 395 const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target, 396 ui::Dataspace dataspace) { 397 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); 398 399 ALOGV("setClientTarget for display %d", displayId); 400 auto& hwcDisplay = mDisplayData[displayId].hwcDisplay; 401 auto error = hwcDisplay->setClientTarget(slot, target, acquireFence, dataspace); 402 RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE); 403 return NO_ERROR; 404 } 405 406 status_t HWComposer::prepare(DisplayDevice& displayDevice) { 407 ATRACE_CALL(); 408 409 Mutex::Autolock _l(mDisplayLock); 410 auto displayId = displayDevice.getHwcDisplayId(); 411 if (displayId == DisplayDevice::DISPLAY_ID_INVALID) { 412 ALOGV("Skipping HWComposer prepare for non-HWC display"); 413 return NO_ERROR; 414 } 415 416 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); 417 418 auto& displayData = mDisplayData[displayId]; 419 auto& hwcDisplay = displayData.hwcDisplay; 420 if (!hwcDisplay->isConnected()) { 421 return NO_ERROR; 422 } 423 424 uint32_t numTypes = 0; 425 uint32_t numRequests = 0; 426 427 HWC2::Error error = HWC2::Error::None; 428 429 // First try to skip validate altogether when there is no client 430 // composition. When there is client composition, since we haven't 431 // rendered to the client target yet, we should not attempt to skip 432 // validate. 433 // 434 // displayData.hasClientComposition hasn't been updated for this frame. 435 // The check below is incorrect. We actually rely on HWC here to fall 436 // back to validate when there is any client layer. 437 displayData.validateWasSkipped = false; 438 if (!displayData.hasClientComposition) { 439 sp<android::Fence> outPresentFence; 440 uint32_t state = UINT32_MAX; 441 error = hwcDisplay->presentOrValidate(&numTypes, &numRequests, &outPresentFence , &state); 442 if (error != HWC2::Error::HasChanges) { 443 RETURN_IF_HWC_ERROR_FOR("presentOrValidate", error, displayId, UNKNOWN_ERROR); 444 } 445 if (state == 1) { //Present Succeeded. 446 std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences; 447 error = hwcDisplay->getReleaseFences(&releaseFences); 448 displayData.releaseFences = std::move(releaseFences); 449 displayData.lastPresentFence = outPresentFence; 450 displayData.validateWasSkipped = true; 451 displayData.presentError = error; 452 return NO_ERROR; 453 } 454 // Present failed but Validate ran. 455 } else { 456 error = hwcDisplay->validate(&numTypes, &numRequests); 457 } 458 ALOGV("SkipValidate failed, Falling back to SLOW validate/present"); 459 if (error != HWC2::Error::HasChanges) { 460 RETURN_IF_HWC_ERROR_FOR("validate", error, displayId, BAD_INDEX); 461 } 462 463 std::unordered_map<HWC2::Layer*, HWC2::Composition> changedTypes; 464 changedTypes.reserve(numTypes); 465 error = hwcDisplay->getChangedCompositionTypes(&changedTypes); 466 RETURN_IF_HWC_ERROR_FOR("getChangedCompositionTypes", error, displayId, BAD_INDEX); 467 468 displayData.displayRequests = static_cast<HWC2::DisplayRequest>(0); 469 std::unordered_map<HWC2::Layer*, HWC2::LayerRequest> layerRequests; 470 layerRequests.reserve(numRequests); 471 error = hwcDisplay->getRequests(&displayData.displayRequests, 472 &layerRequests); 473 RETURN_IF_HWC_ERROR_FOR("getRequests", error, displayId, BAD_INDEX); 474 475 displayData.hasClientComposition = false; 476 displayData.hasDeviceComposition = false; 477 for (auto& layer : displayDevice.getVisibleLayersSortedByZ()) { 478 auto hwcLayer = layer->getHwcLayer(displayId); 479 480 if (changedTypes.count(hwcLayer) != 0) { 481 // We pass false so we only update our state and don't call back 482 // into the HWC device 483 validateChange(layer->getCompositionType(displayId), 484 changedTypes[hwcLayer]); 485 layer->setCompositionType(displayId, changedTypes[hwcLayer], false); 486 } 487 488 switch (layer->getCompositionType(displayId)) { 489 case HWC2::Composition::Client: 490 displayData.hasClientComposition = true; 491 break; 492 case HWC2::Composition::Device: 493 case HWC2::Composition::SolidColor: 494 case HWC2::Composition::Cursor: 495 case HWC2::Composition::Sideband: 496 displayData.hasDeviceComposition = true; 497 break; 498 default: 499 break; 500 } 501 502 if (layerRequests.count(hwcLayer) != 0 && 503 layerRequests[hwcLayer] == 504 HWC2::LayerRequest::ClearClientTarget) { 505 layer->setClearClientTarget(displayId, true); 506 } else { 507 if (layerRequests.count(hwcLayer) != 0) { 508 LOG_DISPLAY_ERROR(displayId, 509 ("Unknown layer request " + to_string(layerRequests[hwcLayer])) 510 .c_str()); 511 } 512 layer->setClearClientTarget(displayId, false); 513 } 514 } 515 516 error = hwcDisplay->acceptChanges(); 517 RETURN_IF_HWC_ERROR_FOR("acceptChanges", error, displayId, BAD_INDEX); 518 519 return NO_ERROR; 520 } 521 522 bool HWComposer::hasDeviceComposition(int32_t displayId) const { 523 if (displayId == DisplayDevice::DISPLAY_ID_INVALID) { 524 // Displays without a corresponding HWC display are never composed by 525 // the device 526 return false; 527 } 528 529 RETURN_IF_INVALID_DISPLAY(displayId, false); 530 return mDisplayData[displayId].hasDeviceComposition; 531 } 532 533 bool HWComposer::hasFlipClientTargetRequest(int32_t displayId) const { 534 if (displayId == DisplayDevice::DISPLAY_ID_INVALID) { 535 // Displays without a corresponding HWC display are never composed by 536 // the device 537 return false; 538 } 539 540 RETURN_IF_INVALID_DISPLAY(displayId, false); 541 return ((static_cast<uint32_t>(mDisplayData[displayId].displayRequests) & 542 static_cast<uint32_t>(HWC2::DisplayRequest::FlipClientTarget)) != 0); 543 } 544 545 bool HWComposer::hasClientComposition(int32_t displayId) const { 546 if (displayId == DisplayDevice::DISPLAY_ID_INVALID) { 547 // Displays without a corresponding HWC display are always composed by 548 // the client 549 return true; 550 } 551 552 RETURN_IF_INVALID_DISPLAY(displayId, true); 553 return mDisplayData[displayId].hasClientComposition; 554 } 555 556 sp<Fence> HWComposer::getPresentFence(int32_t displayId) const { 557 RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE); 558 return mDisplayData[displayId].lastPresentFence; 559 } 560 561 sp<Fence> HWComposer::getLayerReleaseFence(int32_t displayId, 562 HWC2::Layer* layer) const { 563 RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE); 564 auto displayFences = mDisplayData[displayId].releaseFences; 565 if (displayFences.count(layer) == 0) { 566 ALOGV("getLayerReleaseFence: Release fence not found"); 567 return Fence::NO_FENCE; 568 } 569 return displayFences[layer]; 570 } 571 572 status_t HWComposer::presentAndGetReleaseFences(int32_t displayId) { 573 ATRACE_CALL(); 574 575 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); 576 577 auto& displayData = mDisplayData[displayId]; 578 auto& hwcDisplay = displayData.hwcDisplay; 579 580 if (displayData.validateWasSkipped) { 581 // explicitly flush all pending commands 582 auto error = mHwcDevice->flushCommands(); 583 RETURN_IF_HWC_ERROR_FOR("flushCommands", error, displayId, UNKNOWN_ERROR); 584 RETURN_IF_HWC_ERROR_FOR("present", displayData.presentError, displayId, UNKNOWN_ERROR); 585 return NO_ERROR; 586 } 587 588 auto error = hwcDisplay->present(&displayData.lastPresentFence); 589 RETURN_IF_HWC_ERROR_FOR("present", error, displayId, UNKNOWN_ERROR); 590 591 std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences; 592 error = hwcDisplay->getReleaseFences(&releaseFences); 593 RETURN_IF_HWC_ERROR_FOR("getReleaseFences", error, displayId, UNKNOWN_ERROR); 594 595 displayData.releaseFences = std::move(releaseFences); 596 597 return NO_ERROR; 598 } 599 600 status_t HWComposer::setPowerMode(int32_t displayId, int32_t intMode) { 601 ALOGV("setPowerMode(%d, %d)", displayId, intMode); 602 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); 603 604 if (displayId >= VIRTUAL_DISPLAY_ID_BASE) { 605 LOG_DISPLAY_ERROR(displayId, "Invalid operation on virtual display"); 606 return INVALID_OPERATION; 607 } 608 609 auto mode = static_cast<HWC2::PowerMode>(intMode); 610 if (mode == HWC2::PowerMode::Off) { 611 setVsyncEnabled(displayId, HWC2::Vsync::Disable); 612 } 613 614 auto& hwcDisplay = mDisplayData[displayId].hwcDisplay; 615 switch (mode) { 616 case HWC2::PowerMode::Off: 617 case HWC2::PowerMode::On: 618 ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str()); 619 { 620 auto error = hwcDisplay->setPowerMode(mode); 621 if (error != HWC2::Error::None) { 622 LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(), 623 error, displayId); 624 } 625 } 626 break; 627 case HWC2::PowerMode::Doze: 628 case HWC2::PowerMode::DozeSuspend: 629 ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str()); 630 { 631 bool supportsDoze = false; 632 auto error = hwcDisplay->supportsDoze(&supportsDoze); 633 if (error != HWC2::Error::None) { 634 LOG_HWC_ERROR("supportsDoze", error, displayId); 635 } 636 637 if (!supportsDoze) { 638 mode = HWC2::PowerMode::On; 639 } 640 641 error = hwcDisplay->setPowerMode(mode); 642 if (error != HWC2::Error::None) { 643 LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(), 644 error, displayId); 645 } 646 } 647 break; 648 default: 649 ALOGV("setPowerMode: Not calling HWC"); 650 break; 651 } 652 653 return NO_ERROR; 654 } 655 656 status_t HWComposer::setActiveConfig(int32_t displayId, size_t configId) { 657 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); 658 659 auto& displayData = mDisplayData[displayId]; 660 if (displayData.configMap.count(configId) == 0) { 661 LOG_DISPLAY_ERROR(displayId, ("Invalid config " + std::to_string(configId)).c_str()); 662 return BAD_INDEX; 663 } 664 665 auto error = displayData.hwcDisplay->setActiveConfig(displayData.configMap[configId]); 666 RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR); 667 return NO_ERROR; 668 } 669 670 status_t HWComposer::setColorTransform(int32_t displayId, 671 const mat4& transform) { 672 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); 673 674 auto& displayData = mDisplayData[displayId]; 675 bool isIdentity = transform == mat4(); 676 auto error = displayData.hwcDisplay->setColorTransform(transform, 677 isIdentity ? HAL_COLOR_TRANSFORM_IDENTITY : 678 HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX); 679 RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR); 680 return NO_ERROR; 681 } 682 683 void HWComposer::disconnectDisplay(int displayId) { 684 LOG_ALWAYS_FATAL_IF(displayId < 0); 685 auto& displayData = mDisplayData[displayId]; 686 687 auto displayType = HWC2::DisplayType::Invalid; 688 auto error = displayData.hwcDisplay->getType(&displayType); 689 RETURN_IF_HWC_ERROR_FOR("getType", error, displayId); 690 691 // If this was a virtual display, add its slot back for reuse by future 692 // virtual displays 693 if (displayType == HWC2::DisplayType::Virtual) { 694 mFreeDisplaySlots.insert(displayId); 695 ++mRemainingHwcVirtualDisplays; 696 } 697 698 auto hwcId = displayData.hwcDisplay->getId(); 699 mHwcDisplaySlots.erase(hwcId); 700 displayData.reset(); 701 702 mHwcDevice->destroyDisplay(hwcId); 703 } 704 705 status_t HWComposer::setOutputBuffer(int32_t displayId, 706 const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buffer) { 707 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); 708 709 auto& hwcDisplay = mDisplayData[displayId].hwcDisplay; 710 auto displayType = HWC2::DisplayType::Invalid; 711 auto error = hwcDisplay->getType(&displayType); 712 RETURN_IF_HWC_ERROR_FOR("getType", error, displayId, NAME_NOT_FOUND); 713 714 if (displayType != HWC2::DisplayType::Virtual) { 715 LOG_DISPLAY_ERROR(displayId, "Invalid operation on physical display"); 716 return INVALID_OPERATION; 717 } 718 719 error = hwcDisplay->setOutputBuffer(buffer, acquireFence); 720 RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR); 721 return NO_ERROR; 722 } 723 724 void HWComposer::clearReleaseFences(int32_t displayId) { 725 RETURN_IF_INVALID_DISPLAY(displayId); 726 mDisplayData[displayId].releaseFences.clear(); 727 } 728 729 status_t HWComposer::getHdrCapabilities( 730 int32_t displayId, HdrCapabilities* outCapabilities) { 731 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); 732 733 auto& hwcDisplay = mDisplayData[displayId].hwcDisplay; 734 auto error = hwcDisplay->getHdrCapabilities(outCapabilities); 735 RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR); 736 return NO_ERROR; 737 } 738 739 int32_t HWComposer::getSupportedPerFrameMetadata(int32_t displayId) const { 740 RETURN_IF_INVALID_DISPLAY(displayId, 0); 741 742 int32_t supportedMetadata; 743 auto error = mDisplayData[displayId].hwcDisplay->getSupportedPerFrameMetadata( 744 &supportedMetadata); 745 RETURN_IF_HWC_ERROR(error, displayId, 0); 746 return supportedMetadata; 747 } 748 749 std::vector<ui::RenderIntent> HWComposer::getRenderIntents(int32_t displayId, 750 ui::ColorMode colorMode) const { 751 RETURN_IF_INVALID_DISPLAY(displayId, {}); 752 753 std::vector<ui::RenderIntent> renderIntents; 754 auto error = mDisplayData[displayId].hwcDisplay->getRenderIntents(colorMode, &renderIntents); 755 RETURN_IF_HWC_ERROR(error, displayId, {}); 756 return renderIntents; 757 } 758 759 mat4 HWComposer::getDataspaceSaturationMatrix(int32_t displayId, ui::Dataspace dataspace) { 760 RETURN_IF_INVALID_DISPLAY(displayId, {}); 761 762 mat4 matrix; 763 auto error = mDisplayData[displayId].hwcDisplay->getDataspaceSaturationMatrix(dataspace, 764 &matrix); 765 RETURN_IF_HWC_ERROR(error, displayId, {}); 766 return matrix; 767 } 768 769 // Converts a PixelFormat to a human-readable string. Max 11 chars. 770 // (Could use a table of prefab String8 objects.) 771 /* 772 static String8 getFormatStr(PixelFormat format) { 773 switch (format) { 774 case PIXEL_FORMAT_RGBA_8888: return String8("RGBA_8888"); 775 case PIXEL_FORMAT_RGBX_8888: return String8("RGBx_8888"); 776 case PIXEL_FORMAT_RGB_888: return String8("RGB_888"); 777 case PIXEL_FORMAT_RGB_565: return String8("RGB_565"); 778 case PIXEL_FORMAT_BGRA_8888: return String8("BGRA_8888"); 779 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: 780 return String8("ImplDef"); 781 default: 782 String8 result; 783 result.appendFormat("? %08x", format); 784 return result; 785 } 786 } 787 */ 788 789 bool HWComposer::isUsingVrComposer() const { 790 return getComposer()->isUsingVrComposer(); 791 } 792 793 void HWComposer::dump(String8& result) const { 794 // TODO: In order to provide a dump equivalent to HWC1, we need to shadow 795 // all the state going into the layers. This is probably better done in 796 // Layer itself, but it's going to take a bit of work to get there. 797 result.append(mHwcDevice->dump().c_str()); 798 } 799 800 std::optional<hwc2_display_t> 801 HWComposer::getHwcDisplayId(int32_t displayId) const { 802 if (!isValidDisplay(displayId)) { 803 return {}; 804 } 805 return mDisplayData[displayId].hwcDisplay->getId(); 806 } 807 808 // --------------------------------------------------------------------------- 809 810 HWComposer::DisplayData::DisplayData() 811 : hasClientComposition(false), 812 hasDeviceComposition(false), 813 hwcDisplay(nullptr), 814 lastPresentFence(Fence::NO_FENCE), 815 outbufHandle(nullptr), 816 outbufAcquireFence(Fence::NO_FENCE), 817 vsyncEnabled(HWC2::Vsync::Disable) { 818 ALOGV("Created new DisplayData"); 819 } 820 821 HWComposer::DisplayData::~DisplayData() { 822 } 823 824 void HWComposer::DisplayData::reset() { 825 ALOGV("DisplayData reset"); 826 *this = DisplayData(); 827 } 828 829 // --------------------------------------------------------------------------- 830 }; // namespace android 831