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