HWC2.cpp revision 87670ffe26079eb50b62f698eb0f7bfa8ee51deb
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 <gfx/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::GraphicBuffer;
78using android::HdrCapabilities;
79using android::Rect;
80using android::Region;
81using android::sp;
82using android::gfx::FloatRect;
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(bool useVrComposer)
139  : mComposer(std::make_unique<Hwc2::Composer>(useVrComposer)),
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 = -1;
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(uint32_t slot, 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    (void) slot;
972    int32_t intError = mDevice.mSetClientTarget(mDevice.mHwcDevice, mId, target,
973            fenceFd, static_cast<int32_t>(dataspace), {0, nullptr});
974#else
975    auto intError = mDevice.mComposer->setClientTarget(mId, slot, target,
976            fenceFd, static_cast<Hwc2::Dataspace>(dataspace),
977            std::vector<Hwc2::IComposerClient::Rect>());
978#endif
979    return static_cast<Error>(intError);
980}
981
982Error Display::setColorMode(android_color_mode_t mode)
983{
984#ifdef BYPASS_IHWC
985    int32_t intError = mDevice.mSetColorMode(mDevice.mHwcDevice, mId, mode);
986#else
987    auto intError = mDevice.mComposer->setColorMode(mId,
988            static_cast<Hwc2::ColorMode>(mode));
989#endif
990    return static_cast<Error>(intError);
991}
992
993Error Display::setColorTransform(const android::mat4& matrix,
994        android_color_transform_t hint)
995{
996#ifdef BYPASS_IHWC
997    int32_t intError = mDevice.mSetColorTransform(mDevice.mHwcDevice, mId,
998            matrix.asArray(), static_cast<int32_t>(hint));
999#else
1000    auto intError = mDevice.mComposer->setColorTransform(mId,
1001            matrix.asArray(), static_cast<Hwc2::ColorTransform>(hint));
1002#endif
1003    return static_cast<Error>(intError);
1004}
1005
1006Error Display::setOutputBuffer(const sp<GraphicBuffer>& buffer,
1007        const sp<Fence>& releaseFence)
1008{
1009    int32_t fenceFd = releaseFence->dup();
1010    auto handle = buffer->getNativeBuffer()->handle;
1011#ifdef BYPASS_IHWC
1012    int32_t intError = mDevice.mSetOutputBuffer(mDevice.mHwcDevice, mId, handle,
1013            fenceFd);
1014#else
1015    auto intError = mDevice.mComposer->setOutputBuffer(mId, handle, fenceFd);
1016#endif
1017    close(fenceFd);
1018    return static_cast<Error>(intError);
1019}
1020
1021Error Display::setPowerMode(PowerMode mode)
1022{
1023#ifdef BYPASS_IHWC
1024    auto intMode = static_cast<int32_t>(mode);
1025    int32_t intError = mDevice.mSetPowerMode(mDevice.mHwcDevice, mId, intMode);
1026#else
1027    auto intMode = static_cast<Hwc2::IComposerClient::PowerMode>(mode);
1028    auto intError = mDevice.mComposer->setPowerMode(mId, intMode);
1029#endif
1030    return static_cast<Error>(intError);
1031}
1032
1033Error Display::setVsyncEnabled(Vsync enabled)
1034{
1035#ifdef BYPASS_IHWC
1036    auto intEnabled = static_cast<int32_t>(enabled);
1037    int32_t intError = mDevice.mSetVsyncEnabled(mDevice.mHwcDevice, mId,
1038            intEnabled);
1039#else
1040    auto intEnabled = static_cast<Hwc2::IComposerClient::Vsync>(enabled);
1041    auto intError = mDevice.mComposer->setVsyncEnabled(mId, intEnabled);
1042#endif
1043    return static_cast<Error>(intError);
1044}
1045
1046Error Display::validate(uint32_t* outNumTypes, uint32_t* outNumRequests)
1047{
1048    uint32_t numTypes = 0;
1049    uint32_t numRequests = 0;
1050#ifdef BYPASS_IHWC
1051    int32_t intError = mDevice.mValidateDisplay(mDevice.mHwcDevice, mId,
1052            &numTypes, &numRequests);
1053#else
1054    auto intError = mDevice.mComposer->validateDisplay(mId,
1055            &numTypes, &numRequests);
1056#endif
1057    auto error = static_cast<Error>(intError);
1058    if (error != Error::None && error != Error::HasChanges) {
1059        return error;
1060    }
1061
1062    *outNumTypes = numTypes;
1063    *outNumRequests = numRequests;
1064    return error;
1065}
1066
1067// For use by Device
1068
1069int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute)
1070{
1071    int32_t value = 0;
1072#ifdef BYPASS_IHWC
1073    int32_t intError = mDevice.mGetDisplayAttribute(mDevice.mHwcDevice, mId,
1074            configId, static_cast<int32_t>(attribute), &value);
1075#else
1076    auto intError = mDevice.mComposer->getDisplayAttribute(mId, configId,
1077            static_cast<Hwc2::IComposerClient::Attribute>(attribute),
1078            &value);
1079#endif
1080    auto error = static_cast<Error>(intError);
1081    if (error != Error::None) {
1082        ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId,
1083                configId, to_string(attribute).c_str(),
1084                to_string(error).c_str(), intError);
1085        return -1;
1086    }
1087    return value;
1088}
1089
1090void Display::loadConfig(hwc2_config_t configId)
1091{
1092    ALOGV("[%" PRIu64 "] loadConfig(%u)", mId, configId);
1093
1094    auto config = Config::Builder(*this, configId)
1095            .setWidth(getAttribute(configId, Attribute::Width))
1096            .setHeight(getAttribute(configId, Attribute::Height))
1097            .setVsyncPeriod(getAttribute(configId, Attribute::VsyncPeriod))
1098            .setDpiX(getAttribute(configId, Attribute::DpiX))
1099            .setDpiY(getAttribute(configId, Attribute::DpiY))
1100            .build();
1101    mConfigs.emplace(configId, std::move(config));
1102}
1103
1104void Display::loadConfigs()
1105{
1106    ALOGV("[%" PRIu64 "] loadConfigs", mId);
1107
1108#ifdef BYPASS_IHWC
1109    uint32_t numConfigs = 0;
1110    int32_t intError = mDevice.mGetDisplayConfigs(mDevice.mHwcDevice, mId,
1111            &numConfigs, nullptr);
1112    auto error = static_cast<Error>(intError);
1113    if (error != Error::None) {
1114        ALOGE("[%" PRIu64 "] getDisplayConfigs [1] failed: %s (%d)", mId,
1115                to_string(error).c_str(), intError);
1116        return;
1117    }
1118
1119    std::vector<hwc2_config_t> configIds(numConfigs);
1120    intError = mDevice.mGetDisplayConfigs(mDevice.mHwcDevice, mId, &numConfigs,
1121            configIds.data());
1122    error = static_cast<Error>(intError);
1123#else
1124    std::vector<Hwc2::Config> configIds;
1125    auto intError = mDevice.mComposer->getDisplayConfigs(mId, &configIds);
1126    auto error = static_cast<Error>(intError);
1127#endif
1128    if (error != Error::None) {
1129        ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId,
1130                to_string(error).c_str(), intError);
1131        return;
1132    }
1133
1134    for (auto configId : configIds) {
1135        loadConfig(configId);
1136    }
1137}
1138
1139// For use by Layer
1140
1141void Display::destroyLayer(hwc2_layer_t layerId)
1142{
1143#ifdef BYPASS_IHWC
1144    int32_t intError = mDevice.mDestroyLayer(mDevice.mHwcDevice, mId, layerId);
1145#else
1146    auto intError =mDevice.mComposer->destroyLayer(mId, layerId);
1147#endif
1148    auto error = static_cast<Error>(intError);
1149    ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")"
1150            " failed: %s (%d)", mId, layerId, to_string(error).c_str(),
1151            intError);
1152    mLayers.erase(layerId);
1153}
1154
1155// Other Display methods
1156
1157std::shared_ptr<Layer> Display::getLayerById(hwc2_layer_t id) const
1158{
1159    if (mLayers.count(id) == 0) {
1160        return nullptr;
1161    }
1162
1163    auto layer = mLayers.at(id).lock();
1164    return layer;
1165}
1166
1167// Layer methods
1168
1169Layer::Layer(const std::shared_ptr<Display>& display, hwc2_layer_t id)
1170  : mDisplay(display),
1171    mDisplayId(display->getId()),
1172    mDevice(display->getDevice()),
1173    mId(id)
1174{
1175    ALOGV("Created layer %" PRIu64 " on display %" PRIu64, id,
1176            display->getId());
1177}
1178
1179Layer::~Layer()
1180{
1181    auto display = mDisplay.lock();
1182    if (display) {
1183        display->destroyLayer(mId);
1184    }
1185}
1186
1187Error Layer::setCursorPosition(int32_t x, int32_t y)
1188{
1189#ifdef BYPASS_IHWC
1190    int32_t intError = mDevice.mSetCursorPosition(mDevice.mHwcDevice,
1191            mDisplayId, mId, x, y);
1192#else
1193    auto intError = mDevice.mComposer->setCursorPosition(mDisplayId,
1194            mId, x, y);
1195#endif
1196    return static_cast<Error>(intError);
1197}
1198
1199Error Layer::setBuffer(uint32_t slot, buffer_handle_t buffer,
1200        const sp<Fence>& acquireFence)
1201{
1202    int32_t fenceFd = acquireFence->dup();
1203#ifdef BYPASS_IHWC
1204    (void) slot;
1205    int32_t intError = mDevice.mSetLayerBuffer(mDevice.mHwcDevice, mDisplayId,
1206            mId, buffer, fenceFd);
1207#else
1208    auto intError = mDevice.mComposer->setLayerBuffer(mDisplayId,
1209            mId, slot, buffer, fenceFd);
1210#endif
1211    return static_cast<Error>(intError);
1212}
1213
1214Error Layer::setSurfaceDamage(const Region& damage)
1215{
1216    // We encode default full-screen damage as INVALID_RECT upstream, but as 0
1217    // rects for HWC
1218#ifdef BYPASS_IHWC
1219    int32_t intError = 0;
1220#else
1221    Hwc2::Error intError = Hwc2::Error::NONE;
1222#endif
1223    if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) {
1224#ifdef BYPASS_IHWC
1225        intError = mDevice.mSetLayerSurfaceDamage(mDevice.mHwcDevice,
1226                mDisplayId, mId, {0, nullptr});
1227#else
1228        intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId,
1229                mId, std::vector<Hwc2::IComposerClient::Rect>());
1230#endif
1231    } else {
1232        size_t rectCount = 0;
1233        auto rectArray = damage.getArray(&rectCount);
1234
1235#ifdef BYPASS_IHWC
1236        std::vector<hwc_rect_t> hwcRects;
1237#else
1238        std::vector<Hwc2::IComposerClient::Rect> hwcRects;
1239#endif
1240        for (size_t rect = 0; rect < rectCount; ++rect) {
1241            hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
1242                    rectArray[rect].right, rectArray[rect].bottom});
1243        }
1244
1245#ifdef BYPASS_IHWC
1246        hwc_region_t hwcRegion = {};
1247        hwcRegion.numRects = rectCount;
1248        hwcRegion.rects = hwcRects.data();
1249
1250        intError = mDevice.mSetLayerSurfaceDamage(mDevice.mHwcDevice,
1251                mDisplayId, mId, hwcRegion);
1252#else
1253        intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId,
1254                mId, hwcRects);
1255#endif
1256    }
1257
1258    return static_cast<Error>(intError);
1259}
1260
1261Error Layer::setBlendMode(BlendMode mode)
1262{
1263#ifdef BYPASS_IHWC
1264    auto intMode = static_cast<int32_t>(mode);
1265    int32_t intError = mDevice.mSetLayerBlendMode(mDevice.mHwcDevice,
1266            mDisplayId, mId, intMode);
1267#else
1268    auto intMode = static_cast<Hwc2::IComposerClient::BlendMode>(mode);
1269    auto intError = mDevice.mComposer->setLayerBlendMode(mDisplayId,
1270            mId, intMode);
1271#endif
1272    return static_cast<Error>(intError);
1273}
1274
1275Error Layer::setColor(hwc_color_t color)
1276{
1277#ifdef BYPASS_IHWC
1278    int32_t intError = mDevice.mSetLayerColor(mDevice.mHwcDevice, mDisplayId,
1279            mId, color);
1280#else
1281    Hwc2::IComposerClient::Color hwcColor{color.r, color.g, color.b, color.a};
1282    auto intError = mDevice.mComposer->setLayerColor(mDisplayId,
1283            mId, hwcColor);
1284#endif
1285    return static_cast<Error>(intError);
1286}
1287
1288Error Layer::setCompositionType(Composition type)
1289{
1290#ifdef BYPASS_IHWC
1291    auto intType = static_cast<int32_t>(type);
1292    int32_t intError = mDevice.mSetLayerCompositionType(mDevice.mHwcDevice,
1293            mDisplayId, mId, intType);
1294#else
1295    auto intType = static_cast<Hwc2::IComposerClient::Composition>(type);
1296    auto intError = mDevice.mComposer->setLayerCompositionType(mDisplayId,
1297            mId, intType);
1298#endif
1299    return static_cast<Error>(intError);
1300}
1301
1302Error Layer::setDataspace(android_dataspace_t dataspace)
1303{
1304#ifdef BYPASS_IHWC
1305    auto intDataspace = static_cast<int32_t>(dataspace);
1306    int32_t intError = mDevice.mSetLayerDataspace(mDevice.mHwcDevice,
1307            mDisplayId, mId, intDataspace);
1308#else
1309    auto intDataspace = static_cast<Hwc2::Dataspace>(dataspace);
1310    auto intError = mDevice.mComposer->setLayerDataspace(mDisplayId,
1311            mId, intDataspace);
1312#endif
1313    return static_cast<Error>(intError);
1314}
1315
1316Error Layer::setDisplayFrame(const Rect& frame)
1317{
1318#ifdef BYPASS_IHWC
1319    hwc_rect_t hwcRect{frame.left, frame.top, frame.right, frame.bottom};
1320    int32_t intError = mDevice.mSetLayerDisplayFrame(mDevice.mHwcDevice,
1321            mDisplayId, mId, hwcRect);
1322#else
1323    Hwc2::IComposerClient::Rect hwcRect{frame.left, frame.top,
1324        frame.right, frame.bottom};
1325    auto intError = mDevice.mComposer->setLayerDisplayFrame(mDisplayId,
1326            mId, hwcRect);
1327#endif
1328    return static_cast<Error>(intError);
1329}
1330
1331Error Layer::setPlaneAlpha(float alpha)
1332{
1333#ifdef BYPASS_IHWC
1334    int32_t intError = mDevice.mSetLayerPlaneAlpha(mDevice.mHwcDevice,
1335            mDisplayId, mId, alpha);
1336#else
1337    auto intError = mDevice.mComposer->setLayerPlaneAlpha(mDisplayId,
1338            mId, alpha);
1339#endif
1340    return static_cast<Error>(intError);
1341}
1342
1343Error Layer::setSidebandStream(const native_handle_t* stream)
1344{
1345    if (!mDevice.hasCapability(Capability::SidebandStream)) {
1346        ALOGE("Attempted to call setSidebandStream without checking that the "
1347                "device supports sideband streams");
1348        return Error::Unsupported;
1349    }
1350#ifdef BYPASS_IHWC
1351    int32_t intError = mDevice.mSetLayerSidebandStream(mDevice.mHwcDevice,
1352            mDisplayId, mId, stream);
1353#else
1354    auto intError = mDevice.mComposer->setLayerSidebandStream(mDisplayId,
1355            mId, stream);
1356#endif
1357    return static_cast<Error>(intError);
1358}
1359
1360Error Layer::setSourceCrop(const FloatRect& crop)
1361{
1362#ifdef BYPASS_IHWC
1363    hwc_frect_t hwcRect{crop.left, crop.top, crop.right, crop.bottom};
1364    int32_t intError = mDevice.mSetLayerSourceCrop(mDevice.mHwcDevice,
1365            mDisplayId, mId, hwcRect);
1366#else
1367    Hwc2::IComposerClient::FRect hwcRect{
1368        crop.left, crop.top, crop.right, crop.bottom};
1369    auto intError = mDevice.mComposer->setLayerSourceCrop(mDisplayId,
1370            mId, hwcRect);
1371#endif
1372    return static_cast<Error>(intError);
1373}
1374
1375Error Layer::setTransform(Transform transform)
1376{
1377#ifdef BYPASS_IHWC
1378    auto intTransform = static_cast<int32_t>(transform);
1379    int32_t intError = mDevice.mSetLayerTransform(mDevice.mHwcDevice,
1380            mDisplayId, mId, intTransform);
1381#else
1382    auto intTransform = static_cast<Hwc2::Transform>(transform);
1383    auto intError = mDevice.mComposer->setLayerTransform(mDisplayId,
1384            mId, intTransform);
1385#endif
1386    return static_cast<Error>(intError);
1387}
1388
1389Error Layer::setVisibleRegion(const Region& region)
1390{
1391    size_t rectCount = 0;
1392    auto rectArray = region.getArray(&rectCount);
1393
1394#ifdef BYPASS_IHWC
1395    std::vector<hwc_rect_t> hwcRects;
1396#else
1397    std::vector<Hwc2::IComposerClient::Rect> hwcRects;
1398#endif
1399    for (size_t rect = 0; rect < rectCount; ++rect) {
1400        hwcRects.push_back({rectArray[rect].left, rectArray[rect].top,
1401                rectArray[rect].right, rectArray[rect].bottom});
1402    }
1403
1404#ifdef BYPASS_IHWC
1405    hwc_region_t hwcRegion = {};
1406    hwcRegion.numRects = rectCount;
1407    hwcRegion.rects = hwcRects.data();
1408
1409    int32_t intError = mDevice.mSetLayerVisibleRegion(mDevice.mHwcDevice,
1410            mDisplayId, mId, hwcRegion);
1411#else
1412    auto intError = mDevice.mComposer->setLayerVisibleRegion(mDisplayId,
1413            mId, hwcRects);
1414#endif
1415    return static_cast<Error>(intError);
1416}
1417
1418Error Layer::setZOrder(uint32_t z)
1419{
1420#ifdef BYPASS_IHWC
1421    int32_t intError = mDevice.mSetLayerZOrder(mDevice.mHwcDevice, mDisplayId,
1422            mId, z);
1423#else
1424    auto intError = mDevice.mComposer->setLayerZOrder(mDisplayId, mId, z);
1425#endif
1426    return static_cast<Error>(intError);
1427}
1428
1429Error Layer::setInfo(uint32_t type, uint32_t appId)
1430{
1431#ifdef BYPASS_IHWC
1432  (void)type;
1433  (void)appId;
1434  int32_t intError = 0;
1435#else
1436  auto intError = mDevice.mComposer->setLayerInfo(mDisplayId, mId, type, appId);
1437#endif
1438  return static_cast<Error>(intError);
1439}
1440
1441} // namespace HWC2
1442