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