HWComposer.cpp revision 56a9e5d33ce9a60f042288ef8b62952d44ffec4c
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 83namespace android { 84 85#define MIN_HWC_HEADER_VERSION HWC_HEADER_VERSION 86 87// --------------------------------------------------------------------------- 88 89HWComposer::HWComposer(std::unique_ptr<android::Hwc2::Composer> composer) 90 : mHwcDevice(std::make_unique<HWC2::Device>(std::move(composer))) {} 91 92HWComposer::~HWComposer() = default; 93 94void HWComposer::registerCallback(HWC2::ComposerCallback* callback, 95 int32_t sequenceId) { 96 mHwcDevice->registerCallback(callback, sequenceId); 97} 98 99bool HWComposer::hasCapability(HWC2::Capability capability) const 100{ 101 return mHwcDevice->getCapabilities().count(capability) > 0; 102} 103 104bool HWComposer::isValidDisplay(int32_t displayId) const { 105 return static_cast<size_t>(displayId) < mDisplayData.size() && 106 mDisplayData[displayId].hwcDisplay; 107} 108 109void 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 134void 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 153bool 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 208status_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 253HWC2::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 263void 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 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 RETURN_IF_INVALID_DISPLAY(displayId, false); 283 return mDisplayData[displayId].hwcDisplay->isConnected(); 284} 285 286std::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 300std::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 321std::vector<ui::ColorMode> HWComposer::getColorModes(int32_t displayId) const { 322 RETURN_IF_INVALID_DISPLAY(displayId, {}); 323 324 std::vector<ui::ColorMode> modes; 325 auto error = mDisplayData[displayId].hwcDisplay->getColorModes(&modes); 326 RETURN_IF_HWC_ERROR(error, displayId, {}); 327 return modes; 328} 329 330status_t HWComposer::setActiveColorMode(int32_t displayId, ui::ColorMode mode, 331 ui::RenderIntent renderIntent) { 332 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); 333 334 auto& displayData = mDisplayData[displayId]; 335 auto error = displayData.hwcDisplay->setColorMode(mode, renderIntent); 336 RETURN_IF_HWC_ERROR_FOR(("setColorMode(" + decodeColorMode(mode) + ", " + 337 decodeRenderIntent(renderIntent) + ")") 338 .c_str(), 339 error, displayId, UNKNOWN_ERROR); 340 341 return NO_ERROR; 342} 343 344 345void HWComposer::setVsyncEnabled(int32_t displayId, HWC2::Vsync enabled) { 346 if (displayId < 0 || displayId >= HWC_DISPLAY_VIRTUAL) { 347 ALOGD("setVsyncEnabled: Ignoring for virtual display %d", displayId); 348 return; 349 } 350 351 RETURN_IF_INVALID_DISPLAY(displayId); 352 353 // NOTE: we use our own internal lock here because we have to call 354 // into the HWC with the lock held, and we want to make sure 355 // that even if HWC blocks (which it shouldn't), it won't 356 // affect other threads. 357 Mutex::Autolock _l(mVsyncLock); 358 auto& displayData = mDisplayData[displayId]; 359 if (enabled != displayData.vsyncEnabled) { 360 ATRACE_CALL(); 361 auto error = displayData.hwcDisplay->setVsyncEnabled(enabled); 362 RETURN_IF_HWC_ERROR(error, displayId); 363 364 displayData.vsyncEnabled = enabled; 365 366 char tag[16]; 367 snprintf(tag, sizeof(tag), "HW_VSYNC_ON_%1u", displayId); 368 ATRACE_INT(tag, enabled == HWC2::Vsync::Enable ? 1 : 0); 369 } 370} 371 372status_t HWComposer::setClientTarget(int32_t displayId, uint32_t slot, 373 const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target, 374 ui::Dataspace dataspace) { 375 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); 376 377 ALOGV("setClientTarget for display %d", displayId); 378 auto& hwcDisplay = mDisplayData[displayId].hwcDisplay; 379 auto error = hwcDisplay->setClientTarget(slot, target, acquireFence, dataspace); 380 RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE); 381 return NO_ERROR; 382} 383 384status_t HWComposer::prepare(DisplayDevice& displayDevice) { 385 ATRACE_CALL(); 386 387 Mutex::Autolock _l(mDisplayLock); 388 auto displayId = displayDevice.getHwcDisplayId(); 389 if (displayId == DisplayDevice::DISPLAY_ID_INVALID) { 390 ALOGV("Skipping HWComposer prepare for non-HWC display"); 391 return NO_ERROR; 392 } 393 394 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); 395 396 auto& displayData = mDisplayData[displayId]; 397 auto& hwcDisplay = displayData.hwcDisplay; 398 if (!hwcDisplay->isConnected()) { 399 return NO_ERROR; 400 } 401 402 uint32_t numTypes = 0; 403 uint32_t numRequests = 0; 404 405 HWC2::Error error = HWC2::Error::None; 406 407 // First try to skip validate altogether when there is no client 408 // composition. When there is client composition, since we haven't 409 // rendered to the client target yet, we should not attempt to skip 410 // validate. 411 // 412 // displayData.hasClientComposition hasn't been updated for this frame. 413 // The check below is incorrect. We actually rely on HWC here to fall 414 // back to validate when there is any client layer. 415 displayData.validateWasSkipped = false; 416 if (!displayData.hasClientComposition) { 417 sp<android::Fence> outPresentFence; 418 uint32_t state = UINT32_MAX; 419 error = hwcDisplay->presentOrValidate(&numTypes, &numRequests, &outPresentFence , &state); 420 if (error != HWC2::Error::HasChanges) { 421 RETURN_IF_HWC_ERROR_FOR("presentOrValidate", error, displayId, UNKNOWN_ERROR); 422 } 423 if (state == 1) { //Present Succeeded. 424 std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences; 425 error = hwcDisplay->getReleaseFences(&releaseFences); 426 displayData.releaseFences = std::move(releaseFences); 427 displayData.lastPresentFence = outPresentFence; 428 displayData.validateWasSkipped = true; 429 displayData.presentError = error; 430 return NO_ERROR; 431 } 432 // Present failed but Validate ran. 433 } else { 434 error = hwcDisplay->validate(&numTypes, &numRequests); 435 } 436 ALOGV("SkipValidate failed, Falling back to SLOW validate/present"); 437 if (error != HWC2::Error::HasChanges) { 438 RETURN_IF_HWC_ERROR_FOR("validate", error, displayId, BAD_INDEX); 439 } 440 441 std::unordered_map<HWC2::Layer*, HWC2::Composition> changedTypes; 442 changedTypes.reserve(numTypes); 443 error = hwcDisplay->getChangedCompositionTypes(&changedTypes); 444 RETURN_IF_HWC_ERROR_FOR("getChangedCompositionTypes", error, displayId, BAD_INDEX); 445 446 displayData.displayRequests = static_cast<HWC2::DisplayRequest>(0); 447 std::unordered_map<HWC2::Layer*, HWC2::LayerRequest> layerRequests; 448 layerRequests.reserve(numRequests); 449 error = hwcDisplay->getRequests(&displayData.displayRequests, 450 &layerRequests); 451 RETURN_IF_HWC_ERROR_FOR("getRequests", error, displayId, BAD_INDEX); 452 453 displayData.hasClientComposition = false; 454 displayData.hasDeviceComposition = false; 455 for (auto& layer : displayDevice.getVisibleLayersSortedByZ()) { 456 auto hwcLayer = layer->getHwcLayer(displayId); 457 458 if (changedTypes.count(hwcLayer) != 0) { 459 // We pass false so we only update our state and don't call back 460 // into the HWC device 461 validateChange(layer->getCompositionType(displayId), 462 changedTypes[hwcLayer]); 463 layer->setCompositionType(displayId, changedTypes[hwcLayer], false); 464 } 465 466 switch (layer->getCompositionType(displayId)) { 467 case HWC2::Composition::Client: 468 displayData.hasClientComposition = true; 469 break; 470 case HWC2::Composition::Device: 471 case HWC2::Composition::SolidColor: 472 case HWC2::Composition::Cursor: 473 case HWC2::Composition::Sideband: 474 displayData.hasDeviceComposition = true; 475 break; 476 default: 477 break; 478 } 479 480 if (layerRequests.count(hwcLayer) != 0 && 481 layerRequests[hwcLayer] == 482 HWC2::LayerRequest::ClearClientTarget) { 483 layer->setClearClientTarget(displayId, true); 484 } else { 485 if (layerRequests.count(hwcLayer) != 0) { 486 LOG_DISPLAY_ERROR(displayId, 487 ("Unknown layer request " + to_string(layerRequests[hwcLayer])) 488 .c_str()); 489 } 490 layer->setClearClientTarget(displayId, false); 491 } 492 } 493 494 error = hwcDisplay->acceptChanges(); 495 RETURN_IF_HWC_ERROR_FOR("acceptChanges", error, displayId, BAD_INDEX); 496 497 return NO_ERROR; 498} 499 500bool HWComposer::hasDeviceComposition(int32_t displayId) const { 501 if (displayId == DisplayDevice::DISPLAY_ID_INVALID) { 502 // Displays without a corresponding HWC display are never composed by 503 // the device 504 return false; 505 } 506 507 RETURN_IF_INVALID_DISPLAY(displayId, false); 508 return mDisplayData[displayId].hasDeviceComposition; 509} 510 511bool HWComposer::hasFlipClientTargetRequest(int32_t displayId) const { 512 if (displayId == DisplayDevice::DISPLAY_ID_INVALID) { 513 // Displays without a corresponding HWC display are never composed by 514 // the device 515 return false; 516 } 517 518 RETURN_IF_INVALID_DISPLAY(displayId, false); 519 return ((static_cast<uint32_t>(mDisplayData[displayId].displayRequests) & 520 static_cast<uint32_t>(HWC2::DisplayRequest::FlipClientTarget)) != 0); 521} 522 523bool HWComposer::hasClientComposition(int32_t displayId) const { 524 if (displayId == DisplayDevice::DISPLAY_ID_INVALID) { 525 // Displays without a corresponding HWC display are always composed by 526 // the client 527 return true; 528 } 529 530 RETURN_IF_INVALID_DISPLAY(displayId, true); 531 return mDisplayData[displayId].hasClientComposition; 532} 533 534sp<Fence> HWComposer::getPresentFence(int32_t displayId) const { 535 RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE); 536 return mDisplayData[displayId].lastPresentFence; 537} 538 539sp<Fence> HWComposer::getLayerReleaseFence(int32_t displayId, 540 HWC2::Layer* layer) const { 541 RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE); 542 auto displayFences = mDisplayData[displayId].releaseFences; 543 if (displayFences.count(layer) == 0) { 544 ALOGV("getLayerReleaseFence: Release fence not found"); 545 return Fence::NO_FENCE; 546 } 547 return displayFences[layer]; 548} 549 550status_t HWComposer::presentAndGetReleaseFences(int32_t displayId) { 551 ATRACE_CALL(); 552 553 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); 554 555 auto& displayData = mDisplayData[displayId]; 556 auto& hwcDisplay = displayData.hwcDisplay; 557 558 if (displayData.validateWasSkipped) { 559 // explicitly flush all pending commands 560 auto error = mHwcDevice->flushCommands(); 561 RETURN_IF_HWC_ERROR_FOR("flushCommands", error, displayId, UNKNOWN_ERROR); 562 RETURN_IF_HWC_ERROR_FOR("present", displayData.presentError, displayId, UNKNOWN_ERROR); 563 return NO_ERROR; 564 } 565 566 auto error = hwcDisplay->present(&displayData.lastPresentFence); 567 RETURN_IF_HWC_ERROR_FOR("present", error, displayId, UNKNOWN_ERROR); 568 569 std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences; 570 error = hwcDisplay->getReleaseFences(&releaseFences); 571 RETURN_IF_HWC_ERROR_FOR("getReleaseFences", error, displayId, UNKNOWN_ERROR); 572 573 displayData.releaseFences = std::move(releaseFences); 574 575 return NO_ERROR; 576} 577 578status_t HWComposer::setPowerMode(int32_t displayId, int32_t intMode) { 579 ALOGV("setPowerMode(%d, %d)", displayId, intMode); 580 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); 581 582 if (displayId >= VIRTUAL_DISPLAY_ID_BASE) { 583 LOG_DISPLAY_ERROR(displayId, "Invalid operation on virtual display"); 584 return INVALID_OPERATION; 585 } 586 587 auto mode = static_cast<HWC2::PowerMode>(intMode); 588 if (mode == HWC2::PowerMode::Off) { 589 setVsyncEnabled(displayId, HWC2::Vsync::Disable); 590 } 591 592 auto& hwcDisplay = mDisplayData[displayId].hwcDisplay; 593 switch (mode) { 594 case HWC2::PowerMode::Off: 595 case HWC2::PowerMode::On: 596 ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str()); 597 { 598 auto error = hwcDisplay->setPowerMode(mode); 599 LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(), error, displayId); 600 } 601 break; 602 case HWC2::PowerMode::Doze: 603 case HWC2::PowerMode::DozeSuspend: 604 ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str()); 605 { 606 bool supportsDoze = false; 607 auto error = hwcDisplay->supportsDoze(&supportsDoze); 608 LOG_HWC_ERROR("supportsDoze", error, displayId); 609 610 if (!supportsDoze) { 611 mode = HWC2::PowerMode::On; 612 } 613 614 error = hwcDisplay->setPowerMode(mode); 615 LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(), error, displayId); 616 } 617 break; 618 default: 619 ALOGV("setPowerMode: Not calling HWC"); 620 break; 621 } 622 623 return NO_ERROR; 624} 625 626status_t HWComposer::setActiveConfig(int32_t displayId, size_t configId) { 627 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); 628 629 auto& displayData = mDisplayData[displayId]; 630 if (displayData.configMap.count(configId) == 0) { 631 LOG_DISPLAY_ERROR(displayId, ("Invalid config " + std::to_string(configId)).c_str()); 632 return BAD_INDEX; 633 } 634 635 auto error = displayData.hwcDisplay->setActiveConfig(displayData.configMap[configId]); 636 RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR); 637 return NO_ERROR; 638} 639 640status_t HWComposer::setColorTransform(int32_t displayId, 641 const mat4& transform) { 642 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); 643 644 auto& displayData = mDisplayData[displayId]; 645 bool isIdentity = transform == mat4(); 646 auto error = displayData.hwcDisplay->setColorTransform(transform, 647 isIdentity ? HAL_COLOR_TRANSFORM_IDENTITY : 648 HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX); 649 RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR); 650 return NO_ERROR; 651} 652 653void HWComposer::disconnectDisplay(int displayId) { 654 LOG_ALWAYS_FATAL_IF(displayId < 0); 655 auto& displayData = mDisplayData[displayId]; 656 657 auto displayType = HWC2::DisplayType::Invalid; 658 auto error = displayData.hwcDisplay->getType(&displayType); 659 RETURN_IF_HWC_ERROR_FOR("getType", error, displayId); 660 661 // If this was a virtual display, add its slot back for reuse by future 662 // virtual displays 663 if (displayType == HWC2::DisplayType::Virtual) { 664 mFreeDisplaySlots.insert(displayId); 665 ++mRemainingHwcVirtualDisplays; 666 } 667 668 auto hwcId = displayData.hwcDisplay->getId(); 669 mHwcDisplaySlots.erase(hwcId); 670 displayData.reset(); 671 672 mHwcDevice->destroyDisplay(hwcId); 673} 674 675status_t HWComposer::setOutputBuffer(int32_t displayId, 676 const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buffer) { 677 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); 678 679 auto& hwcDisplay = mDisplayData[displayId].hwcDisplay; 680 auto displayType = HWC2::DisplayType::Invalid; 681 auto error = hwcDisplay->getType(&displayType); 682 RETURN_IF_HWC_ERROR_FOR("getType", error, displayId, NAME_NOT_FOUND); 683 684 if (displayType != HWC2::DisplayType::Virtual) { 685 LOG_DISPLAY_ERROR(displayId, "Invalid operation on physical display"); 686 return INVALID_OPERATION; 687 } 688 689 error = hwcDisplay->setOutputBuffer(buffer, acquireFence); 690 RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR); 691 return NO_ERROR; 692} 693 694void HWComposer::clearReleaseFences(int32_t displayId) { 695 RETURN_IF_INVALID_DISPLAY(displayId); 696 mDisplayData[displayId].releaseFences.clear(); 697} 698 699status_t HWComposer::getHdrCapabilities( 700 int32_t displayId, HdrCapabilities* outCapabilities) { 701 RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX); 702 703 auto& hwcDisplay = mDisplayData[displayId].hwcDisplay; 704 auto error = hwcDisplay->getHdrCapabilities(outCapabilities); 705 RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR); 706 return NO_ERROR; 707} 708 709int32_t HWComposer::getSupportedPerFrameMetadata(int32_t displayId) const { 710 RETURN_IF_INVALID_DISPLAY(displayId, 0); 711 712 int32_t supportedMetadata; 713 auto error = mDisplayData[displayId].hwcDisplay->getSupportedPerFrameMetadata( 714 &supportedMetadata); 715 RETURN_IF_HWC_ERROR(error, displayId, 0); 716 return supportedMetadata; 717} 718 719std::vector<ui::RenderIntent> HWComposer::getRenderIntents(int32_t displayId, 720 ui::ColorMode colorMode) const { 721 RETURN_IF_INVALID_DISPLAY(displayId, {}); 722 723 std::vector<ui::RenderIntent> renderIntents; 724 auto error = mDisplayData[displayId].hwcDisplay->getRenderIntents(colorMode, &renderIntents); 725 RETURN_IF_HWC_ERROR(error, displayId, {}); 726 return renderIntents; 727} 728 729mat4 HWComposer::getDataspaceSaturationMatrix(int32_t displayId, ui::Dataspace dataspace) { 730 RETURN_IF_INVALID_DISPLAY(displayId, {}); 731 732 mat4 matrix; 733 auto error = mDisplayData[displayId].hwcDisplay->getDataspaceSaturationMatrix(dataspace, 734 &matrix); 735 RETURN_IF_HWC_ERROR(error, displayId, {}); 736 return matrix; 737} 738 739// Converts a PixelFormat to a human-readable string. Max 11 chars. 740// (Could use a table of prefab String8 objects.) 741/* 742static String8 getFormatStr(PixelFormat format) { 743 switch (format) { 744 case PIXEL_FORMAT_RGBA_8888: return String8("RGBA_8888"); 745 case PIXEL_FORMAT_RGBX_8888: return String8("RGBx_8888"); 746 case PIXEL_FORMAT_RGB_888: return String8("RGB_888"); 747 case PIXEL_FORMAT_RGB_565: return String8("RGB_565"); 748 case PIXEL_FORMAT_BGRA_8888: return String8("BGRA_8888"); 749 case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: 750 return String8("ImplDef"); 751 default: 752 String8 result; 753 result.appendFormat("? %08x", format); 754 return result; 755 } 756} 757*/ 758 759bool HWComposer::isUsingVrComposer() const { 760 return getComposer()->isUsingVrComposer(); 761} 762 763void HWComposer::dump(String8& result) const { 764 // TODO: In order to provide a dump equivalent to HWC1, we need to shadow 765 // all the state going into the layers. This is probably better done in 766 // Layer itself, but it's going to take a bit of work to get there. 767 result.append(mHwcDevice->dump().c_str()); 768} 769 770std::optional<hwc2_display_t> 771HWComposer::getHwcDisplayId(int32_t displayId) const { 772 if (!isValidDisplay(displayId)) { 773 return {}; 774 } 775 return mDisplayData[displayId].hwcDisplay->getId(); 776} 777 778// --------------------------------------------------------------------------- 779 780HWComposer::DisplayData::DisplayData() 781 : hasClientComposition(false), 782 hasDeviceComposition(false), 783 hwcDisplay(nullptr), 784 lastPresentFence(Fence::NO_FENCE), 785 outbufHandle(nullptr), 786 outbufAcquireFence(Fence::NO_FENCE), 787 vsyncEnabled(HWC2::Vsync::Disable) { 788 ALOGV("Created new DisplayData"); 789} 790 791HWComposer::DisplayData::~DisplayData() { 792} 793 794void HWComposer::DisplayData::reset() { 795 ALOGV("DisplayData reset"); 796 *this = DisplayData(); 797} 798 799// --------------------------------------------------------------------------- 800}; // namespace android 801