1c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza/*
2c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza * Copyright 2015 The Android Open Source Project
3c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza *
4c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza * Licensed under the Apache License, Version 2.0 (the "License");
5c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza * you may not use this file except in compliance with the License.
6c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza * You may obtain a copy of the License at
7c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza *
8c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza *      http://www.apache.org/licenses/LICENSE-2.0
9c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza *
10c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza * Unless required by applicable law or agreed to in writing, software
11c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza * distributed under the License is distributed on an "AS IS" BASIS,
12c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza * See the License for the specific language governing permissions and
14c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza * limitations under the License.
15c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza */
16c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
17c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza//#define LOG_NDEBUG 0
18c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
19c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza#undef LOG_TAG
20c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza#define LOG_TAG "HWC2On1Adapter"
21c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza#define ATRACE_TAG ATRACE_TAG_GRAPHICS
22c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
23c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza#include "HWC2On1Adapter.h"
24c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
25c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza#include <hardware/hwcomposer.h>
26c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza#include <log/log.h>
27c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza#include <utils/Trace.h>
28c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
29c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza#include <cstdlib>
30c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza#include <chrono>
31c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza#include <inttypes.h>
32c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza#include <sstream>
33c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
34c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozausing namespace std::chrono_literals;
35c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
36c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic bool operator==(const hwc_color_t& lhs, const hwc_color_t& rhs) {
37c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return lhs.r == rhs.r &&
38c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            lhs.g == rhs.g &&
39c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            lhs.b == rhs.b &&
40c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            lhs.a == rhs.a;
41c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
42c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
43c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic bool operator==(const hwc_rect_t& lhs, const hwc_rect_t& rhs) {
44c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return lhs.left == rhs.left &&
45c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            lhs.top == rhs.top &&
46c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            lhs.right == rhs.right &&
47c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            lhs.bottom == rhs.bottom;
48c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
49c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
50c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic bool operator==(const hwc_frect_t& lhs, const hwc_frect_t& rhs) {
51c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return lhs.left == rhs.left &&
52c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            lhs.top == rhs.top &&
53c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            lhs.right == rhs.right &&
54c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            lhs.bottom == rhs.bottom;
55c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
56c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
57c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozatemplate <typename T>
58c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic inline bool operator!=(const T& lhs, const T& rhs)
59c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
60c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return !(lhs == rhs);
61c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
62c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
63c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic uint8_t getMinorVersion(struct hwc_composer_device_1* device)
64c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
65c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto version = device->common.version & HARDWARE_API_VERSION_2_MAJ_MIN_MASK;
66c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return (version >> 16) & 0xF;
67c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
68c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
69c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozatemplate <typename PFN, typename T>
70c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic hwc2_function_pointer_t asFP(T function)
71c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
72c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
73c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return reinterpret_cast<hwc2_function_pointer_t>(function);
74c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
75c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
76c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozausing namespace HWC2;
77c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
78076ac670262e448c531e6db7727cfade325866caDan Stozastatic constexpr Attribute ColorTransform = static_cast<Attribute>(6);
79076ac670262e448c531e6db7727cfade325866caDan Stoza
80c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozanamespace android {
81c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
82c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::DisplayContentsDeleter::operator()(
83c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc_display_contents_1_t* contents)
84c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
85c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (contents != nullptr) {
86c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (size_t l = 0; l < contents->numHwLayers; ++l) {
87c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto& layer = contents->hwLayers[l];
88c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            std::free(const_cast<hwc_rect_t*>(layer.visibleRegionScreen.rects));
89c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
90c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
91c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::free(contents);
92c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
93c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
94c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozaclass HWC2On1Adapter::Callbacks : public hwc_procs_t {
95c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    public:
96c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        Callbacks(HWC2On1Adapter& adapter) : mAdapter(adapter) {
97c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            invalidate = &invalidateHook;
98c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            vsync = &vsyncHook;
99c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            hotplug = &hotplugHook;
100c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
101c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
102c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        static void invalidateHook(const hwc_procs_t* procs) {
103c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto callbacks = static_cast<const Callbacks*>(procs);
104c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            callbacks->mAdapter.hwc1Invalidate();
105c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
106c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
107c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        static void vsyncHook(const hwc_procs_t* procs, int display,
108c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                int64_t timestamp) {
109c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto callbacks = static_cast<const Callbacks*>(procs);
110c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            callbacks->mAdapter.hwc1Vsync(display, timestamp);
111c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
112c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
113c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        static void hotplugHook(const hwc_procs_t* procs, int display,
114c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                int connected) {
115c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto callbacks = static_cast<const Callbacks*>(procs);
116c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            callbacks->mAdapter.hwc1Hotplug(display, connected);
117c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
118c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
119c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    private:
120c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        HWC2On1Adapter& mAdapter;
121c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza};
122c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
123c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic int closeHook(hw_device_t* /*device*/)
124c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
125c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Do nothing, since the real work is done in the class destructor, but we
126c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // need to provide a valid function pointer for hwc2_close to call
127c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return 0;
128c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
129c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
130c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaHWC2On1Adapter::HWC2On1Adapter(hwc_composer_device_1_t* hwc1Device)
131c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza  : mDumpString(),
132c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1Device(hwc1Device),
133c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1MinorVersion(getMinorVersion(hwc1Device)),
134c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1SupportsVirtualDisplays(false),
135c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1Callbacks(std::make_unique<Callbacks>(*this)),
136c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mCapabilities(),
137c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mLayers(),
138c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1VirtualDisplay(),
139c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mStateMutex(),
140c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mCallbacks(),
141c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHasPendingInvalidate(false),
142c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mPendingVsyncs(),
143c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mPendingHotplugs(),
144c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDisplays(),
145c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1DisplayMap()
146c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
147c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    common.close = closeHook;
148c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    getCapabilities = getCapabilitiesHook;
149c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    getFunction = getFunctionHook;
150c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    populateCapabilities();
151c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    populatePrimary();
152c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1Device->registerProcs(mHwc1Device,
153c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            static_cast<const hwc_procs_t*>(mHwc1Callbacks.get()));
154c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
155c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
156c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaHWC2On1Adapter::~HWC2On1Adapter() {
157c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc_close_1(mHwc1Device);
158c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
159c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
160c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::doGetCapabilities(uint32_t* outCount,
161c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        int32_t* outCapabilities)
162c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
163c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (outCapabilities == nullptr) {
164c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        *outCount = mCapabilities.size();
165c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
166c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
167c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
168c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto capabilityIter = mCapabilities.cbegin();
169c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t written = 0; written < *outCount; ++written) {
170c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (capabilityIter == mCapabilities.cend()) {
171c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return;
172c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
173c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        outCapabilities[written] = static_cast<int32_t>(*capabilityIter);
174c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ++capabilityIter;
175c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
176c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
177c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
178c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozahwc2_function_pointer_t HWC2On1Adapter::doGetFunction(
179c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        FunctionDescriptor descriptor)
180c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
181c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (descriptor) {
182c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Device functions
183c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::CreateVirtualDisplay:
184c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
185c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    createVirtualDisplayHook);
186c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::DestroyVirtualDisplay:
187c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
188c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    destroyVirtualDisplayHook);
189c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::Dump:
190c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_DUMP>(dumpHook);
191c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetMaxVirtualDisplayCount:
192c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
193c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    getMaxVirtualDisplayCountHook);
194c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::RegisterCallback:
195c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_REGISTER_CALLBACK>(registerCallbackHook);
196c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
197c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Display functions
198c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::AcceptDisplayChanges:
199c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(
200c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::acceptChanges),
201c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::acceptChanges>);
202c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::CreateLayer:
203c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_CREATE_LAYER>(
204c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::createLayer),
205c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::createLayer, hwc2_layer_t*>);
206c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::DestroyLayer:
207c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_DESTROY_LAYER>(
208c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::destroyLayer),
209c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::destroyLayer, hwc2_layer_t>);
210c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetActiveConfig:
211c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_ACTIVE_CONFIG>(
212c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::getActiveConfig),
213c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::getActiveConfig, hwc2_config_t*>);
214c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetChangedCompositionTypes:
215c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(
216c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::getChangedCompositionTypes),
217c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::getChangedCompositionTypes, uint32_t*,
218c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    hwc2_layer_t*, int32_t*>);
219076ac670262e448c531e6db7727cfade325866caDan Stoza        case FunctionDescriptor::GetColorModes:
220076ac670262e448c531e6db7727cfade325866caDan Stoza            return asFP<HWC2_PFN_GET_COLOR_MODES>(
221076ac670262e448c531e6db7727cfade325866caDan Stoza                    displayHook<decltype(&Display::getColorModes),
222076ac670262e448c531e6db7727cfade325866caDan Stoza                    &Display::getColorModes, uint32_t*, int32_t*>);
223c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetDisplayAttribute:
224c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(
225c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    getDisplayAttributeHook);
226c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetDisplayConfigs:
227c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_DISPLAY_CONFIGS>(
228c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::getConfigs),
229c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::getConfigs, uint32_t*, hwc2_config_t*>);
230c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetDisplayName:
231c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_DISPLAY_NAME>(
232c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::getName),
233c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::getName, uint32_t*, char*>);
234c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetDisplayRequests:
235c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_DISPLAY_REQUESTS>(
236c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::getRequests),
237c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::getRequests, int32_t*, uint32_t*, hwc2_layer_t*,
238c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    int32_t*>);
239c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetDisplayType:
240c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_DISPLAY_TYPE>(
241c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::getType),
242c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::getType, int32_t*>);
243c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetDozeSupport:
244c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_DOZE_SUPPORT>(
245c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::getDozeSupport),
246c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::getDozeSupport, int32_t*>);
247ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza        case FunctionDescriptor::GetHdrCapabilities:
248ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza            return asFP<HWC2_PFN_GET_HDR_CAPABILITIES>(
249ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza                    displayHook<decltype(&Display::getHdrCapabilities),
250ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza                    &Display::getHdrCapabilities, uint32_t*, int32_t*, float*,
251ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza                    float*, float*>);
252c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetReleaseFences:
253c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_RELEASE_FENCES>(
254c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::getReleaseFences),
255c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::getReleaseFences, uint32_t*, hwc2_layer_t*,
256c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    int32_t*>);
257c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::PresentDisplay:
258c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_PRESENT_DISPLAY>(
259c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::present),
260c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::present, int32_t*>);
261c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetActiveConfig:
262c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_ACTIVE_CONFIG>(
263c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::setActiveConfig),
264c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::setActiveConfig, hwc2_config_t>);
265c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetClientTarget:
266c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_CLIENT_TARGET>(
267c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::setClientTarget),
268c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::setClientTarget, buffer_handle_t, int32_t,
2695cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza                    int32_t, hwc_region_t>);
270076ac670262e448c531e6db7727cfade325866caDan Stoza        case FunctionDescriptor::SetColorMode:
271076ac670262e448c531e6db7727cfade325866caDan Stoza            return asFP<HWC2_PFN_SET_COLOR_MODE>(
272076ac670262e448c531e6db7727cfade325866caDan Stoza                    displayHook<decltype(&Display::setColorMode),
273076ac670262e448c531e6db7727cfade325866caDan Stoza                    &Display::setColorMode, int32_t>);
2745df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza        case FunctionDescriptor::SetColorTransform:
2755df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza            return asFP<HWC2_PFN_SET_COLOR_TRANSFORM>(setColorTransformHook);
276c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetOutputBuffer:
277c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_OUTPUT_BUFFER>(
278c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::setOutputBuffer),
279c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::setOutputBuffer, buffer_handle_t, int32_t>);
280c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetPowerMode:
281c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_POWER_MODE>(setPowerModeHook);
282c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetVsyncEnabled:
283c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_VSYNC_ENABLED>(setVsyncEnabledHook);
284c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::ValidateDisplay:
285c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_VALIDATE_DISPLAY>(
286c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::validate),
287c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::validate, uint32_t*, uint32_t*>);
288c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
289c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Layer functions
290c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetCursorPosition:
291c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_CURSOR_POSITION>(
292c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setCursorPosition),
293c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Layer::setCursorPosition, int32_t, int32_t>);
294c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerBuffer:
295c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_BUFFER>(
296c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setBuffer), &Layer::setBuffer,
297c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    buffer_handle_t, int32_t>);
298c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerSurfaceDamage:
299c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(
300c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setSurfaceDamage),
301c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Layer::setSurfaceDamage, hwc_region_t>);
302c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
303c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Layer state functions
304c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerBlendMode:
305c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_BLEND_MODE>(
306c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    setLayerBlendModeHook);
307c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerColor:
308c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_COLOR>(
309c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setColor), &Layer::setColor,
310c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    hwc_color_t>);
311c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerCompositionType:
312c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(
313c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    setLayerCompositionTypeHook);
3145df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza        case FunctionDescriptor::SetLayerDataspace:
3155df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza            return asFP<HWC2_PFN_SET_LAYER_DATASPACE>(setLayerDataspaceHook);
316c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerDisplayFrame:
317c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(
318c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setDisplayFrame),
319c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Layer::setDisplayFrame, hwc_rect_t>);
320c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerPlaneAlpha:
321c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(
322c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setPlaneAlpha),
323c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Layer::setPlaneAlpha, float>);
324c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerSidebandStream:
325c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_SIDEBAND_STREAM>(
326c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setSidebandStream),
327c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Layer::setSidebandStream, const native_handle_t*>);
328c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerSourceCrop:
329c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>(
330c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setSourceCrop),
331c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Layer::setSourceCrop, hwc_frect_t>);
332c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerTransform:
333c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_TRANSFORM>(setLayerTransformHook);
334c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerVisibleRegion:
335c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(
336c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setVisibleRegion),
337c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Layer::setVisibleRegion, hwc_region_t>);
338c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerZOrder:
339c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_Z_ORDER>(setLayerZOrderHook);
340c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
341c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        default:
342c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGE("doGetFunction: Unknown function descriptor: %d (%s)",
343c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    static_cast<int32_t>(descriptor),
344c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    to_string(descriptor).c_str());
345c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return nullptr;
346c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
347c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
348c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
349c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza// Device functions
350c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
351c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::createVirtualDisplay(uint32_t width,
352c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        uint32_t height, hwc2_display_t* outDisplay)
353c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
354fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
355c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
356c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1VirtualDisplay) {
357c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // We have already allocated our only HWC1 virtual display
358c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("createVirtualDisplay: HWC1 virtual display already allocated");
359c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::NoResources;
360c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
361c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
362c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (MAX_VIRTUAL_DISPLAY_DIMENSION != 0 &&
363c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            (width > MAX_VIRTUAL_DISPLAY_DIMENSION ||
364c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            height > MAX_VIRTUAL_DISPLAY_DIMENSION)) {
365c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("createVirtualDisplay: Can't create a virtual display with"
366c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                " a dimension > %u (tried %u x %u)",
367c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                MAX_VIRTUAL_DISPLAY_DIMENSION, width, height);
368c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::NoResources;
369c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
370c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
371c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1VirtualDisplay = std::make_shared<HWC2On1Adapter::Display>(*this,
372c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            HWC2::DisplayType::Virtual);
373c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1VirtualDisplay->populateConfigs(width, height);
374c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto displayId = mHwc1VirtualDisplay->getId();
375c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1DisplayMap[HWC_DISPLAY_VIRTUAL] = displayId;
376c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1VirtualDisplay->setHwc1Id(HWC_DISPLAY_VIRTUAL);
377c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDisplays.emplace(displayId, mHwc1VirtualDisplay);
378c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outDisplay = displayId;
379c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
380c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
381c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
382c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
383c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::destroyVirtualDisplay(hwc2_display_t displayId)
384c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
385fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
386c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
387c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!mHwc1VirtualDisplay || (mHwc1VirtualDisplay->getId() != displayId)) {
388c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadDisplay;
389c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
390c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
391c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1VirtualDisplay.reset();
392c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1DisplayMap.erase(HWC_DISPLAY_VIRTUAL);
393c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDisplays.erase(displayId);
394c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
395c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
396c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
397c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
398c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::dump(uint32_t* outSize, char* outBuffer)
399c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
400c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (outBuffer != nullptr) {
401c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto copiedBytes = mDumpString.copy(outBuffer, *outSize);
402c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        *outSize = static_cast<uint32_t>(copiedBytes);
403c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
404c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
405c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
406c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::stringstream output;
407c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
408c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "-- HWC2On1Adapter --\n";
409c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
410c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "Adapting to a HWC 1." << static_cast<int>(mHwc1MinorVersion) <<
411c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            " device\n";
412c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
413c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Attempt to acquire the lock for 1 second, but proceed without the lock
414c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // after that, so we can still get some information if we're deadlocked
415fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex,
416fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza            std::defer_lock);
417c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    lock.try_lock_for(1s);
418c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
419c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mCapabilities.empty()) {
420c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "Capabilities: None\n";
421c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
422c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "Capabilities:\n";
423c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (auto capability : mCapabilities) {
424c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            output << "  " << to_string(capability) << '\n';
425c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
426c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
427c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
428c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "Displays:\n";
429c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (const auto& element : mDisplays) {
430c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        const auto& display = element.second;
431c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << display->dump();
432c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
433c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << '\n';
434c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
435fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    // Release the lock before calling into HWC1, and since we no longer require
436fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    // mutual exclusion to access mCapabilities or mDisplays
437fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    lock.unlock();
438fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza
439c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1Device->dump) {
440c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "HWC1 dump:\n";
441c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        std::vector<char> hwc1Dump(4096);
442c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Call with size - 1 to preserve a null character at the end
443c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHwc1Device->dump(mHwc1Device, hwc1Dump.data(),
444c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                static_cast<int>(hwc1Dump.size() - 1));
445c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << hwc1Dump.data();
446c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
447c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
448c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDumpString = output.str();
449c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outSize = static_cast<uint32_t>(mDumpString.size());
450c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
451c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
452c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozauint32_t HWC2On1Adapter::getMaxVirtualDisplayCount()
453c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
454c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return mHwc1SupportsVirtualDisplays ? 1 : 0;
455c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
456c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
457c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic bool isValid(Callback descriptor) {
458c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (descriptor) {
459c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case Callback::Hotplug: // Fall-through
460c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case Callback::Refresh: // Fall-through
461c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case Callback::Vsync: return true;
462c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        default: return false;
463c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
464c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
465c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
466c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::registerCallback(Callback descriptor,
467c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer)
468c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
469c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!isValid(descriptor)) {
470c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadParameter;
471c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
472c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
473c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("registerCallback(%s, %p, %p)", to_string(descriptor).c_str(),
474c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            callbackData, pointer);
475c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
476fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
477c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
478c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mCallbacks[descriptor] = {callbackData, pointer};
479c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
480c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    bool hasPendingInvalidate = false;
481c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::vector<hwc2_display_t> displayIds;
482c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::vector<std::pair<hwc2_display_t, int64_t>> pendingVsyncs;
483c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::vector<std::pair<hwc2_display_t, int>> pendingHotplugs;
484c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
485c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (descriptor == Callback::Refresh) {
486c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hasPendingInvalidate = mHasPendingInvalidate;
487c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (hasPendingInvalidate) {
488c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            for (auto& displayPair : mDisplays) {
489c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                displayIds.emplace_back(displayPair.first);
490c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
491c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
492c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHasPendingInvalidate = false;
493c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else if (descriptor == Callback::Vsync) {
494c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (auto pending : mPendingVsyncs) {
495c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto hwc1DisplayId = pending.first;
496c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
497c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                ALOGE("hwc1Vsync: Couldn't find display for HWC1 id %d",
498c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                        hwc1DisplayId);
499c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                continue;
500c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
501c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto displayId = mHwc1DisplayMap[hwc1DisplayId];
502c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto timestamp = pending.second;
503c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            pendingVsyncs.emplace_back(displayId, timestamp);
504c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
505c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mPendingVsyncs.clear();
506c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else if (descriptor == Callback::Hotplug) {
507c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Hotplug the primary display
508c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        pendingHotplugs.emplace_back(mHwc1DisplayMap[HWC_DISPLAY_PRIMARY],
509c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                static_cast<int32_t>(Connection::Connected));
510c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
511c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (auto pending : mPendingHotplugs) {
512c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto hwc1DisplayId = pending.first;
513c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
514c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                ALOGE("hwc1Hotplug: Couldn't find display for HWC1 id %d",
515c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                        hwc1DisplayId);
516c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                continue;
517c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
518c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto displayId = mHwc1DisplayMap[hwc1DisplayId];
519c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto connected = pending.second;
520c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            pendingHotplugs.emplace_back(displayId, connected);
521c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
522c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
523c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
524c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Call pending callbacks without the state lock held
525c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    lock.unlock();
526c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
527c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (hasPendingInvalidate) {
528c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto refresh = reinterpret_cast<HWC2_PFN_REFRESH>(pointer);
529c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (auto displayId : displayIds) {
530c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            refresh(callbackData, displayId);
531c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
532c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
533c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!pendingVsyncs.empty()) {
534c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto vsync = reinterpret_cast<HWC2_PFN_VSYNC>(pointer);
535c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (auto& pendingVsync : pendingVsyncs) {
536c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            vsync(callbackData, pendingVsync.first, pendingVsync.second);
537c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
538c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
539c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!pendingHotplugs.empty()) {
540c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(pointer);
541c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (auto& pendingHotplug : pendingHotplugs) {
542c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            hotplug(callbackData, pendingHotplug.first, pendingHotplug.second);
543c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
544c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
545c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
546c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
547c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
548c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza// Display functions
549c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
550c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastd::atomic<hwc2_display_t> HWC2On1Adapter::Display::sNextId(1);
551c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
552c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaHWC2On1Adapter::Display::Display(HWC2On1Adapter& device, HWC2::DisplayType type)
553c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza  : mId(sNextId++),
554c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDevice(device),
555c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDirtyCount(0),
556c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mStateMutex(),
557c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mZIsDirty(false),
558c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1RequestedContents(nullptr),
559c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1ReceivedContents(nullptr),
560c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mRetireFence(),
561c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mChanges(),
562c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1Id(-1),
563c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mConfigs(),
564c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mActiveConfig(nullptr),
565c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mName(),
566c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mType(type),
567c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mPowerMode(PowerMode::Off),
568c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mVsyncEnabled(Vsync::Invalid),
569c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mClientTarget(),
570c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mOutputBuffer(),
5715df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    mHasColorTransform(false),
572fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    mLayers(),
573fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    mHwc1LayerMap() {}
574c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
575c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::acceptChanges()
576c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
577c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
578c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
579c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!mChanges) {
580c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("[%" PRIu64 "] acceptChanges failed, not validated", mId);
581c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::NotValidated;
582c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
583c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
584c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] acceptChanges", mId);
585c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
586c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (auto& change : mChanges->getTypeChanges()) {
587c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto layerId = change.first;
588c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto type = change.second;
589c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto layer = mDevice.mLayers[layerId];
590c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        layer->setCompositionType(type);
591c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
592c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
593c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mChanges->clearTypeChanges();
594c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
595c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1RequestedContents = std::move(mHwc1ReceivedContents);
596c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
597c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
598c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
599c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
600c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::createLayer(hwc2_layer_t* outLayerId)
601c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
602c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
603c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
604c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto layer = *mLayers.emplace(std::make_shared<Layer>(*this));
605c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDevice.mLayers.emplace(std::make_pair(layer->getId(), layer));
606c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outLayerId = layer->getId();
607c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] created layer %" PRIu64, mId, *outLayerId);
608c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
609c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
610c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
611c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::destroyLayer(hwc2_layer_t layerId)
612c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
613c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
614c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
615c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto mapLayer = mDevice.mLayers.find(layerId);
616c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mapLayer == mDevice.mLayers.end()) {
617c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("[%" PRIu64 "] destroyLayer(%" PRIu64 ") failed: no such layer",
618c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mId, layerId);
619c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadLayer;
620c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
621c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto layer = mapLayer->second;
622c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDevice.mLayers.erase(mapLayer);
623c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto zRange = mLayers.equal_range(layer);
624c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (auto current = zRange.first; current != zRange.second; ++current) {
625c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (**current == *layer) {
626c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            current = mLayers.erase(current);
627c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
628c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
629c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
630c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] destroyed layer %" PRIu64, mId, layerId);
631c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
632c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
633c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
634c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::getActiveConfig(hwc2_config_t* outConfig)
635c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
636c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
637c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
638c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!mActiveConfig) {
639c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("[%" PRIu64 "] getActiveConfig --> %s", mId,
640c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                to_string(Error::BadConfig).c_str());
641c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadConfig;
642c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
643c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto configId = mActiveConfig->getId();
644c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] getActiveConfig --> %u", mId, configId);
645c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outConfig = configId;
646c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
647c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
648c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
649c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::getAttribute(hwc2_config_t configId,
650c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        Attribute attribute, int32_t* outValue)
651c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
652c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
653c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
654c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (configId > mConfigs.size() || !mConfigs[configId]->isOnDisplay(*this)) {
655c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("[%" PRIu64 "] getAttribute failed: bad config (%u)", mId,
656c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                configId);
657c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadConfig;
658c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
659c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outValue = mConfigs[configId]->getAttribute(attribute);
660c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] getAttribute(%u, %s) --> %d", mId, configId,
661c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            to_string(attribute).c_str(), *outValue);
662c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
663c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
664c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
665c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::getChangedCompositionTypes(
666c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        uint32_t* outNumElements, hwc2_layer_t* outLayers, int32_t* outTypes)
667c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
668c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
669c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
670c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!mChanges) {
671c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("[%" PRIu64 "] getChangedCompositionTypes failed: not validated",
672c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mId);
673c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::NotValidated;
674c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
675c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
676c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if ((outLayers == nullptr) || (outTypes == nullptr)) {
677c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        *outNumElements = mChanges->getTypeChanges().size();
678c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::None;
679c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
680c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
681c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    uint32_t numWritten = 0;
682c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (const auto& element : mChanges->getTypeChanges()) {
683c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (numWritten == *outNumElements) {
684c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
685c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
686c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto layerId = element.first;
687c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto intType = static_cast<int32_t>(element.second);
688c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("Adding %" PRIu64 " %s", layerId,
689c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                to_string(element.second).c_str());
690c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        outLayers[numWritten] = layerId;
691c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        outTypes[numWritten] = intType;
692c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ++numWritten;
693c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
694c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outNumElements = numWritten;
695c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
696c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
697c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
698c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
699076ac670262e448c531e6db7727cfade325866caDan StozaError HWC2On1Adapter::Display::getColorModes(uint32_t* outNumModes,
700076ac670262e448c531e6db7727cfade325866caDan Stoza        int32_t* outModes)
701076ac670262e448c531e6db7727cfade325866caDan Stoza{
702076ac670262e448c531e6db7727cfade325866caDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
703076ac670262e448c531e6db7727cfade325866caDan Stoza
704076ac670262e448c531e6db7727cfade325866caDan Stoza    if (!outModes) {
705076ac670262e448c531e6db7727cfade325866caDan Stoza        *outNumModes = mColorModes.size();
706076ac670262e448c531e6db7727cfade325866caDan Stoza        return Error::None;
707076ac670262e448c531e6db7727cfade325866caDan Stoza    }
708076ac670262e448c531e6db7727cfade325866caDan Stoza    uint32_t numModes = std::min(*outNumModes,
709076ac670262e448c531e6db7727cfade325866caDan Stoza            static_cast<uint32_t>(mColorModes.size()));
710076ac670262e448c531e6db7727cfade325866caDan Stoza    std::copy_n(mColorModes.cbegin(), numModes, outModes);
711076ac670262e448c531e6db7727cfade325866caDan Stoza    *outNumModes = numModes;
712076ac670262e448c531e6db7727cfade325866caDan Stoza    return Error::None;
713076ac670262e448c531e6db7727cfade325866caDan Stoza}
714076ac670262e448c531e6db7727cfade325866caDan Stoza
715c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::getConfigs(uint32_t* outNumConfigs,
716c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc2_config_t* outConfigs)
717c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
718c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
719c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
720c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!outConfigs) {
721c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        *outNumConfigs = mConfigs.size();
722c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::None;
723c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
724c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    uint32_t numWritten = 0;
725c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (const auto& config : mConfigs) {
726c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (numWritten == *outNumConfigs) {
727c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
728c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
729c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        outConfigs[numWritten] = config->getId();
730c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ++numWritten;
731c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
732c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outNumConfigs = numWritten;
733c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
734c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
735c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
736c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::getDozeSupport(int32_t* outSupport)
737c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
738c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
739c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
740c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mDevice.mHwc1MinorVersion < 4 || mHwc1Id != 0) {
741c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        *outSupport = 0;
742c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
743c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        *outSupport = 1;
744c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
745c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
746c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
747c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
748ed40eba4c1264806a1b795bf45b0dea366ee9975Dan StozaError HWC2On1Adapter::Display::getHdrCapabilities(uint32_t* outNumTypes,
749ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza        int32_t* /*outTypes*/, float* /*outMaxLuminance*/,
750ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza        float* /*outMaxAverageLuminance*/, float* /*outMinLuminance*/)
751ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza{
752ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza    // This isn't supported on HWC1, so per the HWC2 header, return numTypes = 0
753ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza    *outNumTypes = 0;
754ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza    return Error::None;
755ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza}
756ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza
757c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::getName(uint32_t* outSize, char* outName)
758c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
759c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
760c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
761c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!outName) {
762c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        *outSize = mName.size();
763c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::None;
764c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
765c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto numCopied = mName.copy(outName, *outSize);
766c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outSize = numCopied;
767c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
768c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
769c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
770c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::getReleaseFences(uint32_t* outNumElements,
771c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc2_layer_t* outLayers, int32_t* outFences)
772c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
773c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
774c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
775c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    uint32_t numWritten = 0;
776c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    bool outputsNonNull = (outLayers != nullptr) && (outFences != nullptr);
777c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (const auto& layer : mLayers) {
778c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (outputsNonNull && (numWritten == *outNumElements)) {
779c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
780c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
781c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
782c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto releaseFence = layer->getReleaseFence();
783c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (releaseFence != Fence::NO_FENCE) {
784c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            if (outputsNonNull) {
785c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                outLayers[numWritten] = layer->getId();
786c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                outFences[numWritten] = releaseFence->dup();
787c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
788c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ++numWritten;
789c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
790c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
791c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outNumElements = numWritten;
792c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
793c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
794c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
795c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
796c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::getRequests(int32_t* outDisplayRequests,
797c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        uint32_t* outNumElements, hwc2_layer_t* outLayers,
798c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        int32_t* outLayerRequests)
799c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
800c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
801c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
802c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!mChanges) {
803c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::NotValidated;
804c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
805c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
806c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (outLayers == nullptr || outLayerRequests == nullptr) {
807c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        *outNumElements = mChanges->getNumLayerRequests();
808c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::None;
809c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
810c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
811c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outDisplayRequests = mChanges->getDisplayRequests();
812c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    uint32_t numWritten = 0;
813c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (const auto& request : mChanges->getLayerRequests()) {
814