HWC2.cpp revision cd8d7f08fe26645f74e540365b1a8a38e602088d
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 "FloatRect.h"
27
28#include <ui/Fence.h>
29#include <ui/GraphicBuffer.h>
30#include <ui/Region.h>
31
32#include <android/configuration.h>
33
34#include <algorithm>
35#include <inttypes.h>
36
37extern "C" {
38    static void hotplug_hook(hwc2_callback_data_t callbackData,
39            hwc2_display_t displayId, int32_t intConnected) {
40        auto device = static_cast<HWC2::Device*>(callbackData);
41        auto display = device->getDisplayById(displayId);
42        if (display) {
43            auto connected = static_cast<HWC2::Connection>(intConnected);
44            device->callHotplug(std::move(display), connected);
45        } else {
46            ALOGE("Hotplug callback called with unknown display %" PRIu64,
47                    displayId);
48        }
49    }
50
51    static void refresh_hook(hwc2_callback_data_t callbackData,
52            hwc2_display_t displayId) {
53        auto device = static_cast<HWC2::Device*>(callbackData);
54        auto display = device->getDisplayById(displayId);
55        if (display) {
56            device->callRefresh(std::move(display));
57        } else {
58            ALOGE("Refresh callback called with unknown display %" PRIu64,
59                    displayId);
60        }
61    }
62
63    static void vsync_hook(hwc2_callback_data_t callbackData,
64            hwc2_display_t displayId, int64_t timestamp) {
65        auto device = static_cast<HWC2::Device*>(callbackData);
66        auto display = device->getDisplayById(displayId);
67        if (display) {
68            device->callVsync(std::move(display), timestamp);
69        } else {
70            ALOGE("Vsync callback called with unknown display %" PRIu64,
71                    displayId);
72        }
73    }
74}
75
76using android::Fence;
77using android::FloatRect;
78using android::GraphicBuffer;
79using android::HdrCapabilities;
80using android::Rect;
81using android::Region;
82using android::sp;
83using android::hardware::Return;
84using android::hardware::Void;
85
86namespace HWC2 {
87
88namespace Hwc2 = android::Hwc2;
89
90// Device methods
91
92#ifdef BYPASS_IHWC
93Device::Device(hwc2_device_t* device)
94  : mHwcDevice(device),
95    mCreateVirtualDisplay(nullptr),
96    mDestroyVirtualDisplay(nullptr),
97    mDump(nullptr),
98    mGetMaxVirtualDisplayCount(nullptr),
99    mRegisterCallback(nullptr),
100    mAcceptDisplayChanges(nullptr),
101    mCreateLayer(nullptr),
102    mDestroyLayer(nullptr),
103    mGetActiveConfig(nullptr),
104    mGetChangedCompositionTypes(nullptr),
105    mGetColorModes(nullptr),
106    mGetDisplayAttribute(nullptr),
107    mGetDisplayConfigs(nullptr),
108    mGetDisplayName(nullptr),
109    mGetDisplayRequests(nullptr),
110    mGetDisplayType(nullptr),
111    mGetDozeSupport(nullptr),
112    mGetHdrCapabilities(nullptr),
113    mGetReleaseFences(nullptr),
114    mPresentDisplay(nullptr),
115    mSetActiveConfig(nullptr),
116    mSetClientTarget(nullptr),
117    mSetColorMode(nullptr),
118    mSetColorTransform(nullptr),
119    mSetOutputBuffer(nullptr),
120    mSetPowerMode(nullptr),
121    mSetVsyncEnabled(nullptr),
122    mValidateDisplay(nullptr),
123    mSetCursorPosition(nullptr),
124    mSetLayerBuffer(nullptr),
125    mSetLayerSurfaceDamage(nullptr),
126    mSetLayerBlendMode(nullptr),
127    mSetLayerColor(nullptr),
128    mSetLayerCompositionType(nullptr),
129    mSetLayerDataspace(nullptr),
130    mSetLayerDisplayFrame(nullptr),
131    mSetLayerPlaneAlpha(nullptr),
132    mSetLayerSidebandStream(nullptr),
133    mSetLayerSourceCrop(nullptr),
134    mSetLayerTransform(nullptr),
135    mSetLayerVisibleRegion(nullptr),
136    mSetLayerZOrder(nullptr),
137#else
138Device::Device()
139  : mComposer(std::make_unique<Hwc2::Composer>()),
140#endif // BYPASS_IHWC
141    mCapabilities(),
142    mDisplays(),
143    mHotplug(),
144    mPendingHotplugs(),
145    mRefresh(),
146    mPendingRefreshes(),
147    mVsync(),
148    mPendingVsyncs()
149{
150    loadCapabilities();
151    loadFunctionPointers();
152    registerCallbacks();
153}
154
155Device::~Device()
156{
157#ifdef BYPASS_IHWC
158    if (mHwcDevice == nullptr) {
159        return;
160    }
161#endif
162
163    for (auto element : mDisplays) {
164        auto display = element.second.lock();
165        if (!display) {
166            ALOGE("~Device: Found a display (%" PRId64 " that has already been"
167                    " destroyed", element.first);
168            continue;
169        }
170
171        DisplayType displayType = HWC2::DisplayType::Invalid;
172        auto error = display->getType(&displayType);
173        if (error != Error::None) {
174            ALOGE("~Device: Failed to determine type of display %" PRIu64
175                    ": %s (%d)", display->getId(), to_string(error).c_str(),
176                    static_cast<int32_t>(error));
177            continue;
178        }
179
180        if (displayType == HWC2::DisplayType::Physical) {
181            error = display->setVsyncEnabled(HWC2::Vsync::Disable);
182            if (error != Error::None) {
183                ALOGE("~Device: Failed to disable vsync for display %" PRIu64
184                        ": %s (%d)", display->getId(), to_string(error).c_str(),
185                        static_cast<int32_t>(error));
186            }
187        }
188    }
189
190#ifdef BYPASS_IHWC
191    hwc2_close(mHwcDevice);
192#endif
193}
194
195// Required by HWC2 device
196
197std::string Device::dump() const
198{
199#ifdef BYPASS_IHWC
200    uint32_t numBytes = 0;
201    mDump(mHwcDevice, &numBytes, nullptr);
202
203    std::vector<char> buffer(numBytes);
204    mDump(mHwcDevice, &numBytes, buffer.data());
205
206    return std::string(buffer.data(), buffer.size());
207#else
208    return mComposer->dumpDebugInfo();
209#endif
210}
211
212uint32_t Device::getMaxVirtualDisplayCount() const
213{
214#ifdef BYPASS_IHWC
215    return mGetMaxVirtualDisplayCount(mHwcDevice);
216#else
217    return mComposer->getMaxVirtualDisplayCount();
218#endif
219}
220
221Error Device::createVirtualDisplay(uint32_t width, uint32_t height,
222        android_pixel_format_t* format, std::shared_ptr<Display>* outDisplay)
223{
224    ALOGI("Creating virtual display");
225
226    hwc2_display_t displayId = 0;
227#ifdef BYPASS_IHWC
228    int32_t intFormat = static_cast<int32_t>(*format);
229    int32_t intError = mCreateVirtualDisplay(mHwcDevice, width, height,
230            &intFormat, &displayId);
231#else
232    auto intFormat = static_cast<Hwc2::PixelFormat>(*format);
233    auto intError = mComposer->createVirtualDisplay(width, height,
234            intFormat, displayId);
235#endif
236    auto error = static_cast<Error>(intError);
237    if (error != Error::None) {
238        return error;
239    }
240
241    ALOGI("Created virtual display");
242    *format = static_cast<android_pixel_format_t>(intFormat);
243    *outDisplay = getDisplayById(displayId);
244    if (!*outDisplay) {
245        ALOGE("Failed to get display by id");
246        return Error::BadDisplay;
247    }
248    (*outDisplay)->setVirtual();
249    return Error::None;
250}
251
252void Device::registerHotplugCallback(HotplugCallback hotplug)
253{
254    ALOGV("registerHotplugCallback");
255    mHotplug = hotplug;
256    for (auto& pending : mPendingHotplugs) {
257        auto& display = pending.first;
258        auto connected = pending.second;
259        ALOGV("Sending pending hotplug(%" PRIu64 ", %s)", display->getId(),
260                to_string(connected).c_str());
261        mHotplug(std::move(display), connected);
262    }
263}
264
265void Device::registerRefreshCallback(RefreshCallback refresh)
266{
267    mRefresh = refresh;
268    for (auto& pending : mPendingRefreshes) {
269        mRefresh(std::move(pending));
270    }
271}
272
273void Device::registerVsyncCallback(VsyncCallback vsync)
274{
275    mVsync = vsync;
276    for (auto& pending : mPendingVsyncs) {
277        auto& display = pending.first;
278        auto timestamp = pending.second;
279        mVsync(std::move(display), timestamp);
280    }
281}
282
283// For use by Device callbacks
284
285void Device::callHotplug(std::shared_ptr<Display> display, Connection connected)
286{
287    if (connected == Connection::Connected) {
288        if (!display->isConnected()) {
289#ifndef BYPASS_IHWC
290            mComposer->setClientTargetSlotCount(display->getId());
291#endif
292            display->loadConfigs();
293            display->setConnected(true);
294        }
295    } else {
296        display->setConnected(false);
297        mDisplays.erase(display->getId());
298    }
299
300    if (mHotplug) {
301        mHotplug(std::move(display), connected);
302    } else {
303        ALOGV("callHotplug called, but no valid callback registered, storing");
304        mPendingHotplugs.emplace_back(std::move(display), connected);
305    }
306}
307
308void Device::callRefresh(std::shared_ptr<Display> display)
309{
310    if (mRefresh) {
311        mRefresh(std::move(display));
312    } else {
313        ALOGV("callRefresh called, but no valid callback registered, storing");
314        mPendingRefreshes.emplace_back(std::move(display));
315    }
316}
317
318void Device::callVsync(std::shared_ptr<Display> display, nsecs_t timestamp)
319{
320    if (mVsync) {
321        mVsync(std::move(display), timestamp);
322    } else {
323        ALOGV("callVsync called, but no valid callback registered, storing");
324        mPendingVsyncs.emplace_back(std::move(display), timestamp);
325    }
326}
327
328// Other Device methods
329
330std::shared_ptr<Display> Device::getDisplayById(hwc2_display_t id) {
331    if (mDisplays.count(id) != 0) {
332        auto strongDisplay = mDisplays[id].lock();
333        ALOGE_IF(!strongDisplay, "Display %" PRId64 " is in mDisplays but is no"
334                " longer alive", id);
335        return strongDisplay;
336    }
337
338    auto display = std::make_shared<Display>(*this, id);
339    mDisplays.emplace(id, display);
340    return display;
341}
342
343// Device initialization methods
344
345void Device::loadCapabilities()
346{
347    static_assert(sizeof(Capability) == sizeof(int32_t),
348            "Capability size has changed");
349#ifdef BYPASS_IHWC
350    uint32_t numCapabilities = 0;
351    mHwcDevice->getCapabilities(mHwcDevice, &numCapabilities, nullptr);
352    std::vector<Capability> capabilities(numCapabilities);
353    auto asInt = reinterpret_cast<int32_t*>(capabilities.data());
354    mHwcDevice->getCapabilities(mHwcDevice, &numCapabilities, asInt);
355    for (auto capability : capabilities) {
356        mCapabilities.emplace(capability);
357    }
358#else
359    auto capabilities = mComposer->getCapabilities();
360    for (auto capability : capabilities) {
361        mCapabilities.emplace(static_cast<Capability>(capability));
362    }
363#endif
364}
365
366bool Device::hasCapability(HWC2::Capability capability) const
367{
368    return std::find(mCapabilities.cbegin(), mCapabilities.cend(),
369            capability) != mCapabilities.cend();
370}
371
372void Device::loadFunctionPointers()
373{
374#ifdef BYPASS_IHWC
375    // For all of these early returns, we log an error message inside
376    // loadFunctionPointer specifying which function failed to load
377
378    // Display function pointers
379    if (!loadFunctionPointer(FunctionDescriptor::CreateVirtualDisplay,
380            mCreateVirtualDisplay)) return;
381    if (!loadFunctionPointer(FunctionDescriptor::DestroyVirtualDisplay,
382            mDestroyVirtualDisplay)) return;
383    if (!loadFunctionPointer(FunctionDescriptor::Dump, mDump)) return;
384    if (!loadFunctionPointer(FunctionDescriptor::GetMaxVirtualDisplayCount,
385            mGetMaxVirtualDisplayCount)) return;
386    if (!loadFunctionPointer(FunctionDescriptor::RegisterCallback,
387            mRegisterCallback)) return;
388
389    // Device function pointers
390    if (!loadFunctionPointer(FunctionDescriptor::AcceptDisplayChanges,
391            mAcceptDisplayChanges)) return;
392    if (!loadFunctionPointer(FunctionDescriptor::CreateLayer,
393            mCreateLayer)) return;
394    if (!loadFunctionPointer(FunctionDescriptor::DestroyLayer,
395            mDestroyLayer)) return;
396    if (!loadFunctionPointer(FunctionDescriptor::GetActiveConfig,
397            mGetActiveConfig)) return;
398    if (!loadFunctionPointer(FunctionDescriptor::GetChangedCompositionTypes,
399            mGetChangedCompositionTypes)) return;
400    if (!loadFunctionPointer(FunctionDescriptor::GetColorModes,
401            mGetColorModes)) return;
402    if (!loadFunctionPointer(FunctionDescriptor::GetDisplayAttribute,
403            mGetDisplayAttribute)) return;
404    if (!loadFunctionPointer(FunctionDescriptor::GetDisplayConfigs,
405            mGetDisplayConfigs)) return;
406    if (!loadFunctionPointer(FunctionDescriptor::GetDisplayName,
407            mGetDisplayName)) return;
408    if (!loadFunctionPointer(FunctionDescriptor::GetDisplayRequests,
409            mGetDisplayRequests)) return;
410    if (!loadFunctionPointer(FunctionDescriptor::GetDisplayType,
411            mGetDisplayType)) return;
412    if (!loadFunctionPointer(FunctionDescriptor::GetDozeSupport,
413            mGetDozeSupport)) return;
414    if (!loadFunctionPointer(FunctionDescriptor::GetHdrCapabilities,
415            mGetHdrCapabilities)) return;
416    if (!loadFunctionPointer(FunctionDescriptor::GetReleaseFences,
417            mGetReleaseFences)) return;
418    if (!loadFunctionPointer(FunctionDescriptor::PresentDisplay,
419            mPresentDisplay)) return;
420    if (!loadFunctionPointer(FunctionDescriptor::SetActiveConfig,
421            mSetActiveConfig)) return;
422    if (!loadFunctionPointer(FunctionDescriptor::SetClientTarget,
423            mSetClientTarget)) return;
424    if (!loadFunctionPointer(FunctionDescriptor::SetColorMode,
425            mSetColorMode)) return;
426    if (!loadFunctionPointer(FunctionDescriptor::SetColorTransform,
427            mSetColorTransform)) return;
428    if (!loadFunctionPointer(FunctionDescriptor::SetOutputBuffer,
429            mSetOutputBuffer)) return;
430    if (!loadFunctionPointer(FunctionDescriptor::SetPowerMode,
431            mSetPowerMode)) return;
432    if (!loadFunctionPointer(FunctionDescriptor::SetVsyncEnabled,
433            mSetVsyncEnabled)) return;
434    if (!loadFunctionPointer(FunctionDescriptor::ValidateDisplay,
435            mValidateDisplay)) return;
436
437    // Layer function pointers
438    if (!loadFunctionPointer(FunctionDescriptor::SetCursorPosition,
439            mSetCursorPosition)) return;
440    if (!loadFunctionPointer(FunctionDescriptor::SetLayerBuffer,
441            mSetLayerBuffer)) return;
442    if (!loadFunctionPointer(FunctionDescriptor::SetLayerSurfaceDamage,
443            mSetLayerSurfaceDamage)) return;
444    if (!loadFunctionPointer(FunctionDescriptor::SetLayerBlendMode,
445            mSetLayerBlendMode)) return;
446    if (!loadFunctionPointer(FunctionDescriptor::SetLayerColor,
447            mSetLayerColor)) return;
448    if (!loadFunctionPointer(FunctionDescriptor::SetLayerCompositionType,
449            mSetLayerCompositionType)) return;
450    if (!loadFunctionPointer(FunctionDescriptor::SetLayerDataspace,
451            mSetLayerDataspace)) return;
452    if (!loadFunctionPointer(FunctionDescriptor::SetLayerDisplayFrame,
453            mSetLayerDisplayFrame)) return;
454    if (!loadFunctionPointer(FunctionDescriptor::SetLayerPlaneAlpha,
455            mSetLayerPlaneAlpha)) return;
456    if (hasCapability(Capability::SidebandStream)) {
457        if (!loadFunctionPointer(FunctionDescriptor::SetLayerSidebandStream,
458                mSetLayerSidebandStream)) return;
459    }
460    if (!loadFunctionPointer(FunctionDescriptor::SetLayerSourceCrop,
461            mSetLayerSourceCrop)) return;
462    if (!loadFunctionPointer(FunctionDescriptor::SetLayerTransform,
463            mSetLayerTransform)) return;
464    if (!loadFunctionPointer(FunctionDescriptor::SetLayerVisibleRegion,
465            mSetLayerVisibleRegion)) return;
466    if (!loadFunctionPointer(FunctionDescriptor::SetLayerZOrder,
467            mSetLayerZOrder)) return;
468#endif // BYPASS_IHWC
469}
470
471namespace {
472class ComposerCallback : public Hwc2::IComposerCallback {
473public:
474    ComposerCallback(Device* device) : mDevice(device) {}
475
476    Return<void> onHotplug(Hwc2::Display display,
477            Connection connected) override
478    {
479        hotplug_hook(mDevice, display, static_cast<int32_t>(connected));
480        return Void();
481    }
482
483    Return<void> onRefresh(Hwc2::Display display) override
484    {
485        refresh_hook(mDevice, display);
486        return Void();
487    }
488
489    Return<void> onVsync(Hwc2::Display display, int64_t timestamp) override
490    {
491        vsync_hook(mDevice, display, timestamp);
492        return Void();
493    }
494
495private:
496    Device* mDevice;
497};
498} // namespace anonymous
499
500void Device::registerCallbacks()
501{
502#ifdef BYPASS_IHWC
503    registerCallback<HWC2_PFN_HOTPLUG>(Callback::Hotplug, hotplug_hook);
504    registerCallback<HWC2_PFN_REFRESH>(Callback::Refresh, refresh_hook);
505    registerCallback<HWC2_PFN_VSYNC>(Callback::Vsync, vsync_hook);
506#else
507    sp<ComposerCallback> callback = new ComposerCallback(this);
508    mComposer->registerCallback(callback);
509#endif
510}
511
512
513// For use by Display
514
515void Device::destroyVirtualDisplay(hwc2_display_t display)
516{
517    ALOGI("Destroying virtual display");
518#ifdef BYPASS_IHWC
519    int32_t intError = mDestroyVirtualDisplay(mHwcDevice, display);
520#else
521    auto intError = mComposer->destroyVirtualDisplay(display);
522#endif
523    auto error = static_cast<Error>(intError);
524    ALOGE_IF(error != Error::None, "destroyVirtualDisplay(%" PRIu64 ") failed:"
525            " %s (%d)", display, to_string(error).c_str(), intError);
526    mDisplays.erase(display);
527}
528
529// Display methods
530
531Display::Display(Device& device, hwc2_display_t id)
532  : mDevice(device),
533    mId(id),
534    mIsConnected(false),
535    mIsVirtual(false)
536{
537    ALOGV("Created display %" PRIu64, id);
538}
539
540Display::~Display()
541{
542    ALOGV("Destroyed display %" PRIu64, mId);
543    if (mIsVirtual) {
544        mDevice.destroyVirtualDisplay(mId);
545    }
546}
547
548Display::Config::Config(Display& display, hwc2_config_t id)
549  : mDisplay(display),
550    mId(id),
551    mWidth(-1),
552    mHeight(-1),
553    mVsyncPeriod(-1),
554    mDpiX(-1),
555    mDpiY(-1) {}
556
557Display::Config::Builder::Builder(Display& display, hwc2_config_t id)
558  : mConfig(new Config(display, id)) {}
559
560float Display::Config::Builder::getDefaultDensity() {
561    // Default density is based on TVs: 1080p displays get XHIGH density, lower-
562    // resolution displays get TV density. Maybe eventually we'll need to update
563    // it for 4k displays, though hopefully those will just report accurate DPI
564    // information to begin with. This is also used for virtual displays and
565    // older HWC implementations, so be careful about orientation.
566
567    auto longDimension = std::max(mConfig->mWidth, mConfig->mHeight);
568    if (longDimension >= 1080) {
569        return ACONFIGURATION_DENSITY_XHIGH;
570    } else {
571        return ACONFIGURATION_DENSITY_TV;
572    }
573}
574
575// Required by HWC2 display
576
577Error Display::acceptChanges()
578{
579#ifdef BYPASS_IHWC
580    int32_t intError = mDevice.mAcceptDisplayChanges(mDevice.mHwcDevice, mId);
581#else
582    auto intError = mDevice.mComposer->acceptDisplayChanges(mId);
583#endif
584    return static_cast<Error>(intError);
585}
586
587Error Display::createLayer(std::shared_ptr<Layer>* outLayer)
588{
589    hwc2_layer_t layerId = 0;
590#ifdef BYPASS_IHWC
591    int32_t intError = mDevice.mCreateLayer(mDevice.mHwcDevice, mId, &layerId);
592#else
593    auto intError = mDevice.mComposer->createLayer(mId, layerId);
594#endif
595    auto error = static_cast<Error>(intError);
596    if (error != Error::None) {
597        return error;
598    }
599
600    auto layer = std::make_shared<Layer>(shared_from_this(), layerId);
601    mLayers.emplace(layerId, layer);
602    *outLayer = std::move(layer);
603    return Error::None;
604}
605
606Error Display::getActiveConfig(
607        std::shared_ptr<const Display::Config>* outConfig) const
608{
609    ALOGV("[%" PRIu64 "] getActiveConfig", mId);
610    hwc2_config_t configId = 0;
611#ifdef BYPASS_IHWC
612    int32_t intError = mDevice.mGetActiveConfig(mDevice.mHwcDevice, mId,
613            &configId);
614#else
615    auto intError = mDevice.mComposer->getActiveConfig(mId, configId);
616#endif
617    auto error = static_cast<Error>(intError);
618
619    if (error != Error::None) {
620        ALOGE("Unable to get active config for mId:[%" PRIu64 "]", mId);
621        *outConfig = nullptr;
622        return error;
623    }
624
625    if (mConfigs.count(configId) != 0) {
626        *outConfig = mConfigs.at(configId);
627    } else {
628        ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId,
629                configId);
630        // Return no error, but the caller needs to check for a null pointer to
631        // detect this case
632        *outConfig = nullptr;
633    }
634
635    return Error::None;
636}
637
638Error Display::getChangedCompositionTypes(
639        std::unordered_map<std::shared_ptr<Layer>, Composition>* outTypes)
640{
641#ifdef BYPASS_IHWC
642    uint32_t numElements = 0;
643    int32_t intError = mDevice.mGetChangedCompositionTypes(mDevice.mHwcDevice,
644            mId, &numElements, nullptr, nullptr);
645    auto error = static_cast<Error>(intError);
646    if (error != Error::None) {
647        return error;
648    }
649
650    std::vector<hwc2_layer_t> layerIds(numElements);
651    std::vector<int32_t> types(numElements);
652    intError = mDevice.mGetChangedCompositionTypes(mDevice.mHwcDevice, mId,
653            &numElements, layerIds.data(), types.data());
654#else
655    std::vector<Hwc2::Layer> layerIds;
656    std::vector<Hwc2::IComposerClient::Composition> types;
657    auto intError = mDevice.mComposer->getChangedCompositionTypes(mId,
658            layerIds, types);
659    uint32_t numElements = layerIds.size();
660    auto error = static_cast<Error>(intError);
661#endif
662    error = static_cast<Error>(intError);
663    if (error != Error::None) {
664        return error;
665    }
666
667    outTypes->clear();
668    outTypes->reserve(numElements);
669    for (uint32_t element = 0; element < numElements; ++element) {
670        auto layer = getLayerById(layerIds[element]);
671        if (layer) {
672            auto type = static_cast<Composition>(types[element]);
673            ALOGV("getChangedCompositionTypes: adding %" PRIu64 " %s",
674                    layer->getId(), to_string(type).c_str());
675            outTypes->emplace(layer, type);
676        } else {
677            ALOGE("getChangedCompositionTypes: invalid layer %" PRIu64 " found"
678                    " on display %" PRIu64, layerIds[element], mId);
679        }
680    }
681
682    return Error::None;
683}
684
685Error Display::getColorModes(std::vector<android_color_mode_t>* outModes) const
686{
687#ifdef BYPASS_IHWC
688    uint32_t numModes = 0;
689    int32_t intError = mDevice.mGetColorModes(mDevice.mHwcDevice, mId,
690            &numModes, nullptr);
691    auto error = static_cast<Error>(intError);
692    if (error != Error::None)  {
693        return error;
694    }
695
696    std::vector<int32_t> modes(numModes);
697    intError = mDevice.mGetColorModes(mDevice.mHwcDevice, mId, &numModes,
698            modes.data());
699    error = static_cast<Error>(intError);
700#else
701    std::vector<Hwc2::ColorMode> modes;
702    auto intError = mDevice.mComposer->getColorModes(mId, modes);
703    uint32_t numModes = modes.size();
704    auto error = static_cast<Error>(intError);
705#endif
706    if (error != Error::None) {
707        return error;
708    }
709
710    outModes->resize(numModes);
711    for (size_t i = 0; i < numModes; i++) {
712        (*outModes)[i] = static_cast<android_color_mode_t>(modes[i]);
713    }
714    return Error::None;
715}
716
717std::vector<std::shared_ptr<const Display::Config>> Display::getConfigs() const
718{
719    std::vector<std::shared_ptr<const Config>> configs;
720    for (const auto& element : mConfigs) {
721        configs.emplace_back(element.second);
722    }
723    return configs;
724}
725
726Error Display::getName(std::string* outName) const
727{
728#ifdef BYPASS_IHWC
729    uint32_t size;
730    int32_t intError = mDevice.mGetDisplayName(mDevice.mHwcDevice, mId, &size,
731            nullptr);
732    auto error = static_cast<Error>(intError);
733    if (error != Error::None) {
734        return error;
735    }
736
737    std::vector<char> rawName(size);
738    intError = mDevice.mGetDisplayName(mDevice.mHwcDevice, mId, &size,
739            rawName.data());
740    error = static_cast<Error>(intError);
741    if (error != Error::None) {
742        return error;
743    }
744
745    *outName = std::string(rawName.cbegin(), rawName.cend());
746    return Error::None;
747#else
748    auto intError = mDevice.mComposer->getDisplayName(mId, *outName);
749    return static_cast<Error>(intError);
750#endif
751}
752
753Error Display::getRequests(HWC2::DisplayRequest* outDisplayRequests,
754        std::unordered_map<std::shared_ptr<Layer>, LayerRequest>*
755                outLayerRequests)
756{
757#ifdef BYPASS_IHWC
758    int32_t intDisplayRequests = 0;
759    uint32_t numElements = 0;
760    int32_t intError = mDevice.mGetDisplayRequests(mDevice.mHwcDevice, mId,
761            &intDisplayRequests, &numElements, nullptr, nullptr);
762    auto error = static_cast<Error>(intError);
763    if (error != Error::None) {
764        return error;
765    }
766
767    std::vector<hwc2_layer_t> layerIds(numElements);
768    std::vector<int32_t> layerRequests(numElements);
769    intError = mDevice.mGetDisplayRequests(mDevice.mHwcDevice, mId,
770            &intDisplayRequests, &numElements, layerIds.data(),
771            layerRequests.data());
772    error = static_cast<Error>(intError);
773#else
774    uint32_t intDisplayRequests;
775    std::vector<Hwc2::Layer> layerIds;
776    std::vector<uint32_t> layerRequests;
777    auto intError = mDevice.mComposer->getDisplayRequests(mId,
778            intDisplayRequests, layerIds, layerRequests);
779    uint32_t numElements = layerIds.size();
780    auto error = static_cast<Error>(intError);
781#endif
782    if (error != Error::None) {
783        return error;
784    }
785
786    *outDisplayRequests = static_cast<DisplayRequest>(intDisplayRequests);
787    outLayerRequests->clear();
788    outLayerRequests->reserve(numElements);
789    for (uint32_t element = 0; element < numElements; ++element) {
790        auto layer = getLayerById(layerIds[element]);
791        if (layer) {
792            auto layerRequest =
793                    static_cast<LayerRequest>(layerRequests[element]);
794            outLayerRequests->emplace(layer, layerRequest);
795        } else {
796            ALOGE("getRequests: invalid layer %" PRIu64 " found on display %"
797                    PRIu64, layerIds[element], mId);
798        }
799    }
800
801    return Error::None;
802}
803
804Error Display::getType(DisplayType* outType) const
805{
806#ifdef BYPASS_IHWC
807    int32_t intType = 0;
808    int32_t intError = mDevice.mGetDisplayType(mDevice.mHwcDevice, mId,
809            &intType);
810#else
811    Hwc2::IComposerClient::DisplayType intType =
812        Hwc2::IComposerClient::DisplayType::INVALID;
813    auto intError = mDevice.mComposer->getDisplayType(mId, intType);
814#endif
815    auto error = static_cast<Error>(intError);
816    if (error != Error::None) {
817        return error;
818    }
819
820    *outType = static_cast<DisplayType>(intType);
821    return Error::None;
822}
823
824Error Display::supportsDoze(bool* outSupport) const
825{
826#ifdef BYPASS_IHWC
827    int32_t intSupport = 0;
828    int32_t intError = mDevice.mGetDozeSupport(mDevice.mHwcDevice, mId,
829            &intSupport);
830#else
831    bool intSupport = false;
832    auto intError = mDevice.mComposer->getDozeSupport(mId, intSupport);
833#endif
834    auto error = static_cast<Error>(intError);
835    if (error != Error::None) {
836        return error;
837    }
838    *outSupport = static_cast<bool>(intSupport);
839    return Error::None;
840}
841
842Error Display::getHdrCapabilities(
843        std::unique_ptr<HdrCapabilities>* outCapabilities) const
844{
845    uint32_t numTypes = 0;
846    float maxLuminance = -1.0f;
847    float maxAverageLuminance = -1.0f;
848    float minLuminance = -1.0f;
849#ifdef BYPASS_IHWC
850    int32_t intError = mDevice.mGetHdrCapabilities(mDevice.mHwcDevice, mId,
851            &numTypes, nullptr, &maxLuminance, &maxAverageLuminance,
852            &minLuminance);
853    auto error = static_cast<HWC2::Error>(intError);
854    if (error != Error::None) {
855        return error;
856    }
857
858    std::vector<int32_t> types(numTypes);
859    intError = mDevice.mGetHdrCapabilities(mDevice.mHwcDevice, mId, &numTypes,
860            types.data(), &maxLuminance, &maxAverageLuminance, &minLuminance);
861    error = static_cast<HWC2::Error>(intError);
862#else
863    std::vector<Hwc2::Hdr> intTypes;
864    auto intError = mDevice.mComposer->getHdrCapabilities(mId, intTypes,
865            maxLuminance, maxAverageLuminance, minLuminance);
866    auto error = static_cast<HWC2::Error>(intError);
867
868    std::vector<int32_t> types;
869    for (auto type : intTypes) {
870        types.push_back(static_cast<int32_t>(type));
871    }
872    numTypes = types.size();
873#endif
874    if (error != Error::None) {
875        return error;
876    }
877
878    *outCapabilities = std::make_unique<HdrCapabilities>(std::move(types),
879            maxLuminance, maxAverageLuminance, minLuminance);
880    return Error::None;
881}
882
883Error Display::getReleaseFences(
884        std::unordered_map<std::shared_ptr<Layer>, sp<Fence>>* outFences) const
885{
886#ifdef BYPASS_IHWC
887    uint32_t numElements = 0;
888    int32_t intError = mDevice.mGetReleaseFences(mDevice.mHwcDevice, mId,
889            &numElements, nullptr, nullptr);
890    auto error = static_cast<Error>(intError);
891    if (error != Error::None) {
892        return error;
893    }
894
895    std::vector<hwc2_layer_t> layerIds(numElements);
896    std::vector<int32_t> fenceFds(numElements);
897    intError = mDevice.mGetReleaseFences(mDevice.mHwcDevice, mId, &numElements,
898            layerIds.data(), fenceFds.data());
899    error = static_cast<Error>(intError);
900#else
901    std::vector<Hwc2::Layer> layerIds;
902    std::vector<int> fenceFds;
903    auto intError = mDevice.mComposer->getReleaseFences(mId,
904            layerIds, fenceFds);
905    auto error = static_cast<Error>(intError);
906    uint32_t numElements = layerIds.size();
907#endif
908    if (error != Error::None) {
909        return error;
910    }
911
912    std::unordered_map<std::shared_ptr<Layer>, sp<Fence>> releaseFences;
913    releaseFences.reserve(numElements);
914    for (uint32_t element = 0; element < numElements; ++element) {
915        auto layer = getLayerById(layerIds[element]);
916        if (layer) {
917            sp<Fence> fence(new Fence(fenceFds[element]));
918            releaseFences.emplace(std::move(layer), fence);
919        } else {
920            ALOGE("getReleaseFences: invalid layer %" PRIu64
921                    " found on display %" PRIu64, layerIds[element], mId);
922            return Error::BadLayer;
923        }
924    }
925
926    *outFences = std::move(releaseFences);
927    return Error::None;
928}
929
930Error Display::present(sp<Fence>* outPresentFence)
931{
932    int32_t presentFenceFd = 0;
933#ifdef BYPASS_IHWC
934    int32_t intError = mDevice.mPresentDisplay(mDevice.mHwcDevice, mId,
935            &presentFenceFd);
936#else
937    auto intError = mDevice.mComposer->presentDisplay(mId, presentFenceFd);
938#endif
939    auto error = static_cast<Error>(intError);
940    if (error != Error::None) {
941        return error;
942    }
943
944    *outPresentFence = new Fence(presentFenceFd);
945    return Error::None;
946}
947
948Error Display::setActiveConfig(const std::shared_ptr<const Config>& config)
949{
950    if (config->getDisplayId() != mId) {
951        ALOGE("setActiveConfig received config %u for the wrong display %"
952                PRIu64 " (expected %" PRIu64 ")", config->getId(),
953                config->getDisplayId(), mId);
954        return Error::BadConfig;
955    }
956#ifdef BYPASS_IHWC
957    int32_t intError = mDevice.mSetActiveConfig(mDevice.mHwcDevice, mId,
958            config->getId());
959#else
960    auto intError = mDevice.mComposer->setActiveConfig(mId, config->getId());
961#endif
962    return static_cast<Error>(intError);
963}
964
965Error Display::setClientTarget(buffer_handle_t target,
966        const sp<Fence>& acquireFence, android_dataspace_t dataspace)
967{
968    // TODO: Properly encode client target surface damage
969    int32_t fenceFd = acquireFence->dup();
970#ifdef BYPASS_IHWC
971    int32_t intError = mDevice.mSetClientTarget(mDevice.mHwcDevice, mId, target,
972            fenceFd, static_cast<int32_t>(dataspace), {0, nullptr});
973#else
974    auto intError = mDevice.mComposer->setClientTarget(mId, target, fenceFd,
975            static_cast<Hwc2::Dataspace>(dataspace),
976            std::vector<Hwc2::IComposerClient::Rect>());
977#endif
978    return static_cast<Error>(intError);
979}
980
981Error Display::setColorMode(android_color_mode_t mode)
982{
983#ifdef BYPASS_IHWC
984    int32_t intError = mDevice.mSetColorMode(mDevice.mHwcDevice, mId, mode);
985#else
986    auto intError = mDevice.mComposer->setColorMode(mId,
987            static_cast<Hwc2::ColorMode>(mode));
988#endif
989    return static_cast<Error>(intError);
990}
991
992Error Display::setColorTransform(const android::mat4& matrix,
993        android_color_transform_t hint)
994{
995#ifdef BYPASS_IHWC
996    int32_t intError = mDevice.mSetColorTransform(mDevice.mHwcDevice, mId,
997            matrix.asArray(), static_cast<int32_t>(hint));
998#else
999    auto intError = mDevice.mComposer->setColorTransform(mId,
1000            matrix.asArray(), static_cast<Hwc2::ColorTransform>(hint));
1001#endif
1002    return static_cast<Error>(intError);
1003}
1004
1005Error Display::setOutputBuffer(const sp<GraphicBuffer>& buffer,
1006        const sp<Fence>& releaseFence)
1007{
1008    int32_t fenceFd = releaseFence->dup();
1009    auto handle = buffer->getNativeBuffer()->handle;
1010#ifdef BYPASS_IHWC
1011    int32_t intError = mDevice.mSetOutputBuffer(mDevice.mHwcDevice, mId, handle,
1012            fenceFd);
1013#else
1014    auto intError = mDevice.mComposer->setOutputBuffer(mId, handle, fenceFd);
1015#endif
1016    close(fenceFd);
1017    return static_cast<Error>(intError);
1018}
1019
1020Error Display::setPowerMode(PowerMode mode)
1021{
1022#ifdef BYPASS_IHWC
1023    auto intMode = static_cast<int32_t>(mode);
1024    int32_t intError = mDevice.mSetPowerMode(mDevice.mHwcDevice, mId, intMode);
1025#else
1026    auto intMode = static_cast<Hwc2::IComposerClient::PowerMode>(mode);
1027    auto intError = mDevice.mComposer->setPowerMode(mId, intMode);
1028#endif
1029    return static_cast<Error>(intError);
1030}
1031
1032Error Display::setVsyncEnabled(Vsync enabled)
1033{
1034#ifdef BYPASS_IHWC
1035    auto intEnabled = static_cast<int32_t>(enabled);
1036    int32_t intError = mDevice.mSetVsyncEnabled(mDevice.mHwcDevice, mId,
1037            intEnabled);
1038#else
1039    auto intEnabled = static_cast<Hwc2::IComposerClient::Vsync>(enabled);
1040    auto intError = mDevice.mComposer->setVsyncEnabled(mId, intEnabled);
1041#endif
1042    return static_cast<Error>(intError);
1043}
1044
1045Error Display::validate(uint32_t* outNumTypes, uint32_t* outNumRequests)
1046{
1047    uint32_t numTypes = 0;
1048    uint32_t numRequests = 0;
1049#ifdef BYPASS_IHWC
1050    int32_t intError = mDevice.mValidateDisplay(mDevice.mHwcDevice, mId,
1051            &numTypes, &numRequests);
1052#else
1053    auto intError = mDevice.mComposer->validateDisplay(mId,
1054            numTypes, numRequests);
1055#endif
1056    auto error = static_cast<Error>(intError);
1057    if (error != Error::None && error != Error::HasChanges) {
1058        return error;
1059    }
1060
1061    *outNumTypes = numTypes;
1062    *outNumRequests = numRequests;
1063    return error;
1064}
1065
1066// For use by Device
1067
1068int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute)
1069{
1070    int32_t value = 0;
1071#ifdef BYPASS_IHWC
1072    int32_t intError = mDevice.mGetDisplayAttribute(mDevice.mHwcDevice, mId,
1073            configId, static_cast<int32_t>(attribute), &value);
1074#else
1075    auto intError = mDevice.mComposer->getDisplayAttribute(mId,
1076            configId, static_cast<Hwc2::IComposerClient::Attribute>(attribute),
1077            value);
1078#endif
1079    auto error = static_cast<Error>(intError);
1080    if (error != Error::None) {
1081        ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId,
1082                configId, to_string(attribute).c_str(),
1083                to_string(error).c_str(), intError);
1084        return -1;
1085    }
1086    return value;
1087}
1088
1089void Display::loadConfig(hwc2_config_t configId)
1090{
1091    ALOGV("[%" PRIu64 "] loadConfig(%u)", mId, configId);
1092
1093    auto config = Config::Builder(*this, configId)
1094            .setWidth(getAttribute(configId, Attribute::Width))
1095            .setHeight(getAttribute(configId, Attribute::Height))
1096            .setVsyncPeriod(getAttribute(configId, Attribute::VsyncPeriod))
1097            .setDpiX(getAttribute(configId, Attribute::DpiX))
1098            .setDpiY(getAttribute(configId, Attribute::DpiY))
1099            .build();
1100    mConfigs.emplace(configId, std::move(config));
1101}
1102
1103void Display::loadConfigs()
1104{
1105    ALOGV("[%" PRIu64 "] loadConfigs", mId);
1106
1107#ifdef BYPASS_IHWC
1108    uint32_t numConfigs = 0;
1109    int32_t intError = mDevice.mGetDisplayConfigs(mDevice.mHwcDevice, mId,
1110            &numConfigs, nullptr);
1111    auto error = static_cast<Error>(intError);
1112    if (error != Error::None) {
1113        ALOGE("[%" PRIu64 "] getDisplayConfigs [1] failed: %s (%d)", mId,
1114                to_string(error).c_str(), intError);
1115        return;
1116    }
1117
1118    std::vector<hwc2_config_t> configIds(numConfigs);
1119    intError = mDevice.mGetDisplayConfigs(mDevice.mHwcDevice, mId, &numConfigs,
1120            configIds.data());
1121    error = static_cast<Error>(intError);
1122#else
1123    std::vector<Hwc2::Config> configIds;
1124    auto intError = mDevice.mComposer->getDisplayConfigs(mId, configIds);
1125    auto error = static_cast<Error>(intError);
1126#endif
1127    if (error != Error::None) {
1128        ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId,
1129                to_string(error).c_str(), intError);
1130        return;
1131    }
1132
1133    for (auto configId : configIds) {
1134        loadConfig(configId);
1135    }
1136}
1137
1138// For use by Layer
1139
1140void Display::destroyLayer(hwc2_layer_t layerId)
1141{
1142#ifdef BYPASS_IHWC
1143    int32_t intError = mDevice.mDestroyLayer(mDevice.mHwcDevice, mId, layerId);
1144#else
1145    auto intError =mDevice.mComposer->destroyLayer(mId, layerId);
1146#endif
1147    auto error = static_cast<Error>(intError);
1148    ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")"
1149            " failed: %s (%d)", mId, layerId, to_string(error).c_str(),
1150            intError);
1151    mLayers.erase(layerId);
1152}
1153
1154// Other Display methods
1155
1156std::shared_ptr<Layer> Display::getLayerById(hwc2_layer_t id) const
1157{
1158    if (mLayers.count(id) == 0) {
1159        return nullptr;
1160    }
1161
1162    auto layer = mLayers.at(id).lock();
1163    return layer;
1164}
1165
1166// Layer methods
1167
1168Layer::Layer(const std::shared_ptr<Display>& display, hwc2_layer_t id)
1169  : mDisplay(display),
1170    mDisplayId(display->getId()),
1171    mDevice(display->getDevice()),
1172    mId(id)
1173{
1174    ALOGV("Created layer %" PRIu64 " on display %" PRIu64, id,
1175            display->getId());
1176}
1177
1178Layer::~Layer()
1179{
1180    auto display = mDisplay.lock();
1181    if (display) {
1182        display->destroyLayer(mId);
1183    }
1184}
1185
1186Error Layer::setCursorPosition(int32_t x, int32_t y)
1187{
1188#ifdef BYPASS_IHWC
1189    int32_t intError = mDevice.mSetCursorPosition(mDevice.mHwcDevice,
1190            mDisplayId, mId, x, y);
1191#else
1192    auto intError = mDevice.mComposer->setCursorPosition(mDisplayId,
1193            mId, x, y);
1194#endif
1195    return static_cast<Error>(intError);
1196}
1197
1198Error Layer::setBuffer(buffer_handle_t buffer,
1199        const sp<Fence>& acquireFence)
1200{
1201    int32_t fenceFd = acquireFence->dup();
1202#ifdef BYPASS_IHWC
1203    int32_t intError = mDevice.mSetLayerBuffer(mDevice.mHwcDevice, mDisplayId,
1204            mId, buffer, fenceFd);
1205#else
1206    auto intError = mDevice.mComposer->setLayerBuffer(mDisplayId,
1207            mId, buffer, fenceFd);
1208#endif
1209    return static_cast<Error>(intError);
1210}
1211
1212Error Layer::setSurfaceDamage(const Region& damage)
1213{
1214    // We encode default full-screen damage as INVALID_RECT upstream, but as 0
1215    // rects for HWC
1216#ifdef BYPASS_IHWC
1217    int32_t intError = 0;
1218#else
1219    Hwc2::Error intError = Hwc2::Error::NONE;
1220#endif
1221    if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) {
1222#ifdef BYPASS_IHWC
1223        intError = mDevice.mSetLayerSurfaceDamage(mDevice.mHwcDevice,
1224                mDisplayId, mId, {0, nullptr});
1225#else
1226        intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId,
1227                mId, std::vector<Hwc2::IComposerClient::Rect>());
1228#endif
1229    } else {
1230        size_t rectCount = 0;
1231        auto rectArray = damage.getArray(&rectCount);
1232
1233#ifdef BYPASS_IHWC
1234        std::vector<hwc_rect_t> hwcRects;
1235#else
1236        std::vector<Hwc2::IComposerClient::Rect> hwcRects;
1237#endif
1238        for (size_t rect = 0; rect < rectCount; ++rect) {
1239            hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
1240                    rectArray[rect].right, rectArray[rect].bottom});
1241        }
1242
1243#ifdef BYPASS_IHWC
1244        hwc_region_t hwcRegion = {};
1245        hwcRegion.numRects = rectCount;
1246        hwcRegion.rects = hwcRects.data();
1247
1248        intError = mDevice.mSetLayerSurfaceDamage(mDevice.mHwcDevice,
1249                mDisplayId, mId, hwcRegion);
1250#else
1251        intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId,
1252                mId, hwcRects);
1253#endif
1254    }
1255
1256    return static_cast<Error>(intError);
1257}
1258
1259Error Layer::setBlendMode(BlendMode mode)
1260{
1261#ifdef BYPASS_IHWC
1262    auto intMode = static_cast<int32_t>(mode);
1263    int32_t intError = mDevice.mSetLayerBlendMode(mDevice.mHwcDevice,
1264            mDisplayId, mId, intMode);
1265#else
1266    auto intMode = static_cast<Hwc2::IComposerClient::BlendMode>(mode);
1267    auto intError = mDevice.mComposer->setLayerBlendMode(mDisplayId,
1268            mId, intMode);
1269#endif
1270    return static_cast<Error>(intError);
1271}
1272
1273Error Layer::setColor(hwc_color_t color)
1274{
1275#ifdef BYPASS_IHWC
1276    int32_t intError = mDevice.mSetLayerColor(mDevice.mHwcDevice, mDisplayId,
1277            mId, color);
1278#else
1279    Hwc2::IComposerClient::Color hwcColor{color.r, color.g, color.b, color.a};
1280    auto intError = mDevice.mComposer->setLayerColor(mDisplayId,
1281            mId, hwcColor);
1282#endif
1283    return static_cast<Error>(intError);
1284}
1285
1286Error Layer::setCompositionType(Composition type)
1287{
1288#ifdef BYPASS_IHWC
1289    auto intType = static_cast<int32_t>(type);
1290    int32_t intError = mDevice.mSetLayerCompositionType(mDevice.mHwcDevice,
1291            mDisplayId, mId, intType);
1292#else
1293    auto intType = static_cast<Hwc2::IComposerClient::Composition>(type);
1294    auto intError = mDevice.mComposer->setLayerCompositionType(mDisplayId,
1295            mId, intType);
1296#endif
1297    return static_cast<Error>(intError);
1298}
1299
1300Error Layer::setDataspace(android_dataspace_t dataspace)
1301{
1302#ifdef BYPASS_IHWC
1303    auto intDataspace = static_cast<int32_t>(dataspace);
1304    int32_t intError = mDevice.mSetLayerDataspace(mDevice.mHwcDevice,
1305            mDisplayId, mId, intDataspace);
1306#else
1307    auto intDataspace = static_cast<Hwc2::Dataspace>(dataspace);
1308    auto intError = mDevice.mComposer->setLayerDataspace(mDisplayId,
1309            mId, intDataspace);
1310#endif
1311    return static_cast<Error>(intError);
1312}
1313
1314Error Layer::setDisplayFrame(const Rect& frame)
1315{
1316#ifdef BYPASS_IHWC
1317    hwc_rect_t hwcRect{frame.left, frame.top, frame.right, frame.bottom};
1318    int32_t intError = mDevice.mSetLayerDisplayFrame(mDevice.mHwcDevice,
1319            mDisplayId, mId, hwcRect);
1320#else
1321    Hwc2::IComposerClient::Rect hwcRect{frame.left, frame.top,
1322        frame.right, frame.bottom};
1323    auto intError = mDevice.mComposer->setLayerDisplayFrame(mDisplayId,
1324            mId, hwcRect);
1325#endif
1326    return static_cast<Error>(intError);
1327}
1328
1329Error Layer::setPlaneAlpha(float alpha)
1330{
1331#ifdef BYPASS_IHWC
1332    int32_t intError = mDevice.mSetLayerPlaneAlpha(mDevice.mHwcDevice,
1333            mDisplayId, mId, alpha);
1334#else
1335    auto intError = mDevice.mComposer->setLayerPlaneAlpha(mDisplayId,
1336            mId, alpha);
1337#endif
1338    return static_cast<Error>(intError);
1339}
1340
1341Error Layer::setSidebandStream(const native_handle_t* stream)
1342{
1343    if (!mDevice.hasCapability(Capability::SidebandStream)) {
1344        ALOGE("Attempted to call setSidebandStream without checking that the "
1345                "device supports sideband streams");
1346        return Error::Unsupported;
1347    }
1348#ifdef BYPASS_IHWC
1349    int32_t intError = mDevice.mSetLayerSidebandStream(mDevice.mHwcDevice,
1350            mDisplayId, mId, stream);
1351#else
1352    auto intError = mDevice.mComposer->setLayerSidebandStream(mDisplayId,
1353            mId, stream);
1354#endif
1355    return static_cast<Error>(intError);
1356}
1357
1358Error Layer::setSourceCrop(const FloatRect& crop)
1359{
1360#ifdef BYPASS_IHWC
1361    hwc_frect_t hwcRect{crop.left, crop.top, crop.right, crop.bottom};
1362    int32_t intError = mDevice.mSetLayerSourceCrop(mDevice.mHwcDevice,
1363            mDisplayId, mId, hwcRect);
1364#else
1365    Hwc2::IComposerClient::FRect hwcRect{
1366        crop.left, crop.top, crop.right, crop.bottom};
1367    auto intError = mDevice.mComposer->setLayerSourceCrop(mDisplayId,
1368            mId, hwcRect);
1369#endif
1370    return static_cast<Error>(intError);
1371}
1372
1373Error Layer::setTransform(Transform transform)
1374{
1375#ifdef BYPASS_IHWC
1376    auto intTransform = static_cast<int32_t>(transform);
1377    int32_t intError = mDevice.mSetLayerTransform(mDevice.mHwcDevice,
1378            mDisplayId, mId, intTransform);
1379#else
1380    auto intTransform = static_cast<Hwc2::Transform>(transform);
1381    auto intError = mDevice.mComposer->setLayerTransform(mDisplayId,
1382            mId, intTransform);
1383#endif
1384    return static_cast<Error>(intError);
1385}
1386
1387Error Layer::setVisibleRegion(const Region& region)
1388{
1389    size_t rectCount = 0;
1390    auto rectArray = region.getArray(&rectCount);
1391
1392#ifdef BYPASS_IHWC
1393    std::vector<hwc_rect_t> hwcRects;
1394#else
1395    std::vector<Hwc2::IComposerClient::Rect> hwcRects;
1396#endif
1397    for (size_t rect = 0; rect < rectCount; ++rect) {
1398        hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
1399                rectArray[rect].right, rectArray[rect].bottom});
1400    }
1401
1402#ifdef BYPASS_IHWC
1403    hwc_region_t hwcRegion = {};
1404    hwcRegion.numRects = rectCount;
1405    hwcRegion.rects = hwcRects.data();
1406
1407    int32_t intError = mDevice.mSetLayerVisibleRegion(mDevice.mHwcDevice,
1408            mDisplayId, mId, hwcRegion);
1409#else
1410    auto intError = mDevice.mComposer->setLayerVisibleRegion(mDisplayId,
1411            mId, hwcRects);
1412#endif
1413    return static_cast<Error>(intError);
1414}
1415
1416Error Layer::setZOrder(uint32_t z)
1417{
1418#ifdef BYPASS_IHWC
1419    int32_t intError = mDevice.mSetLayerZOrder(mDevice.mHwcDevice, mDisplayId,
1420            mId, z);
1421#else
1422    auto intError = mDevice.mComposer->setLayerZOrder(mDisplayId, mId, z);
1423#endif
1424    return static_cast<Error>(intError);
1425}
1426
1427} // namespace HWC2
1428