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