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