Home | History | Annotate | Download | only in DisplayHardware
      1 /*
      2  * Copyright 2015 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 "HWC2"
     21 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
     22 
     23 #include "HWC2.h"
     24 #include "ComposerHal.h"
     25 
     26 #include <ui/Fence.h>
     27 #include <ui/FloatRect.h>
     28 #include <ui/GraphicBuffer.h>
     29 #include <ui/Region.h>
     30 
     31 #include <android/configuration.h>
     32 
     33 #include <algorithm>
     34 #include <inttypes.h>
     35 
     36 extern "C" {
     37     static void hotplug_hook(hwc2_callback_data_t callbackData,
     38             hwc2_display_t displayId, int32_t intConnected) {
     39         auto device = static_cast<HWC2::Device*>(callbackData);
     40         auto display = device->getDisplayById(displayId);
     41         if (display) {
     42             auto connected = static_cast<HWC2::Connection>(intConnected);
     43             device->callHotplug(std::move(display), connected);
     44         } else {
     45             ALOGE("Hotplug callback called with unknown display %" PRIu64,
     46                     displayId);
     47         }
     48     }
     49 
     50     static void refresh_hook(hwc2_callback_data_t callbackData,
     51             hwc2_display_t displayId) {
     52         auto device = static_cast<HWC2::Device*>(callbackData);
     53         auto display = device->getDisplayById(displayId);
     54         if (display) {
     55             device->callRefresh(std::move(display));
     56         } else {
     57             ALOGE("Refresh callback called with unknown display %" PRIu64,
     58                     displayId);
     59         }
     60     }
     61 
     62     static void vsync_hook(hwc2_callback_data_t callbackData,
     63             hwc2_display_t displayId, int64_t timestamp) {
     64         auto device = static_cast<HWC2::Device*>(callbackData);
     65         auto display = device->getDisplayById(displayId);
     66         if (display) {
     67             device->callVsync(std::move(display), timestamp);
     68         } else {
     69             ALOGE("Vsync callback called with unknown display %" PRIu64,
     70                     displayId);
     71         }
     72     }
     73 }
     74 
     75 using android::Fence;
     76 using android::FloatRect;
     77 using android::GraphicBuffer;
     78 using android::HdrCapabilities;
     79 using android::Rect;
     80 using android::Region;
     81 using android::sp;
     82 using android::hardware::Return;
     83 using android::hardware::Void;
     84 
     85 namespace HWC2 {
     86 
     87 namespace Hwc2 = android::Hwc2;
     88 
     89 // Device methods
     90 
     91 Device::Device(bool useVrComposer)
     92   : mComposer(std::make_unique<Hwc2::Composer>(useVrComposer)),
     93     mCapabilities(),
     94     mDisplays(),
     95     mHotplug(),
     96     mPendingHotplugs(),
     97     mRefresh(),
     98     mPendingRefreshes(),
     99     mVsync(),
    100     mPendingVsyncs()
    101 {
    102     loadCapabilities();
    103     registerCallbacks();
    104 }
    105 
    106 Device::~Device()
    107 {
    108     for (auto element : mDisplays) {
    109         auto display = element.second.lock();
    110         if (!display) {
    111             ALOGE("~Device: Found a display (%" PRId64 " that has already been"
    112                     " destroyed", element.first);
    113             continue;
    114         }
    115 
    116         DisplayType displayType = HWC2::DisplayType::Invalid;
    117         auto error = display->getType(&displayType);
    118         if (error != Error::None) {
    119             ALOGE("~Device: Failed to determine type of display %" PRIu64
    120                     ": %s (%d)", display->getId(), to_string(error).c_str(),
    121                     static_cast<int32_t>(error));
    122             continue;
    123         }
    124 
    125         if (displayType == HWC2::DisplayType::Physical) {
    126             error = display->setVsyncEnabled(HWC2::Vsync::Disable);
    127             if (error != Error::None) {
    128                 ALOGE("~Device: Failed to disable vsync for display %" PRIu64
    129                         ": %s (%d)", display->getId(), to_string(error).c_str(),
    130                         static_cast<int32_t>(error));
    131             }
    132         }
    133     }
    134 }
    135 
    136 // Required by HWC2 device
    137 
    138 std::string Device::dump() const
    139 {
    140     return mComposer->dumpDebugInfo();
    141 }
    142 
    143 uint32_t Device::getMaxVirtualDisplayCount() const
    144 {
    145     return mComposer->getMaxVirtualDisplayCount();
    146 }
    147 
    148 Error Device::createVirtualDisplay(uint32_t width, uint32_t height,
    149         android_pixel_format_t* format, std::shared_ptr<Display>* outDisplay)
    150 {
    151     ALOGI("Creating virtual display");
    152 
    153     hwc2_display_t displayId = 0;
    154     auto intFormat = static_cast<Hwc2::PixelFormat>(*format);
    155     auto intError = mComposer->createVirtualDisplay(width, height,
    156             &intFormat, &displayId);
    157     auto error = static_cast<Error>(intError);
    158     if (error != Error::None) {
    159         return error;
    160     }
    161 
    162     ALOGI("Created virtual display");
    163     *format = static_cast<android_pixel_format_t>(intFormat);
    164     *outDisplay = getDisplayById(displayId);
    165     if (!*outDisplay) {
    166         ALOGE("Failed to get display by id");
    167         return Error::BadDisplay;
    168     }
    169     (*outDisplay)->setConnected(true);
    170     return Error::None;
    171 }
    172 
    173 void Device::registerHotplugCallback(HotplugCallback hotplug)
    174 {
    175     ALOGV("registerHotplugCallback");
    176     mHotplug = hotplug;
    177     for (auto& pending : mPendingHotplugs) {
    178         auto& display = pending.first;
    179         auto connected = pending.second;
    180         ALOGV("Sending pending hotplug(%" PRIu64 ", %s)", display->getId(),
    181                 to_string(connected).c_str());
    182         mHotplug(std::move(display), connected);
    183     }
    184 }
    185 
    186 void Device::registerRefreshCallback(RefreshCallback refresh)
    187 {
    188     mRefresh = refresh;
    189     for (auto& pending : mPendingRefreshes) {
    190         mRefresh(std::move(pending));
    191     }
    192 }
    193 
    194 void Device::registerVsyncCallback(VsyncCallback vsync)
    195 {
    196     mVsync = vsync;
    197     for (auto& pending : mPendingVsyncs) {
    198         auto& display = pending.first;
    199         auto timestamp = pending.second;
    200         mVsync(std::move(display), timestamp);
    201     }
    202 }
    203 
    204 // For use by Device callbacks
    205 
    206 void Device::callHotplug(std::shared_ptr<Display> display, Connection connected)
    207 {
    208     if (connected == Connection::Connected) {
    209         if (!display->isConnected()) {
    210             mComposer->setClientTargetSlotCount(display->getId());
    211             display->loadConfigs();
    212             display->setConnected(true);
    213         }
    214     } else {
    215         display->setConnected(false);
    216         mDisplays.erase(display->getId());
    217     }
    218 
    219     if (mHotplug) {
    220         mHotplug(std::move(display), connected);
    221     } else {
    222         ALOGV("callHotplug called, but no valid callback registered, storing");
    223         mPendingHotplugs.emplace_back(std::move(display), connected);
    224     }
    225 }
    226 
    227 void Device::callRefresh(std::shared_ptr<Display> display)
    228 {
    229     if (mRefresh) {
    230         mRefresh(std::move(display));
    231     } else {
    232         ALOGV("callRefresh called, but no valid callback registered, storing");
    233         mPendingRefreshes.emplace_back(std::move(display));
    234     }
    235 }
    236 
    237 void Device::callVsync(std::shared_ptr<Display> display, nsecs_t timestamp)
    238 {
    239     if (mVsync) {
    240         mVsync(std::move(display), timestamp);
    241     } else {
    242         ALOGV("callVsync called, but no valid callback registered, storing");
    243         mPendingVsyncs.emplace_back(std::move(display), timestamp);
    244     }
    245 }
    246 
    247 // Other Device methods
    248 
    249 std::shared_ptr<Display> Device::getDisplayById(hwc2_display_t id) {
    250     if (mDisplays.count(id) != 0) {
    251         auto strongDisplay = mDisplays[id].lock();
    252         ALOGE_IF(!strongDisplay, "Display %" PRId64 " is in mDisplays but is no"
    253                 " longer alive", id);
    254         return strongDisplay;
    255     }
    256 
    257     auto display = std::make_shared<Display>(*this, id);
    258     mDisplays.emplace(id, display);
    259     return display;
    260 }
    261 
    262 // Device initialization methods
    263 
    264 void Device::loadCapabilities()
    265 {
    266     static_assert(sizeof(Capability) == sizeof(int32_t),
    267             "Capability size has changed");
    268     auto capabilities = mComposer->getCapabilities();
    269     for (auto capability : capabilities) {
    270         mCapabilities.emplace(static_cast<Capability>(capability));
    271     }
    272 }
    273 
    274 bool Device::hasCapability(HWC2::Capability capability) const
    275 {
    276     return std::find(mCapabilities.cbegin(), mCapabilities.cend(),
    277             capability) != mCapabilities.cend();
    278 }
    279 
    280 namespace {
    281 class ComposerCallback : public Hwc2::IComposerCallback {
    282 public:
    283     ComposerCallback(Device* device) : mDevice(device) {}
    284 
    285     Return<void> onHotplug(Hwc2::Display display,
    286             Connection connected) override
    287     {
    288         hotplug_hook(mDevice, display, static_cast<int32_t>(connected));
    289         return Void();
    290     }
    291 
    292     Return<void> onRefresh(Hwc2::Display display) override
    293     {
    294         refresh_hook(mDevice, display);
    295         return Void();
    296     }
    297 
    298     Return<void> onVsync(Hwc2::Display display, int64_t timestamp) override
    299     {
    300         vsync_hook(mDevice, display, timestamp);
    301         return Void();
    302     }
    303 
    304 private:
    305     Device* mDevice;
    306 };
    307 } // namespace anonymous
    308 
    309 void Device::registerCallbacks()
    310 {
    311     sp<ComposerCallback> callback = new ComposerCallback(this);
    312     mComposer->registerCallback(callback);
    313 }
    314 
    315 
    316 // For use by Display
    317 
    318 void Device::destroyVirtualDisplay(hwc2_display_t display)
    319 {
    320     ALOGI("Destroying virtual display");
    321     auto intError = mComposer->destroyVirtualDisplay(display);
    322     auto error = static_cast<Error>(intError);
    323     ALOGE_IF(error != Error::None, "destroyVirtualDisplay(%" PRIu64 ") failed:"
    324             " %s (%d)", display, to_string(error).c_str(), intError);
    325     mDisplays.erase(display);
    326 }
    327 
    328 // Display methods
    329 
    330 Display::Display(Device& device, hwc2_display_t id)
    331   : mDevice(device),
    332     mId(id),
    333     mIsConnected(false),
    334     mType(DisplayType::Invalid)
    335 {
    336     ALOGV("Created display %" PRIu64, id);
    337 
    338     auto intError = mDevice.mComposer->getDisplayType(mId,
    339             reinterpret_cast<Hwc2::IComposerClient::DisplayType *>(&mType));
    340     auto error = static_cast<Error>(intError);
    341     if (error != Error::None) {
    342         ALOGE("getDisplayType(%" PRIu64 ") failed: %s (%d)",
    343               id, to_string(error).c_str(), intError);
    344     }
    345 }
    346 
    347 Display::~Display()
    348 {
    349     ALOGV("Destroyed display %" PRIu64, mId);
    350     if (mType == DisplayType::Virtual) {
    351         mDevice.destroyVirtualDisplay(mId);
    352     }
    353 }
    354 
    355 Display::Config::Config(Display& display, hwc2_config_t id)
    356   : mDisplay(display),
    357     mId(id),
    358     mWidth(-1),
    359     mHeight(-1),
    360     mVsyncPeriod(-1),
    361     mDpiX(-1),
    362     mDpiY(-1) {}
    363 
    364 Display::Config::Builder::Builder(Display& display, hwc2_config_t id)
    365   : mConfig(new Config(display, id)) {}
    366 
    367 float Display::Config::Builder::getDefaultDensity() {
    368     // Default density is based on TVs: 1080p displays get XHIGH density, lower-
    369     // resolution displays get TV density. Maybe eventually we'll need to update
    370     // it for 4k displays, though hopefully those will just report accurate DPI
    371     // information to begin with. This is also used for virtual displays and
    372     // older HWC implementations, so be careful about orientation.
    373 
    374     auto longDimension = std::max(mConfig->mWidth, mConfig->mHeight);
    375     if (longDimension >= 1080) {
    376         return ACONFIGURATION_DENSITY_XHIGH;
    377     } else {
    378         return ACONFIGURATION_DENSITY_TV;
    379     }
    380 }
    381 
    382 // Required by HWC2 display
    383 
    384 Error Display::acceptChanges()
    385 {
    386     auto intError = mDevice.mComposer->acceptDisplayChanges(mId);
    387     return static_cast<Error>(intError);
    388 }
    389 
    390 Error Display::createLayer(std::shared_ptr<Layer>* outLayer)
    391 {
    392     hwc2_layer_t layerId = 0;
    393     auto intError = mDevice.mComposer->createLayer(mId, &layerId);
    394     auto error = static_cast<Error>(intError);
    395     if (error != Error::None) {
    396         return error;
    397     }
    398 
    399     auto layer = std::make_shared<Layer>(shared_from_this(), layerId);
    400     mLayers.emplace(layerId, layer);
    401     *outLayer = std::move(layer);
    402     return Error::None;
    403 }
    404 
    405 Error Display::getActiveConfig(
    406         std::shared_ptr<const Display::Config>* outConfig) const
    407 {
    408     ALOGV("[%" PRIu64 "] getActiveConfig", mId);
    409     hwc2_config_t configId = 0;
    410     auto intError = mDevice.mComposer->getActiveConfig(mId, &configId);
    411     auto error = static_cast<Error>(intError);
    412 
    413     if (error != Error::None) {
    414         ALOGE("Unable to get active config for mId:[%" PRIu64 "]", mId);
    415         *outConfig = nullptr;
    416         return error;
    417     }
    418 
    419     if (mConfigs.count(configId) != 0) {
    420         *outConfig = mConfigs.at(configId);
    421     } else {
    422         ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId,
    423                 configId);
    424         // Return no error, but the caller needs to check for a null pointer to
    425         // detect this case
    426         *outConfig = nullptr;
    427     }
    428 
    429     return Error::None;
    430 }
    431 
    432 Error Display::getChangedCompositionTypes(
    433         std::unordered_map<std::shared_ptr<Layer>, Composition>* outTypes)
    434 {
    435     std::vector<Hwc2::Layer> layerIds;
    436     std::vector<Hwc2::IComposerClient::Composition> types;
    437     auto intError = mDevice.mComposer->getChangedCompositionTypes(mId,
    438             &layerIds, &types);
    439     uint32_t numElements = layerIds.size();
    440     auto error = static_cast<Error>(intError);
    441     error = static_cast<Error>(intError);
    442     if (error != Error::None) {
    443         return error;
    444     }
    445 
    446     outTypes->clear();
    447     outTypes->reserve(numElements);
    448     for (uint32_t element = 0; element < numElements; ++element) {
    449         auto layer = getLayerById(layerIds[element]);
    450         if (layer) {
    451             auto type = static_cast<Composition>(types[element]);
    452             ALOGV("getChangedCompositionTypes: adding %" PRIu64 " %s",
    453                     layer->getId(), to_string(type).c_str());
    454             outTypes->emplace(layer, type);
    455         } else {
    456             ALOGE("getChangedCompositionTypes: invalid layer %" PRIu64 " found"
    457                     " on display %" PRIu64, layerIds[element], mId);
    458         }
    459     }
    460 
    461     return Error::None;
    462 }
    463 
    464 Error Display::getColorModes(std::vector<android_color_mode_t>* outModes) const
    465 {
    466     std::vector<Hwc2::ColorMode> modes;
    467     auto intError = mDevice.mComposer->getColorModes(mId, &modes);
    468     uint32_t numModes = modes.size();
    469     auto error = static_cast<Error>(intError);
    470     if (error != Error::None) {
    471         return error;
    472     }
    473 
    474     outModes->resize(numModes);
    475     for (size_t i = 0; i < numModes; i++) {
    476         (*outModes)[i] = static_cast<android_color_mode_t>(modes[i]);
    477     }
    478     return Error::None;
    479 }
    480 
    481 std::vector<std::shared_ptr<const Display::Config>> Display::getConfigs() const
    482 {
    483     std::vector<std::shared_ptr<const Config>> configs;
    484     for (const auto& element : mConfigs) {
    485         configs.emplace_back(element.second);
    486     }
    487     return configs;
    488 }
    489 
    490 Error Display::getName(std::string* outName) const
    491 {
    492     auto intError = mDevice.mComposer->getDisplayName(mId, outName);
    493     return static_cast<Error>(intError);
    494 }
    495 
    496 Error Display::getRequests(HWC2::DisplayRequest* outDisplayRequests,
    497         std::unordered_map<std::shared_ptr<Layer>, LayerRequest>*
    498                 outLayerRequests)
    499 {
    500     uint32_t intDisplayRequests;
    501     std::vector<Hwc2::Layer> layerIds;
    502     std::vector<uint32_t> layerRequests;
    503     auto intError = mDevice.mComposer->getDisplayRequests(mId,
    504             &intDisplayRequests, &layerIds, &layerRequests);
    505     uint32_t numElements = layerIds.size();
    506     auto error = static_cast<Error>(intError);
    507     if (error != Error::None) {
    508         return error;
    509     }
    510 
    511     *outDisplayRequests = static_cast<DisplayRequest>(intDisplayRequests);
    512     outLayerRequests->clear();
    513     outLayerRequests->reserve(numElements);
    514     for (uint32_t element = 0; element < numElements; ++element) {
    515         auto layer = getLayerById(layerIds[element]);
    516         if (layer) {
    517             auto layerRequest =
    518                     static_cast<LayerRequest>(layerRequests[element]);
    519             outLayerRequests->emplace(layer, layerRequest);
    520         } else {
    521             ALOGE("getRequests: invalid layer %" PRIu64 " found on display %"
    522                     PRIu64, layerIds[element], mId);
    523         }
    524     }
    525 
    526     return Error::None;
    527 }
    528 
    529 Error Display::getType(DisplayType* outType) const
    530 {
    531     *outType = mType;
    532     return Error::None;
    533 }
    534 
    535 Error Display::supportsDoze(bool* outSupport) const
    536 {
    537     bool intSupport = false;
    538     auto intError = mDevice.mComposer->getDozeSupport(mId, &intSupport);
    539     auto error = static_cast<Error>(intError);
    540     if (error != Error::None) {
    541         return error;
    542     }
    543     *outSupport = static_cast<bool>(intSupport);
    544     return Error::None;
    545 }
    546 
    547 Error Display::getHdrCapabilities(
    548         std::unique_ptr<HdrCapabilities>* outCapabilities) const
    549 {
    550     uint32_t numTypes = 0;
    551     float maxLuminance = -1.0f;
    552     float maxAverageLuminance = -1.0f;
    553     float minLuminance = -1.0f;
    554     std::vector<Hwc2::Hdr> intTypes;
    555     auto intError = mDevice.mComposer->getHdrCapabilities(mId, &intTypes,
    556             &maxLuminance, &maxAverageLuminance, &minLuminance);
    557     auto error = static_cast<HWC2::Error>(intError);
    558 
    559     std::vector<int32_t> types;
    560     for (auto type : intTypes) {
    561         types.push_back(static_cast<int32_t>(type));
    562     }
    563     numTypes = types.size();
    564     if (error != Error::None) {
    565         return error;
    566     }
    567 
    568     *outCapabilities = std::make_unique<HdrCapabilities>(std::move(types),
    569             maxLuminance, maxAverageLuminance, minLuminance);
    570     return Error::None;
    571 }
    572 
    573 Error Display::getReleaseFences(
    574         std::unordered_map<std::shared_ptr<Layer>, sp<Fence>>* outFences) const
    575 {
    576     std::vector<Hwc2::Layer> layerIds;
    577     std::vector<int> fenceFds;
    578     auto intError = mDevice.mComposer->getReleaseFences(mId,
    579             &layerIds, &fenceFds);
    580     auto error = static_cast<Error>(intError);
    581     uint32_t numElements = layerIds.size();
    582     if (error != Error::None) {
    583         return error;
    584     }
    585 
    586     std::unordered_map<std::shared_ptr<Layer>, sp<Fence>> releaseFences;
    587     releaseFences.reserve(numElements);
    588     for (uint32_t element = 0; element < numElements; ++element) {
    589         auto layer = getLayerById(layerIds[element]);
    590         if (layer) {
    591             sp<Fence> fence(new Fence(fenceFds[element]));
    592             releaseFences.emplace(std::move(layer), fence);
    593         } else {
    594             ALOGE("getReleaseFences: invalid layer %" PRIu64
    595                     " found on display %" PRIu64, layerIds[element], mId);
    596             for (; element < numElements; ++element) {
    597                 close(fenceFds[element]);
    598             }
    599             return Error::BadLayer;
    600         }
    601     }
    602 
    603     *outFences = std::move(releaseFences);
    604     return Error::None;
    605 }
    606 
    607 Error Display::present(sp<Fence>* outPresentFence)
    608 {
    609     int32_t presentFenceFd = -1;
    610     auto intError = mDevice.mComposer->presentDisplay(mId, &presentFenceFd);
    611     auto error = static_cast<Error>(intError);
    612     if (error != Error::None) {
    613         return error;
    614     }
    615 
    616     *outPresentFence = new Fence(presentFenceFd);
    617     return Error::None;
    618 }
    619 
    620 Error Display::setActiveConfig(const std::shared_ptr<const Config>& config)
    621 {
    622     if (config->getDisplayId() != mId) {
    623         ALOGE("setActiveConfig received config %u for the wrong display %"
    624                 PRIu64 " (expected %" PRIu64 ")", config->getId(),
    625                 config->getDisplayId(), mId);
    626         return Error::BadConfig;
    627     }
    628     auto intError = mDevice.mComposer->setActiveConfig(mId, config->getId());
    629     return static_cast<Error>(intError);
    630 }
    631 
    632 Error Display::setClientTarget(uint32_t slot, const sp<GraphicBuffer>& target,
    633         const sp<Fence>& acquireFence, android_dataspace_t dataspace)
    634 {
    635     // TODO: Properly encode client target surface damage
    636     int32_t fenceFd = acquireFence->dup();
    637     auto intError = mDevice.mComposer->setClientTarget(mId, slot, target,
    638             fenceFd, static_cast<Hwc2::Dataspace>(dataspace),
    639             std::vector<Hwc2::IComposerClient::Rect>());
    640     return static_cast<Error>(intError);
    641 }
    642 
    643 Error Display::setColorMode(android_color_mode_t mode)
    644 {
    645     auto intError = mDevice.mComposer->setColorMode(mId,
    646             static_cast<Hwc2::ColorMode>(mode));
    647     return static_cast<Error>(intError);
    648 }
    649 
    650 Error Display::setColorTransform(const android::mat4& matrix,
    651         android_color_transform_t hint)
    652 {
    653     auto intError = mDevice.mComposer->setColorTransform(mId,
    654             matrix.asArray(), static_cast<Hwc2::ColorTransform>(hint));
    655     return static_cast<Error>(intError);
    656 }
    657 
    658 Error Display::setOutputBuffer(const sp<GraphicBuffer>& buffer,
    659         const sp<Fence>& releaseFence)
    660 {
    661     int32_t fenceFd = releaseFence->dup();
    662     auto handle = buffer->getNativeBuffer()->handle;
    663     auto intError = mDevice.mComposer->setOutputBuffer(mId, handle, fenceFd);
    664     close(fenceFd);
    665     return static_cast<Error>(intError);
    666 }
    667 
    668 Error Display::setPowerMode(PowerMode mode)
    669 {
    670     auto intMode = static_cast<Hwc2::IComposerClient::PowerMode>(mode);
    671     auto intError = mDevice.mComposer->setPowerMode(mId, intMode);
    672     return static_cast<Error>(intError);
    673 }
    674 
    675 Error Display::setVsyncEnabled(Vsync enabled)
    676 {
    677     auto intEnabled = static_cast<Hwc2::IComposerClient::Vsync>(enabled);
    678     auto intError = mDevice.mComposer->setVsyncEnabled(mId, intEnabled);
    679     return static_cast<Error>(intError);
    680 }
    681 
    682 Error Display::validate(uint32_t* outNumTypes, uint32_t* outNumRequests)
    683 {
    684     uint32_t numTypes = 0;
    685     uint32_t numRequests = 0;
    686     auto intError = mDevice.mComposer->validateDisplay(mId,
    687             &numTypes, &numRequests);
    688     auto error = static_cast<Error>(intError);
    689     if (error != Error::None && error != Error::HasChanges) {
    690         return error;
    691     }
    692 
    693     *outNumTypes = numTypes;
    694     *outNumRequests = numRequests;
    695     return error;
    696 }
    697 
    698 Error Display::presentOrValidate(uint32_t* outNumTypes, uint32_t* outNumRequests,
    699                                  sp<android::Fence>* outPresentFence, uint32_t* state) {
    700 
    701     uint32_t numTypes = 0;
    702     uint32_t numRequests = 0;
    703     int32_t presentFenceFd = -1;
    704     auto intError = mDevice.mComposer->presentOrValidateDisplay(mId, &numTypes, &numRequests, &presentFenceFd, state);
    705     auto error = static_cast<Error>(intError);
    706     if (error != Error::None && error != Error::HasChanges) {
    707         return error;
    708     }
    709 
    710     if (*state == 1) {
    711         *outPresentFence = new Fence(presentFenceFd);
    712     }
    713 
    714     if (*state == 0) {
    715         *outNumTypes = numTypes;
    716         *outNumRequests = numRequests;
    717     }
    718     return error;
    719 }
    720 
    721 void Display::discardCommands()
    722 {
    723     mDevice.mComposer->resetCommands();
    724 }
    725 
    726 // For use by Device
    727 
    728 int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute)
    729 {
    730     int32_t value = 0;
    731     auto intError = mDevice.mComposer->getDisplayAttribute(mId, configId,
    732             static_cast<Hwc2::IComposerClient::Attribute>(attribute),
    733             &value);
    734     auto error = static_cast<Error>(intError);
    735     if (error != Error::None) {
    736         ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId,
    737                 configId, to_string(attribute).c_str(),
    738                 to_string(error).c_str(), intError);
    739         return -1;
    740     }
    741     return value;
    742 }
    743 
    744 void Display::loadConfig(hwc2_config_t configId)
    745 {
    746     ALOGV("[%" PRIu64 "] loadConfig(%u)", mId, configId);
    747 
    748     auto config = Config::Builder(*this, configId)
    749             .setWidth(getAttribute(configId, Attribute::Width))
    750             .setHeight(getAttribute(configId, Attribute::Height))
    751             .setVsyncPeriod(getAttribute(configId, Attribute::VsyncPeriod))
    752             .setDpiX(getAttribute(configId, Attribute::DpiX))
    753             .setDpiY(getAttribute(configId, Attribute::DpiY))
    754             .build();
    755     mConfigs.emplace(configId, std::move(config));
    756 }
    757 
    758 void Display::loadConfigs()
    759 {
    760     ALOGV("[%" PRIu64 "] loadConfigs", mId);
    761 
    762     std::vector<Hwc2::Config> configIds;
    763     auto intError = mDevice.mComposer->getDisplayConfigs(mId, &configIds);
    764     auto error = static_cast<Error>(intError);
    765     if (error != Error::None) {
    766         ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId,
    767                 to_string(error).c_str(), intError);
    768         return;
    769     }
    770 
    771     for (auto configId : configIds) {
    772         loadConfig(configId);
    773     }
    774 }
    775 
    776 // For use by Layer
    777 
    778 void Display::destroyLayer(hwc2_layer_t layerId)
    779 {
    780     auto intError =mDevice.mComposer->destroyLayer(mId, layerId);
    781     auto error = static_cast<Error>(intError);
    782     ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")"
    783             " failed: %s (%d)", mId, layerId, to_string(error).c_str(),
    784             intError);
    785     mLayers.erase(layerId);
    786 }
    787 
    788 // Other Display methods
    789 
    790 std::shared_ptr<Layer> Display::getLayerById(hwc2_layer_t id) const
    791 {
    792     if (mLayers.count(id) == 0) {
    793         return nullptr;
    794     }
    795 
    796     auto layer = mLayers.at(id).lock();
    797     return layer;
    798 }
    799 
    800 // Layer methods
    801 
    802 Layer::Layer(const std::shared_ptr<Display>& display, hwc2_layer_t id)
    803   : mDisplay(display),
    804     mDisplayId(display->getId()),
    805     mDevice(display->getDevice()),
    806     mId(id)
    807 {
    808     ALOGV("Created layer %" PRIu64 " on display %" PRIu64, id,
    809             display->getId());
    810 }
    811 
    812 Layer::~Layer()
    813 {
    814     auto display = mDisplay.lock();
    815     if (display) {
    816         display->destroyLayer(mId);
    817     }
    818 }
    819 
    820 Error Layer::setCursorPosition(int32_t x, int32_t y)
    821 {
    822     auto intError = mDevice.mComposer->setCursorPosition(mDisplayId,
    823             mId, x, y);
    824     return static_cast<Error>(intError);
    825 }
    826 
    827 Error Layer::setBuffer(uint32_t slot, const sp<GraphicBuffer>& buffer,
    828         const sp<Fence>& acquireFence)
    829 {
    830     int32_t fenceFd = acquireFence->dup();
    831     auto intError = mDevice.mComposer->setLayerBuffer(mDisplayId,
    832             mId, slot, buffer, fenceFd);
    833     return static_cast<Error>(intError);
    834 }
    835 
    836 Error Layer::setSurfaceDamage(const Region& damage)
    837 {
    838     // We encode default full-screen damage as INVALID_RECT upstream, but as 0
    839     // rects for HWC
    840     Hwc2::Error intError = Hwc2::Error::NONE;
    841     if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) {
    842         intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId,
    843                 mId, std::vector<Hwc2::IComposerClient::Rect>());
    844     } else {
    845         size_t rectCount = 0;
    846         auto rectArray = damage.getArray(&rectCount);
    847 
    848         std::vector<Hwc2::IComposerClient::Rect> hwcRects;
    849         for (size_t rect = 0; rect < rectCount; ++rect) {
    850             hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
    851                     rectArray[rect].right, rectArray[rect].bottom});
    852         }
    853 
    854         intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId,
    855                 mId, hwcRects);
    856     }
    857 
    858     return static_cast<Error>(intError);
    859 }
    860 
    861 Error Layer::setBlendMode(BlendMode mode)
    862 {
    863     auto intMode = static_cast<Hwc2::IComposerClient::BlendMode>(mode);
    864     auto intError = mDevice.mComposer->setLayerBlendMode(mDisplayId,
    865             mId, intMode);
    866     return static_cast<Error>(intError);
    867 }
    868 
    869 Error Layer::setColor(hwc_color_t color)
    870 {
    871     Hwc2::IComposerClient::Color hwcColor{color.r, color.g, color.b, color.a};
    872     auto intError = mDevice.mComposer->setLayerColor(mDisplayId,
    873             mId, hwcColor);
    874     return static_cast<Error>(intError);
    875 }
    876 
    877 Error Layer::setCompositionType(Composition type)
    878 {
    879     auto intType = static_cast<Hwc2::IComposerClient::Composition>(type);
    880     auto intError = mDevice.mComposer->setLayerCompositionType(mDisplayId,
    881             mId, intType);
    882     return static_cast<Error>(intError);
    883 }
    884 
    885 Error Layer::setDataspace(android_dataspace_t dataspace)
    886 {
    887     auto intDataspace = static_cast<Hwc2::Dataspace>(dataspace);
    888     auto intError = mDevice.mComposer->setLayerDataspace(mDisplayId,
    889             mId, intDataspace);
    890     return static_cast<Error>(intError);
    891 }
    892 
    893 Error Layer::setDisplayFrame(const Rect& frame)
    894 {
    895     Hwc2::IComposerClient::Rect hwcRect{frame.left, frame.top,
    896         frame.right, frame.bottom};
    897     auto intError = mDevice.mComposer->setLayerDisplayFrame(mDisplayId,
    898             mId, hwcRect);
    899     return static_cast<Error>(intError);
    900 }
    901 
    902 Error Layer::setPlaneAlpha(float alpha)
    903 {
    904     auto intError = mDevice.mComposer->setLayerPlaneAlpha(mDisplayId,
    905             mId, alpha);
    906     return static_cast<Error>(intError);
    907 }
    908 
    909 Error Layer::setSidebandStream(const native_handle_t* stream)
    910 {
    911     if (!mDevice.hasCapability(Capability::SidebandStream)) {
    912         ALOGE("Attempted to call setSidebandStream without checking that the "
    913                 "device supports sideband streams");
    914         return Error::Unsupported;
    915     }
    916     auto intError = mDevice.mComposer->setLayerSidebandStream(mDisplayId,
    917             mId, stream);
    918     return static_cast<Error>(intError);
    919 }
    920 
    921 Error Layer::setSourceCrop(const FloatRect& crop)
    922 {
    923     Hwc2::IComposerClient::FRect hwcRect{
    924         crop.left, crop.top, crop.right, crop.bottom};
    925     auto intError = mDevice.mComposer->setLayerSourceCrop(mDisplayId,
    926             mId, hwcRect);
    927     return static_cast<Error>(intError);
    928 }
    929 
    930 Error Layer::setTransform(Transform transform)
    931 {
    932     auto intTransform = static_cast<Hwc2::Transform>(transform);
    933     auto intError = mDevice.mComposer->setLayerTransform(mDisplayId,
    934             mId, intTransform);
    935     return static_cast<Error>(intError);
    936 }
    937 
    938 Error Layer::setVisibleRegion(const Region& region)
    939 {
    940     size_t rectCount = 0;
    941     auto rectArray = region.getArray(&rectCount);
    942 
    943     std::vector<Hwc2::IComposerClient::Rect> hwcRects;
    944     for (size_t rect = 0; rect < rectCount; ++rect) {
    945         hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
    946                 rectArray[rect].right, rectArray[rect].bottom});
    947     }
    948 
    949     auto intError = mDevice.mComposer->setLayerVisibleRegion(mDisplayId,
    950             mId, hwcRects);
    951     return static_cast<Error>(intError);
    952 }
    953 
    954 Error Layer::setZOrder(uint32_t z)
    955 {
    956     auto intError = mDevice.mComposer->setLayerZOrder(mDisplayId, mId, z);
    957     return static_cast<Error>(intError);
    958 }
    959 
    960 Error Layer::setInfo(uint32_t type, uint32_t appId)
    961 {
    962   auto intError = mDevice.mComposer->setLayerInfo(mDisplayId, mId, type, appId);
    963   return static_cast<Error>(intError);
    964 }
    965 
    966 } // namespace HWC2
    967