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