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