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