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