HWC2.cpp revision fd997e0969100418b4df8b8d97d21d497afa76c3
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    display->setConnected(true);
133    *outDisplay = display.get();
134    *format = static_cast<android_pixel_format_t>(intFormat);
135    mDisplays.emplace(displayId, std::move(display));
136    ALOGI("Created virtual display");
137    return Error::None;
138}
139
140void Device::destroyDisplay(hwc2_display_t displayId)
141{
142    ALOGI("Destroying display %" PRIu64, displayId);
143    mDisplays.erase(displayId);
144}
145
146void Device::onHotplug(hwc2_display_t displayId, Connection connection) {
147    if (connection == Connection::Connected) {
148        // If we get a hotplug connected event for a display we already have,
149        // destroy the display and recreate it. This will force us to requery
150        // the display params and recreate all layers on that display.
151        auto oldDisplay = getDisplayById(displayId);
152        if (oldDisplay != nullptr && oldDisplay->isConnected()) {
153            ALOGI("Hotplug connecting an already connected display."
154                    " Clearing old display state.");
155        }
156        mDisplays.erase(displayId);
157
158        DisplayType displayType;
159        auto intError = mComposer->getDisplayType(displayId,
160                reinterpret_cast<Hwc2::IComposerClient::DisplayType *>(
161                        &displayType));
162        auto error = static_cast<Error>(intError);
163        if (error != Error::None) {
164            ALOGE("getDisplayType(%" PRIu64 ") failed: %s (%d). "
165                    "Aborting hotplug attempt.",
166                    displayId, to_string(error).c_str(), intError);
167            return;
168        }
169
170        auto newDisplay = std::make_unique<Display>(
171                *mComposer.get(), mCapabilities, displayId, displayType);
172        newDisplay->setConnected(true);
173        mDisplays.emplace(displayId, std::move(newDisplay));
174    } else if (connection == Connection::Disconnected) {
175        // The display will later be destroyed by a call to
176        // destroyDisplay(). For now we just mark it disconnected.
177        auto display = getDisplayById(displayId);
178        if (display) {
179            display->setConnected(false);
180        } else {
181            ALOGW("Attempted to disconnect unknown display %" PRIu64,
182                  displayId);
183        }
184    }
185}
186
187// Other Device methods
188
189Display* Device::getDisplayById(hwc2_display_t id) {
190    auto iter = mDisplays.find(id);
191    return iter == mDisplays.end() ? nullptr : iter->second.get();
192}
193
194// Device initialization methods
195
196void Device::loadCapabilities()
197{
198    static_assert(sizeof(Capability) == sizeof(int32_t),
199            "Capability size has changed");
200    auto capabilities = mComposer->getCapabilities();
201    for (auto capability : capabilities) {
202        mCapabilities.emplace(static_cast<Capability>(capability));
203    }
204}
205
206Error Device::flushCommands()
207{
208    return static_cast<Error>(mComposer->executeCommands());
209}
210
211// Display methods
212
213Display::Display(android::Hwc2::Composer& composer,
214                 const std::unordered_set<Capability>& capabilities, hwc2_display_t id,
215                 DisplayType type)
216      : mComposer(composer),
217        mCapabilities(capabilities),
218        mId(id),
219        mIsConnected(false),
220        mType(type) {
221    ALOGV("Created display %" PRIu64, id);
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::ui::ColorMode>* outModes) const
366{
367    auto intError = mComposer.getColorModes(mId, outModes);
368    return static_cast<Error>(intError);
369    return Error::None;
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, android_dataspace_t 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, static_cast<Hwc2::Dataspace>(dataspace),
526            std::vector<Hwc2::IComposerClient::Rect>());
527    return static_cast<Error>(intError);
528}
529
530Error Display::setColorMode(android::ui::ColorMode mode)
531{
532    auto intError = mComposer.setColorMode(mId, mode);
533    return static_cast<Error>(intError);
534}
535
536Error Display::setColorTransform(const android::mat4& matrix,
537        android_color_transform_t hint)
538{
539    auto intError = mComposer.setColorTransform(mId,
540            matrix.asArray(), static_cast<Hwc2::ColorTransform>(hint));
541    return static_cast<Error>(intError);
542}
543
544Error Display::setOutputBuffer(const sp<GraphicBuffer>& buffer,
545        const sp<Fence>& releaseFence)
546{
547    int32_t fenceFd = releaseFence->dup();
548    auto handle = buffer->getNativeBuffer()->handle;
549    auto intError = mComposer.setOutputBuffer(mId, handle, fenceFd);
550    close(fenceFd);
551    return static_cast<Error>(intError);
552}
553
554Error Display::setPowerMode(PowerMode mode)
555{
556    auto intMode = static_cast<Hwc2::IComposerClient::PowerMode>(mode);
557    auto intError = mComposer.setPowerMode(mId, intMode);
558    return static_cast<Error>(intError);
559}
560
561Error Display::setVsyncEnabled(Vsync enabled)
562{
563    auto intEnabled = static_cast<Hwc2::IComposerClient::Vsync>(enabled);
564    auto intError = mComposer.setVsyncEnabled(mId, intEnabled);
565    return static_cast<Error>(intError);
566}
567
568Error Display::validate(uint32_t* outNumTypes, uint32_t* outNumRequests)
569{
570    uint32_t numTypes = 0;
571    uint32_t numRequests = 0;
572    auto intError = mComposer.validateDisplay(mId, &numTypes, &numRequests);
573    auto error = static_cast<Error>(intError);
574    if (error != Error::None && error != Error::HasChanges) {
575        return error;
576    }
577
578    *outNumTypes = numTypes;
579    *outNumRequests = numRequests;
580    return error;
581}
582
583Error Display::presentOrValidate(uint32_t* outNumTypes, uint32_t* outNumRequests,
584                                 sp<android::Fence>* outPresentFence, uint32_t* state) {
585
586    uint32_t numTypes = 0;
587    uint32_t numRequests = 0;
588    int32_t presentFenceFd = -1;
589    auto intError = mComposer.presentOrValidateDisplay(
590            mId, &numTypes, &numRequests, &presentFenceFd, state);
591    auto error = static_cast<Error>(intError);
592    if (error != Error::None && error != Error::HasChanges) {
593        return error;
594    }
595
596    if (*state == 1) {
597        *outPresentFence = new Fence(presentFenceFd);
598    }
599
600    if (*state == 0) {
601        *outNumTypes = numTypes;
602        *outNumRequests = numRequests;
603    }
604    return error;
605}
606
607// For use by Device
608
609void Display::setConnected(bool connected) {
610    if (!mIsConnected && connected) {
611        mComposer.setClientTargetSlotCount(mId);
612        if (mType == DisplayType::Physical) {
613            loadConfigs();
614        }
615    }
616    mIsConnected = connected;
617}
618
619int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute)
620{
621    int32_t value = 0;
622    auto intError = mComposer.getDisplayAttribute(mId, configId,
623            static_cast<Hwc2::IComposerClient::Attribute>(attribute),
624            &value);
625    auto error = static_cast<Error>(intError);
626    if (error != Error::None) {
627        ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId,
628                configId, to_string(attribute).c_str(),
629                to_string(error).c_str(), intError);
630        return -1;
631    }
632    return value;
633}
634
635void Display::loadConfig(hwc2_config_t configId)
636{
637    ALOGV("[%" PRIu64 "] loadConfig(%u)", mId, configId);
638
639    auto config = Config::Builder(*this, configId)
640            .setWidth(getAttribute(configId, Attribute::Width))
641            .setHeight(getAttribute(configId, Attribute::Height))
642            .setVsyncPeriod(getAttribute(configId, Attribute::VsyncPeriod))
643            .setDpiX(getAttribute(configId, Attribute::DpiX))
644            .setDpiY(getAttribute(configId, Attribute::DpiY))
645            .build();
646    mConfigs.emplace(configId, std::move(config));
647}
648
649void Display::loadConfigs()
650{
651    ALOGV("[%" PRIu64 "] loadConfigs", mId);
652
653    std::vector<Hwc2::Config> configIds;
654    auto intError = mComposer.getDisplayConfigs(mId, &configIds);
655    auto error = static_cast<Error>(intError);
656    if (error != Error::None) {
657        ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId,
658                to_string(error).c_str(), intError);
659        return;
660    }
661
662    for (auto configId : configIds) {
663        loadConfig(configId);
664    }
665}
666
667// Other Display methods
668
669Layer* Display::getLayerById(hwc2_layer_t id) const
670{
671    if (mLayers.count(id) == 0) {
672        return nullptr;
673    }
674
675    return mLayers.at(id).get();
676}
677
678// Layer methods
679
680Layer::Layer(android::Hwc2::Composer& composer, const std::unordered_set<Capability>& capabilities,
681             hwc2_display_t displayId, hwc2_layer_t layerId)
682  : mComposer(composer),
683    mCapabilities(capabilities),
684    mDisplayId(displayId),
685    mId(layerId)
686{
687    ALOGV("Created layer %" PRIu64 " on display %" PRIu64, layerId, displayId);
688}
689
690Layer::~Layer()
691{
692    auto intError = mComposer.destroyLayer(mDisplayId, mId);
693    auto error = static_cast<Error>(intError);
694    ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")"
695            " failed: %s (%d)", mDisplayId, mId, to_string(error).c_str(),
696            intError);
697    if (mLayerDestroyedListener) {
698        mLayerDestroyedListener(this);
699    }
700}
701
702void Layer::setLayerDestroyedListener(std::function<void(Layer*)> listener) {
703    LOG_ALWAYS_FATAL_IF(mLayerDestroyedListener && listener,
704            "Attempt to set layer destroyed listener multiple times");
705    mLayerDestroyedListener = listener;
706}
707
708Error Layer::setCursorPosition(int32_t x, int32_t y)
709{
710    auto intError = mComposer.setCursorPosition(mDisplayId, mId, x, y);
711    return static_cast<Error>(intError);
712}
713
714Error Layer::setBuffer(uint32_t slot, const sp<GraphicBuffer>& buffer,
715        const sp<Fence>& acquireFence)
716{
717    int32_t fenceFd = acquireFence->dup();
718    auto intError = mComposer.setLayerBuffer(mDisplayId, mId, slot, buffer,
719                                             fenceFd);
720    return static_cast<Error>(intError);
721}
722
723Error Layer::setSurfaceDamage(const Region& damage)
724{
725    // We encode default full-screen damage as INVALID_RECT upstream, but as 0
726    // rects for HWC
727    Hwc2::Error intError = Hwc2::Error::NONE;
728    if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) {
729        intError = mComposer.setLayerSurfaceDamage(mDisplayId,
730                mId, std::vector<Hwc2::IComposerClient::Rect>());
731    } else {
732        size_t rectCount = 0;
733        auto rectArray = damage.getArray(&rectCount);
734
735        std::vector<Hwc2::IComposerClient::Rect> hwcRects;
736        for (size_t rect = 0; rect < rectCount; ++rect) {
737            hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
738                    rectArray[rect].right, rectArray[rect].bottom});
739        }
740
741        intError = mComposer.setLayerSurfaceDamage(mDisplayId, mId, hwcRects);
742    }
743
744    return static_cast<Error>(intError);
745}
746
747Error Layer::setBlendMode(BlendMode mode)
748{
749    auto intMode = static_cast<Hwc2::IComposerClient::BlendMode>(mode);
750    auto intError = mComposer.setLayerBlendMode(mDisplayId, mId, intMode);
751    return static_cast<Error>(intError);
752}
753
754Error Layer::setColor(hwc_color_t color)
755{
756    Hwc2::IComposerClient::Color hwcColor{color.r, color.g, color.b, color.a};
757    auto intError = mComposer.setLayerColor(mDisplayId, mId, hwcColor);
758    return static_cast<Error>(intError);
759}
760
761Error Layer::setCompositionType(Composition type)
762{
763    auto intType = static_cast<Hwc2::IComposerClient::Composition>(type);
764    auto intError = mComposer.setLayerCompositionType(
765            mDisplayId, mId, intType);
766    return static_cast<Error>(intError);
767}
768
769Error Layer::setDataspace(android_dataspace_t dataspace)
770{
771    if (dataspace == mDataSpace) {
772        return Error::None;
773    }
774    mDataSpace = dataspace;
775    auto intDataspace = static_cast<Hwc2::Dataspace>(dataspace);
776    auto intError = mComposer.setLayerDataspace(mDisplayId, mId, intDataspace);
777    return static_cast<Error>(intError);
778}
779
780Error Layer::setHdrMetadata(const android::HdrMetadata& metadata) {
781    if (metadata == mHdrMetadata) {
782        return Error::None;
783    }
784
785    mHdrMetadata = metadata;
786    auto intError = mComposer.setLayerHdrMetadata(mDisplayId, mId, metadata);
787    return static_cast<Error>(intError);
788}
789
790Error Layer::setDisplayFrame(const Rect& frame)
791{
792    Hwc2::IComposerClient::Rect hwcRect{frame.left, frame.top,
793        frame.right, frame.bottom};
794    auto intError = mComposer.setLayerDisplayFrame(mDisplayId, mId, hwcRect);
795    return static_cast<Error>(intError);
796}
797
798Error Layer::setPlaneAlpha(float alpha)
799{
800    auto intError = mComposer.setLayerPlaneAlpha(mDisplayId, mId, alpha);
801    return static_cast<Error>(intError);
802}
803
804Error Layer::setSidebandStream(const native_handle_t* stream)
805{
806    if (mCapabilities.count(Capability::SidebandStream) == 0) {
807        ALOGE("Attempted to call setSidebandStream without checking that the "
808                "device supports sideband streams");
809        return Error::Unsupported;
810    }
811    auto intError = mComposer.setLayerSidebandStream(mDisplayId, mId, stream);
812    return static_cast<Error>(intError);
813}
814
815Error Layer::setSourceCrop(const FloatRect& crop)
816{
817    Hwc2::IComposerClient::FRect hwcRect{
818        crop.left, crop.top, crop.right, crop.bottom};
819    auto intError = mComposer.setLayerSourceCrop(mDisplayId, mId, hwcRect);
820    return static_cast<Error>(intError);
821}
822
823Error Layer::setTransform(Transform transform)
824{
825    auto intTransform = static_cast<Hwc2::Transform>(transform);
826    auto intError = mComposer.setLayerTransform(mDisplayId, mId, intTransform);
827    return static_cast<Error>(intError);
828}
829
830Error Layer::setVisibleRegion(const Region& region)
831{
832    size_t rectCount = 0;
833    auto rectArray = region.getArray(&rectCount);
834
835    std::vector<Hwc2::IComposerClient::Rect> hwcRects;
836    for (size_t rect = 0; rect < rectCount; ++rect) {
837        hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
838                rectArray[rect].right, rectArray[rect].bottom});
839    }
840
841    auto intError = mComposer.setLayerVisibleRegion(mDisplayId, mId, hwcRects);
842    return static_cast<Error>(intError);
843}
844
845Error Layer::setZOrder(uint32_t z)
846{
847    auto intError = mComposer.setLayerZOrder(mDisplayId, mId, z);
848    return static_cast<Error>(intError);
849}
850
851Error Layer::setInfo(uint32_t type, uint32_t appId)
852{
853  auto intError = mComposer.setLayerInfo(mDisplayId, mId, type, appId);
854  return static_cast<Error>(intError);
855}
856
857} // namespace HWC2
858