HWC2On1Adapter.cpp revision 5cf424bc129f01ee12c7a4fbea1664276d29f970
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()) {
814c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (numWritten == *outNumElements) {
815c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
816c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
817c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        outLayers[numWritten] = request.first;
818c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        outLayerRequests[numWritten] = static_cast<int32_t>(request.second);
819c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ++numWritten;
820c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
821c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
822c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
823c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
824c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
825c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::getType(int32_t* outType)
826c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
827c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
828c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
829c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outType = static_cast<int32_t>(mType);
830c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
831c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
832c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
833c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::present(int32_t* outRetireFence)
834c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
835c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
836c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
837c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mChanges) {
838c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        Error error = mDevice.setAllDisplays();
839c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (error != Error::None) {
840c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGE("[%" PRIu64 "] present: setAllDisplaysFailed (%s)", mId,
841c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    to_string(error).c_str());
842c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return error;
843c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
844c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
845c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
846c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outRetireFence = mRetireFence.get()->dup();
847c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] present returning retire fence %d", mId,
848c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            *outRetireFence);
849c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
850c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
851c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
852c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
853c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::setActiveConfig(hwc2_config_t configId)
854c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
855c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
856c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
857c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto config = getConfig(configId);
858c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!config) {
859c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadConfig;
860c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
861076ac670262e448c531e6db7727cfade325866caDan Stoza    if (config == mActiveConfig) {
862076ac670262e448c531e6db7727cfade325866caDan Stoza        return Error::None;
863076ac670262e448c531e6db7727cfade325866caDan Stoza    }
864076ac670262e448c531e6db7727cfade325866caDan Stoza
865c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mDevice.mHwc1MinorVersion >= 4) {
866076ac670262e448c531e6db7727cfade325866caDan Stoza        uint32_t hwc1Id = 0;
867076ac670262e448c531e6db7727cfade325866caDan Stoza        auto error = config->getHwc1IdForColorMode(mActiveColorMode, &hwc1Id);
868076ac670262e448c531e6db7727cfade325866caDan Stoza        if (error != Error::None) {
869076ac670262e448c531e6db7727cfade325866caDan Stoza            return error;
870076ac670262e448c531e6db7727cfade325866caDan Stoza        }
871076ac670262e448c531e6db7727cfade325866caDan Stoza
872076ac670262e448c531e6db7727cfade325866caDan Stoza        int intError = mDevice.mHwc1Device->setActiveConfig(mDevice.mHwc1Device,
873076ac670262e448c531e6db7727cfade325866caDan Stoza                mHwc1Id, static_cast<int>(hwc1Id));
874076ac670262e448c531e6db7727cfade325866caDan Stoza        if (intError != 0) {
875076ac670262e448c531e6db7727cfade325866caDan Stoza            ALOGE("setActiveConfig: Failed to set active config on HWC1 (%d)",
876076ac670262e448c531e6db7727cfade325866caDan Stoza                intError);
877076ac670262e448c531e6db7727cfade325866caDan Stoza            return Error::BadConfig;
878076ac670262e448c531e6db7727cfade325866caDan Stoza        }
879076ac670262e448c531e6db7727cfade325866caDan Stoza        mActiveConfig = config;
880c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
881076ac670262e448c531e6db7727cfade325866caDan Stoza
882c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
883c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
884c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
885c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::setClientTarget(buffer_handle_t target,
8865cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza        int32_t acquireFence, int32_t /*dataspace*/, hwc_region_t /*damage*/)
887c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
888c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
889c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
890c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] setClientTarget(%p, %d)", mId, target, acquireFence);
891c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mClientTarget.setBuffer(target);
892c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mClientTarget.setFence(acquireFence);
8935cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza    // dataspace and damage can't be used by HWC1, so ignore them
894c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
895c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
896c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
897076ac670262e448c531e6db7727cfade325866caDan StozaError HWC2On1Adapter::Display::setColorMode(int32_t mode)
898076ac670262e448c531e6db7727cfade325866caDan Stoza{
899076ac670262e448c531e6db7727cfade325866caDan Stoza    std::unique_lock<std::recursive_mutex> lock (mStateMutex);
900076ac670262e448c531e6db7727cfade325866caDan Stoza
901076ac670262e448c531e6db7727cfade325866caDan Stoza    ALOGV("[%" PRIu64 "] setColorMode(%d)", mId, mode);
902076ac670262e448c531e6db7727cfade325866caDan Stoza
903076ac670262e448c531e6db7727cfade325866caDan Stoza    if (mode == mActiveColorMode) {
904076ac670262e448c531e6db7727cfade325866caDan Stoza        return Error::None;
905076ac670262e448c531e6db7727cfade325866caDan Stoza    }
906076ac670262e448c531e6db7727cfade325866caDan Stoza    if (mColorModes.count(mode) == 0) {
907076ac670262e448c531e6db7727cfade325866caDan Stoza        ALOGE("[%" PRIu64 "] Mode %d not found in mColorModes", mId, mode);
908076ac670262e448c531e6db7727cfade325866caDan Stoza        return Error::Unsupported;
909076ac670262e448c531e6db7727cfade325866caDan Stoza    }
910076ac670262e448c531e6db7727cfade325866caDan Stoza
911076ac670262e448c531e6db7727cfade325866caDan Stoza    uint32_t hwc1Config = 0;
912076ac670262e448c531e6db7727cfade325866caDan Stoza    auto error = mActiveConfig->getHwc1IdForColorMode(mode, &hwc1Config);
913076ac670262e448c531e6db7727cfade325866caDan Stoza    if (error != Error::None) {
914076ac670262e448c531e6db7727cfade325866caDan Stoza        return error;
915076ac670262e448c531e6db7727cfade325866caDan Stoza    }
916076ac670262e448c531e6db7727cfade325866caDan Stoza
917076ac670262e448c531e6db7727cfade325866caDan Stoza    ALOGV("[%" PRIu64 "] Setting HWC1 config %u", mId, hwc1Config);
918076ac670262e448c531e6db7727cfade325866caDan Stoza    int intError = mDevice.mHwc1Device->setActiveConfig(mDevice.mHwc1Device,
919076ac670262e448c531e6db7727cfade325866caDan Stoza            mHwc1Id, hwc1Config);
920076ac670262e448c531e6db7727cfade325866caDan Stoza    if (intError != 0) {
921076ac670262e448c531e6db7727cfade325866caDan Stoza        ALOGE("[%" PRIu64 "] Failed to set HWC1 config (%d)", mId, intError);
922076ac670262e448c531e6db7727cfade325866caDan Stoza        return Error::Unsupported;
923076ac670262e448c531e6db7727cfade325866caDan Stoza    }
924076ac670262e448c531e6db7727cfade325866caDan Stoza
925076ac670262e448c531e6db7727cfade325866caDan Stoza    mActiveColorMode = mode;
926076ac670262e448c531e6db7727cfade325866caDan Stoza    return Error::None;
927076ac670262e448c531e6db7727cfade325866caDan Stoza}
928076ac670262e448c531e6db7727cfade325866caDan Stoza
9295df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan StozaError HWC2On1Adapter::Display::setColorTransform(android_color_transform_t hint)
9305df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza{
9315df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
9325df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza
9335df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    ALOGV("%" PRIu64 "] setColorTransform(%d)", mId,
9345df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza            static_cast<int32_t>(hint));
9355df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    mHasColorTransform = (hint != HAL_COLOR_TRANSFORM_IDENTITY);
9365df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    return Error::None;
9375df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza}
9385df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza
939c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::setOutputBuffer(buffer_handle_t buffer,
940c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        int32_t releaseFence)
941c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
942c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
943c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
944c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] setOutputBuffer(%p, %d)", mId, buffer, releaseFence);
945c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mOutputBuffer.setBuffer(buffer);
946c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mOutputBuffer.setFence(releaseFence);
947c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
948c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
949c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
950c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic bool isValid(PowerMode mode)
951c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
952c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (mode) {
953c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case PowerMode::Off: // Fall-through
954c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case PowerMode::DozeSuspend: // Fall-through
955c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case PowerMode::Doze: // Fall-through
956c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case PowerMode::On: return true;
957c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        default: return false;
958c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
959c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
960c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
961c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic int getHwc1PowerMode(PowerMode mode)
962c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
963c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (mode) {
964c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case PowerMode::Off: return HWC_POWER_MODE_OFF;
965c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case PowerMode::DozeSuspend: return HWC_POWER_MODE_DOZE_SUSPEND;
966c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case PowerMode::Doze: return HWC_POWER_MODE_DOZE;
967c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case PowerMode::On: return HWC_POWER_MODE_NORMAL;
968c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        default: return HWC_POWER_MODE_OFF;
969c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
970c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
971c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
972c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::setPowerMode(PowerMode mode)
973c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
974c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!isValid(mode)) {
975c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadParameter;
976c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
977c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mode == mPowerMode) {
978c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::None;
979c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
980c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
981c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
982c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
983c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    int error = 0;
984c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mDevice.mHwc1MinorVersion < 4) {
985c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        error = mDevice.mHwc1Device->blank(mDevice.mHwc1Device, mHwc1Id,
986c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mode == PowerMode::Off);
987c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
988c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        error = mDevice.mHwc1Device->setPowerMode(mDevice.mHwc1Device,
989c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mHwc1Id, getHwc1PowerMode(mode));
990c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
991c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGE_IF(error != 0, "setPowerMode: Failed to set power mode on HWC1 (%d)",
992c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            error);
993c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
994c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] setPowerMode(%s)", mId, to_string(mode).c_str());
995c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mPowerMode = mode;
996c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
997c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
998c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
999c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic bool isValid(Vsync enable) {
1000c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (enable) {
1001c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case Vsync::Enable: // Fall-through
1002c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case Vsync::Disable: return true;
1003c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        default: return false;
1004c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1005c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1006c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1007c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::setVsyncEnabled(Vsync enable)
1008c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1009c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!isValid(enable)) {
1010c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadParameter;
1011c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1012c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (enable == mVsyncEnabled) {
1013c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::None;
1014c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1015c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1016c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1017c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1018c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    int error = mDevice.mHwc1Device->eventControl(mDevice.mHwc1Device,
1019c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            mHwc1Id, HWC_EVENT_VSYNC, enable == Vsync::Enable);
1020c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGE_IF(error != 0, "setVsyncEnabled: Failed to set vsync on HWC1 (%d)",
1021c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            error);
1022c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1023c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mVsyncEnabled = enable;
1024c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1025c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1026c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1027c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::validate(uint32_t* outNumTypes,
1028c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        uint32_t* outNumRequests)
1029c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1030c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1031c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1032c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] Entering validate", mId);
1033c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1034c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!mChanges) {
1035c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (!mDevice.prepareAllDisplays()) {
1036c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return Error::BadDisplay;
1037c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1038c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1039c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1040c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outNumTypes = mChanges->getNumTypes();
1041c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outNumRequests = mChanges->getNumLayerRequests();
1042c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] validate --> %u types, %u requests", mId, *outNumTypes,
1043c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            *outNumRequests);
1044c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (auto request : mChanges->getTypeChanges()) {
1045c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("Layer %" PRIu64 " --> %s", request.first,
1046c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                to_string(request.second).c_str());
1047c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1048c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return *outNumTypes > 0 ? Error::HasChanges : Error::None;
1049c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1050c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1051c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza// Display helpers
1052c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1053c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::updateLayerZ(hwc2_layer_t layerId, uint32_t z)
1054c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1055c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1056c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1057c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto mapLayer = mDevice.mLayers.find(layerId);
1058c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mapLayer == mDevice.mLayers.end()) {
1059c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("[%" PRIu64 "] updateLayerZ failed to find layer", mId);
1060c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadLayer;
1061c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1062c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1063c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto layer = mapLayer->second;
1064c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto zRange = mLayers.equal_range(layer);
1065c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    bool layerOnDisplay = false;
1066c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (auto current = zRange.first; current != zRange.second; ++current) {
1067c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (**current == *layer) {
1068c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            if ((*current)->getZ() == z) {
1069c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                // Don't change anything if the Z hasn't changed
1070c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                return Error::None;
1071c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
1072c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            current = mLayers.erase(current);
1073c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            layerOnDisplay = true;
1074c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
1075c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1076c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1077c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1078c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!layerOnDisplay) {
1079c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("[%" PRIu64 "] updateLayerZ failed to find layer on display",
1080c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mId);
1081c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadLayer;
1082c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1083c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1084c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    layer->setZ(z);
1085c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mLayers.emplace(std::move(layer));
1086c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mZIsDirty = true;
1087c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1088c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1089c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1090c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1091076ac670262e448c531e6db7727cfade325866caDan Stozastatic constexpr uint32_t ATTRIBUTES_WITH_COLOR[] = {
1092c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    HWC_DISPLAY_VSYNC_PERIOD,
1093c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    HWC_DISPLAY_WIDTH,
1094c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    HWC_DISPLAY_HEIGHT,
1095c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    HWC_DISPLAY_DPI_X,
1096c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    HWC_DISPLAY_DPI_Y,
1097076ac670262e448c531e6db7727cfade325866caDan Stoza    HWC_DISPLAY_COLOR_TRANSFORM,
1098c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    HWC_DISPLAY_NO_ATTRIBUTE,
1099c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza};
1100c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1101076ac670262e448c531e6db7727cfade325866caDan Stozastatic constexpr uint32_t ATTRIBUTES_WITHOUT_COLOR[] = {
1102076ac670262e448c531e6db7727cfade325866caDan Stoza    HWC_DISPLAY_VSYNC_PERIOD,
1103076ac670262e448c531e6db7727cfade325866caDan Stoza    HWC_DISPLAY_WIDTH,
1104076ac670262e448c531e6db7727cfade325866caDan Stoza    HWC_DISPLAY_HEIGHT,
1105076ac670262e448c531e6db7727cfade325866caDan Stoza    HWC_DISPLAY_DPI_X,
1106076ac670262e448c531e6db7727cfade325866caDan Stoza    HWC_DISPLAY_DPI_Y,
1107076ac670262e448c531e6db7727cfade325866caDan Stoza    HWC_DISPLAY_NO_ATTRIBUTE,
1108076ac670262e448c531e6db7727cfade325866caDan Stoza};
1109076ac670262e448c531e6db7727cfade325866caDan Stoza
1110076ac670262e448c531e6db7727cfade325866caDan Stozastatic constexpr size_t NUM_ATTRIBUTES_WITH_COLOR =
1111076ac670262e448c531e6db7727cfade325866caDan Stoza        sizeof(ATTRIBUTES_WITH_COLOR) / sizeof(uint32_t);
1112076ac670262e448c531e6db7727cfade325866caDan Stozastatic_assert(sizeof(ATTRIBUTES_WITH_COLOR) > sizeof(ATTRIBUTES_WITHOUT_COLOR),
1113076ac670262e448c531e6db7727cfade325866caDan Stoza        "Attribute tables have unexpected sizes");
1114076ac670262e448c531e6db7727cfade325866caDan Stoza
1115076ac670262e448c531e6db7727cfade325866caDan Stozastatic constexpr uint32_t ATTRIBUTE_MAP_WITH_COLOR[] = {
1116076ac670262e448c531e6db7727cfade325866caDan Stoza    6, // HWC_DISPLAY_NO_ATTRIBUTE = 0
1117076ac670262e448c531e6db7727cfade325866caDan Stoza    0, // HWC_DISPLAY_VSYNC_PERIOD = 1,
1118076ac670262e448c531e6db7727cfade325866caDan Stoza    1, // HWC_DISPLAY_WIDTH = 2,
1119076ac670262e448c531e6db7727cfade325866caDan Stoza    2, // HWC_DISPLAY_HEIGHT = 3,
1120076ac670262e448c531e6db7727cfade325866caDan Stoza    3, // HWC_DISPLAY_DPI_X = 4,
1121076ac670262e448c531e6db7727cfade325866caDan Stoza    4, // HWC_DISPLAY_DPI_Y = 5,
1122076ac670262e448c531e6db7727cfade325866caDan Stoza    5, // HWC_DISPLAY_COLOR_TRANSFORM = 6,
1123076ac670262e448c531e6db7727cfade325866caDan Stoza};
1124076ac670262e448c531e6db7727cfade325866caDan Stoza
1125076ac670262e448c531e6db7727cfade325866caDan Stozastatic constexpr uint32_t ATTRIBUTE_MAP_WITHOUT_COLOR[] = {
1126c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    5, // HWC_DISPLAY_NO_ATTRIBUTE = 0
1127c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    0, // HWC_DISPLAY_VSYNC_PERIOD = 1,
1128c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    1, // HWC_DISPLAY_WIDTH = 2,
1129c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    2, // HWC_DISPLAY_HEIGHT = 3,
1130c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    3, // HWC_DISPLAY_DPI_X = 4,
1131c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    4, // HWC_DISPLAY_DPI_Y = 5,
1132c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza};
1133c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1134c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozatemplate <uint32_t attribute>
1135c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic constexpr bool attributesMatch()
1136c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1137076ac670262e448c531e6db7727cfade325866caDan Stoza    bool match = (attribute ==
1138076ac670262e448c531e6db7727cfade325866caDan Stoza            ATTRIBUTES_WITH_COLOR[ATTRIBUTE_MAP_WITH_COLOR[attribute]]);
1139076ac670262e448c531e6db7727cfade325866caDan Stoza    if (attribute == HWC_DISPLAY_COLOR_TRANSFORM) {
1140076ac670262e448c531e6db7727cfade325866caDan Stoza        return match;
1141076ac670262e448c531e6db7727cfade325866caDan Stoza    }
1142076ac670262e448c531e6db7727cfade325866caDan Stoza
1143076ac670262e448c531e6db7727cfade325866caDan Stoza    return match && (attribute ==
1144076ac670262e448c531e6db7727cfade325866caDan Stoza            ATTRIBUTES_WITHOUT_COLOR[ATTRIBUTE_MAP_WITHOUT_COLOR[attribute]]);
1145c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1146c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic_assert(attributesMatch<HWC_DISPLAY_VSYNC_PERIOD>(),
1147c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        "Tables out of sync");
1148c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic_assert(attributesMatch<HWC_DISPLAY_WIDTH>(), "Tables out of sync");
1149c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic_assert(attributesMatch<HWC_DISPLAY_HEIGHT>(), "Tables out of sync");
1150c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic_assert(attributesMatch<HWC_DISPLAY_DPI_X>(), "Tables out of sync");
1151c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic_assert(attributesMatch<HWC_DISPLAY_DPI_Y>(), "Tables out of sync");
1152076ac670262e448c531e6db7727cfade325866caDan Stozastatic_assert(attributesMatch<HWC_DISPLAY_COLOR_TRANSFORM>(),
1153076ac670262e448c531e6db7727cfade325866caDan Stoza        "Tables out of sync");
1154c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1155c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::populateConfigs()
1156c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1157c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1158c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1159c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] populateConfigs", mId);
1160c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1161c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1Id == -1) {
1162c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("populateConfigs: HWC1 ID not set");
1163c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
1164c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1165c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1166c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const size_t MAX_NUM_CONFIGS = 128;
1167c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    uint32_t configs[MAX_NUM_CONFIGS] = {};
1168c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    size_t numConfigs = MAX_NUM_CONFIGS;
1169c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDevice.mHwc1Device->getDisplayConfigs(mDevice.mHwc1Device, mHwc1Id,
1170c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            configs, &numConfigs);
1171c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1172c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t c = 0; c < numConfigs; ++c) {
1173c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        uint32_t hwc1ConfigId = configs[c];
1174076ac670262e448c531e6db7727cfade325866caDan Stoza        auto newConfig = std::make_shared<Config>(*this);
1175076ac670262e448c531e6db7727cfade325866caDan Stoza
1176076ac670262e448c531e6db7727cfade325866caDan Stoza        int32_t values[NUM_ATTRIBUTES_WITH_COLOR] = {};
1177076ac670262e448c531e6db7727cfade325866caDan Stoza        bool hasColor = true;
1178076ac670262e448c531e6db7727cfade325866caDan Stoza        auto result = mDevice.mHwc1Device->getDisplayAttributes(
1179076ac670262e448c531e6db7727cfade325866caDan Stoza                mDevice.mHwc1Device, mHwc1Id, hwc1ConfigId,
1180076ac670262e448c531e6db7727cfade325866caDan Stoza                ATTRIBUTES_WITH_COLOR, values);
1181076ac670262e448c531e6db7727cfade325866caDan Stoza        if (result != 0) {
1182076ac670262e448c531e6db7727cfade325866caDan Stoza            mDevice.mHwc1Device->getDisplayAttributes(mDevice.mHwc1Device,
1183076ac670262e448c531e6db7727cfade325866caDan Stoza                    mHwc1Id, hwc1ConfigId, ATTRIBUTES_WITHOUT_COLOR, values);
1184076ac670262e448c531e6db7727cfade325866caDan Stoza            hasColor = false;
1185076ac670262e448c531e6db7727cfade325866caDan Stoza        }
1186076ac670262e448c531e6db7727cfade325866caDan Stoza
1187076ac670262e448c531e6db7727cfade325866caDan Stoza        auto attributeMap = hasColor ?
1188076ac670262e448c531e6db7727cfade325866caDan Stoza                ATTRIBUTE_MAP_WITH_COLOR : ATTRIBUTE_MAP_WITHOUT_COLOR;
1189076ac670262e448c531e6db7727cfade325866caDan Stoza
1190076ac670262e448c531e6db7727cfade325866caDan Stoza        newConfig->setAttribute(Attribute::VsyncPeriod,
1191076ac670262e448c531e6db7727cfade325866caDan Stoza                values[attributeMap[HWC_DISPLAY_VSYNC_PERIOD]]);
1192076ac670262e448c531e6db7727cfade325866caDan Stoza        newConfig->setAttribute(Attribute::Width,
1193076ac670262e448c531e6db7727cfade325866caDan Stoza                values[attributeMap[HWC_DISPLAY_WIDTH]]);
1194076ac670262e448c531e6db7727cfade325866caDan Stoza        newConfig->setAttribute(Attribute::Height,
1195076ac670262e448c531e6db7727cfade325866caDan Stoza                values[attributeMap[HWC_DISPLAY_HEIGHT]]);
1196076ac670262e448c531e6db7727cfade325866caDan Stoza        newConfig->setAttribute(Attribute::DpiX,
1197076ac670262e448c531e6db7727cfade325866caDan Stoza                values[attributeMap[HWC_DISPLAY_DPI_X]]);
1198076ac670262e448c531e6db7727cfade325866caDan Stoza        newConfig->setAttribute(Attribute::DpiY,
1199076ac670262e448c531e6db7727cfade325866caDan Stoza                values[attributeMap[HWC_DISPLAY_DPI_Y]]);
1200076ac670262e448c531e6db7727cfade325866caDan Stoza        if (hasColor) {
1201076ac670262e448c531e6db7727cfade325866caDan Stoza            newConfig->setAttribute(ColorTransform,
1202076ac670262e448c531e6db7727cfade325866caDan Stoza                    values[attributeMap[HWC_DISPLAY_COLOR_TRANSFORM]]);
1203076ac670262e448c531e6db7727cfade325866caDan Stoza        }
1204076ac670262e448c531e6db7727cfade325866caDan Stoza
1205076ac670262e448c531e6db7727cfade325866caDan Stoza        // We can only do this after attempting to read the color transform
1206076ac670262e448c531e6db7727cfade325866caDan Stoza        newConfig->setHwc1Id(hwc1ConfigId);
1207076ac670262e448c531e6db7727cfade325866caDan Stoza
1208076ac670262e448c531e6db7727cfade325866caDan Stoza        for (auto& existingConfig : mConfigs) {
1209076ac670262e448c531e6db7727cfade325866caDan Stoza            if (existingConfig->merge(*newConfig)) {
1210076ac670262e448c531e6db7727cfade325866caDan Stoza                ALOGV("Merged config %d with existing config %u: %s",
1211076ac670262e448c531e6db7727cfade325866caDan Stoza                        hwc1ConfigId, existingConfig->getId(),
1212076ac670262e448c531e6db7727cfade325866caDan Stoza                        existingConfig->toString().c_str());
1213076ac670262e448c531e6db7727cfade325866caDan Stoza                newConfig.reset();
1214076ac670262e448c531e6db7727cfade325866caDan Stoza                break;
1215076ac670262e448c531e6db7727cfade325866caDan Stoza            }
1216076ac670262e448c531e6db7727cfade325866caDan Stoza        }
1217076ac670262e448c531e6db7727cfade325866caDan Stoza
1218076ac670262e448c531e6db7727cfade325866caDan Stoza        // If it wasn't merged with any existing config, add it to the end
1219076ac670262e448c531e6db7727cfade325866caDan Stoza        if (newConfig) {
1220076ac670262e448c531e6db7727cfade325866caDan Stoza            newConfig->setId(static_cast<hwc2_config_t>(mConfigs.size()));
1221076ac670262e448c531e6db7727cfade325866caDan Stoza            ALOGV("Found new config %u: %s", newConfig->getId(),
1222076ac670262e448c531e6db7727cfade325866caDan Stoza                    newConfig->toString().c_str());
1223076ac670262e448c531e6db7727cfade325866caDan Stoza            mConfigs.emplace_back(std::move(newConfig));
1224c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1225c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1226076ac670262e448c531e6db7727cfade325866caDan Stoza
1227076ac670262e448c531e6db7727cfade325866caDan Stoza    initializeActiveConfig();
1228076ac670262e448c531e6db7727cfade325866caDan Stoza    populateColorModes();
1229c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1230c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1231c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::populateConfigs(uint32_t width, uint32_t height)
1232c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1233c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1234c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1235076ac670262e448c531e6db7727cfade325866caDan Stoza    mConfigs.emplace_back(std::make_shared<Config>(*this));
1236c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto& config = mConfigs[0];
1237c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1238c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    config->setAttribute(Attribute::Width, static_cast<int32_t>(width));
1239c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    config->setAttribute(Attribute::Height, static_cast<int32_t>(height));
1240076ac670262e448c531e6db7727cfade325866caDan Stoza    config->setHwc1Id(0);
1241076ac670262e448c531e6db7727cfade325866caDan Stoza    config->setId(0);
1242c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mActiveConfig = config;
1243c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1244c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1245c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozabool HWC2On1Adapter::Display::prepare()
1246c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1247c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1248c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1249c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Only prepare display contents for displays HWC1 knows about
1250c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1Id == -1) {
1251c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return true;
1252c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1253c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1254c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // It doesn't make sense to prepare a display for which there is no active
1255c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // config, so return early
1256c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!mActiveConfig) {
1257c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("[%" PRIu64 "] Attempted to prepare, but no config active", mId);
1258c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return false;
1259c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1260c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1261c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] Entering prepare", mId);
1262c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1263c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto currentCount = mHwc1RequestedContents ?
1264c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            mHwc1RequestedContents->numHwLayers : 0;
1265c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto requiredCount = mLayers.size() + 1;
1266c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "]   Requires %zd layers, %zd allocated in %p", mId,
1267c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            requiredCount, currentCount, mHwc1RequestedContents.get());
1268c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1269c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    bool layerCountChanged = (currentCount != requiredCount);
1270c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (layerCountChanged) {
1271c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        reallocateHwc1Contents();
1272c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1273c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1274c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    bool applyAllState = false;
1275c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (layerCountChanged || mZIsDirty) {
1276c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        assignHwc1LayerIds();
1277c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mZIsDirty = false;
1278c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        applyAllState = true;
1279c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1280c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1281c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1RequestedContents->retireFenceFd = -1;
1282c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1RequestedContents->flags = 0;
1283c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (isDirty() || applyAllState) {
1284c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHwc1RequestedContents->flags |= HWC_GEOMETRY_CHANGED;
1285c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1286c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1287c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (auto& layer : mLayers) {
1288c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& hwc1Layer = mHwc1RequestedContents->hwLayers[layer->getHwc1Id()];
1289c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Layer.releaseFenceFd = -1;
1290c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        layer->applyState(hwc1Layer, applyAllState);
1291c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1292c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1293c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1RequestedContents->outbuf = mOutputBuffer.getBuffer();
1294c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1RequestedContents->outbufAcquireFenceFd = mOutputBuffer.getFence();
1295c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1296c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    prepareFramebufferTarget();
1297c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1298c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return true;
1299c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1300c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1301c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic void cloneHWCRegion(hwc_region_t& region)
1302c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1303c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto size = sizeof(hwc_rect_t) * region.numRects;
1304c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto newRects = static_cast<hwc_rect_t*>(std::malloc(size));
1305c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::copy_n(region.rects, region.numRects, newRects);
1306c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    region.rects = newRects;
1307c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1308c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1309c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaHWC2On1Adapter::Display::HWC1Contents
1310c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        HWC2On1Adapter::Display::cloneRequestedContents() const
1311c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1312c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1313c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1314c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    size_t size = sizeof(hwc_display_contents_1_t) +
1315c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            sizeof(hwc_layer_1_t) * (mHwc1RequestedContents->numHwLayers);
1316c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto contents = static_cast<hwc_display_contents_1_t*>(std::malloc(size));
1317c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::memcpy(contents, mHwc1RequestedContents.get(), size);
1318c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t layerId = 0; layerId < contents->numHwLayers; ++layerId) {
1319c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& layer = contents->hwLayers[layerId];
1320c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Deep copy the regions to avoid double-frees
1321c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        cloneHWCRegion(layer.visibleRegionScreen);
1322c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        cloneHWCRegion(layer.surfaceDamage);
1323c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1324c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return HWC1Contents(contents);
1325c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1326c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1327c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::setReceivedContents(HWC1Contents contents)
1328c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1329c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1330c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1331c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1ReceivedContents = std::move(contents);
1332c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1333c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mChanges.reset(new Changes);
1334c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1335c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    size_t numLayers = mHwc1ReceivedContents->numHwLayers;
1336c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t hwc1Id = 0; hwc1Id < numLayers; ++hwc1Id) {
1337c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        const auto& receivedLayer = mHwc1ReceivedContents->hwLayers[hwc1Id];
1338c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (mHwc1LayerMap.count(hwc1Id) == 0) {
1339c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGE_IF(receivedLayer.compositionType != HWC_FRAMEBUFFER_TARGET,
1340c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    "setReceivedContents: HWC1 layer %zd doesn't have a"
1341c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    " matching HWC2 layer, and isn't the framebuffer target",
1342c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    hwc1Id);
1343c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            continue;
1344c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1345c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1346c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        Layer& layer = *mHwc1LayerMap[hwc1Id];
1347c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        updateTypeChanges(receivedLayer, layer);
1348c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        updateLayerRequests(receivedLayer, layer);
1349c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1350c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1351c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1352c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozabool HWC2On1Adapter::Display::hasChanges() const
1353c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1354c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1355c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return mChanges != nullptr;
1356c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1357c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1358c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::set(hwc_display_contents_1& hwcContents)
1359c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1360c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1361c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1362c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!mChanges || (mChanges->getNumTypes() > 0)) {
1363c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("[%" PRIu64 "] set failed: not validated", mId);
1364c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::NotValidated;
1365c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1366c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1367c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Set up the client/framebuffer target
1368c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto numLayers = hwcContents.numHwLayers;
1369c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1370c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Close acquire fences on FRAMEBUFFER layers, since they will not be used
1371c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // by HWC
1372c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t l = 0; l < numLayers - 1; ++l) {
1373c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& layer = hwcContents.hwLayers[l];
1374c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (layer.compositionType == HWC_FRAMEBUFFER) {
1375c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGV("Closing fence %d for layer %zd", layer.acquireFenceFd, l);
1376c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            close(layer.acquireFenceFd);
1377c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            layer.acquireFenceFd = -1;
1378c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1379c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1380c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1381c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto& clientTargetLayer = hwcContents.hwLayers[numLayers - 1];
1382c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (clientTargetLayer.compositionType == HWC_FRAMEBUFFER_TARGET) {
1383c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        clientTargetLayer.handle = mClientTarget.getBuffer();
1384c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        clientTargetLayer.acquireFenceFd = mClientTarget.getFence();
1385c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
1386c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("[%" PRIu64 "] set: last HWC layer wasn't FRAMEBUFFER_TARGET",
1387c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mId);
1388c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1389c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1390c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mChanges.reset();
1391c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1392c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1393c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1394c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1395c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::addRetireFence(int fenceFd)
1396c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1397c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1398c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mRetireFence.add(fenceFd);
1399c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1400c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1401c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::addReleaseFences(
1402c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        const hwc_display_contents_1_t& hwcContents)
1403c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1404c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1405c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1406c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    size_t numLayers = hwcContents.numHwLayers;
1407c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t hwc1Id = 0; hwc1Id < numLayers; ++hwc1Id) {
1408c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        const auto& receivedLayer = hwcContents.hwLayers[hwc1Id];
1409c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (mHwc1LayerMap.count(hwc1Id) == 0) {
1410c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            if (receivedLayer.compositionType != HWC_FRAMEBUFFER_TARGET) {
1411c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                ALOGE("addReleaseFences: HWC1 layer %zd doesn't have a"
1412c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                        " matching HWC2 layer, and isn't the framebuffer"
1413c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                        " target", hwc1Id);
1414c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
1415c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            // Close the framebuffer target release fence since we will use the
1416c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            // display retire fence instead
1417c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            if (receivedLayer.releaseFenceFd != -1) {
1418c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                close(receivedLayer.releaseFenceFd);
1419c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
1420c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            continue;
1421c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1422c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1423c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        Layer& layer = *mHwc1LayerMap[hwc1Id];
1424c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("Adding release fence %d to layer %" PRIu64,
1425c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                receivedLayer.releaseFenceFd, layer.getId());
1426c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        layer.addReleaseFence(receivedLayer.releaseFenceFd);
1427c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1428c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1429c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
14305df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stozabool HWC2On1Adapter::Display::hasColorTransform() const
14315df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza{
14325df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
14335df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    return mHasColorTransform;
14345df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza}
14355df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza
1436c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string hwc1CompositionString(int32_t type)
1437c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1438c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (type) {
1439c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_FRAMEBUFFER: return "Framebuffer";
1440c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_OVERLAY: return "Overlay";
1441c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_BACKGROUND: return "Background";
1442c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_FRAMEBUFFER_TARGET: return "FramebufferTarget";
1443c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_SIDEBAND: return "Sideband";
1444c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_CURSOR_OVERLAY: return "CursorOverlay";
1445c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        default:
1446c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return std::string("Unknown (") + std::to_string(type) + ")";
1447c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1448c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1449c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1450c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string hwc1TransformString(int32_t transform)
1451c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1452c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (transform) {
1453c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case 0: return "None";
1454c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_TRANSFORM_FLIP_H: return "FlipH";
1455c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_TRANSFORM_FLIP_V: return "FlipV";
1456c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_TRANSFORM_ROT_90: return "Rotate90";
1457c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_TRANSFORM_ROT_180: return "Rotate180";
1458c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_TRANSFORM_ROT_270: return "Rotate270";
1459c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_TRANSFORM_FLIP_H_ROT_90: return "FlipHRotate90";
1460c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_TRANSFORM_FLIP_V_ROT_90: return "FlipVRotate90";
1461c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        default:
1462c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return std::string("Unknown (") + std::to_string(transform) + ")";
1463c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1464c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1465c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1466c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string hwc1BlendModeString(int32_t mode)
1467c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1468c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (mode) {
1469c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_BLENDING_NONE: return "None";
1470c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_BLENDING_PREMULT: return "Premultiplied";
1471c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_BLENDING_COVERAGE: return "Coverage";
1472c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        default:
1473c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return std::string("Unknown (") + std::to_string(mode) + ")";
1474c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1475c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1476c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1477c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string rectString(hwc_rect_t rect)
1478c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1479c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::stringstream output;
1480c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "[" << rect.left << ", " << rect.top << ", ";
1481c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << rect.right << ", " << rect.bottom << "]";
1482c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return output.str();
1483c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1484c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1485c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string approximateFloatString(float f)
1486c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1487c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (static_cast<int32_t>(f) == f) {
1488c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return std::to_string(static_cast<int32_t>(f));
1489c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1490c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    int32_t truncated = static_cast<int32_t>(f * 10);
1491c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    bool approximate = (static_cast<float>(truncated) != f * 10);
1492c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const size_t BUFFER_SIZE = 32;
1493c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    char buffer[BUFFER_SIZE] = {};
1494c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto bytesWritten = snprintf(buffer, BUFFER_SIZE,
1495c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            "%s%.1f", approximate ? "~" : "", f);
1496c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return std::string(buffer, bytesWritten);
1497c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1498c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1499c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string frectString(hwc_frect_t frect)
1500c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1501c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::stringstream output;
1502c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "[" << approximateFloatString(frect.left) << ", ";
1503c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << approximateFloatString(frect.top) << ", ";
1504c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << approximateFloatString(frect.right) << ", ";
1505c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << approximateFloatString(frect.bottom) << "]";
1506c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return output.str();
1507c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1508c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1509c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string colorString(hwc_color_t color)
1510c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1511c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::stringstream output;
1512c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "RGBA [";
1513c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << static_cast<int32_t>(color.r) << ", ";
1514c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << static_cast<int32_t>(color.g) << ", ";
1515c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << static_cast<int32_t>(color.b) << ", ";
1516c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << static_cast<int32_t>(color.a) << "]";
1517c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return output.str();
1518c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1519c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1520c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string alphaString(float f)
1521c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1522c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const size_t BUFFER_SIZE = 8;
1523c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    char buffer[BUFFER_SIZE] = {};
1524c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto bytesWritten = snprintf(buffer, BUFFER_SIZE, "%.3f", f);
1525c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return std::string(buffer, bytesWritten);
1526c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1527c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1528c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string to_string(const hwc_layer_1_t& hwcLayer,
1529c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        int32_t hwc1MinorVersion)
1530c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1531c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const char* fill = "          ";
1532c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1533c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::stringstream output;
1534c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1535c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "  Composition: " <<
1536c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            hwc1CompositionString(hwcLayer.compositionType);
1537c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1538c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (hwcLayer.compositionType == HWC_BACKGROUND) {
1539c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "  Color: " << colorString(hwcLayer.backgroundColor) << '\n';
1540c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else if (hwcLayer.compositionType == HWC_SIDEBAND) {
1541c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "  Stream: " << hwcLayer.sidebandStream << '\n';
1542c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
1543c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "  Buffer: " << hwcLayer.handle << "/" <<
1544c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwcLayer.acquireFenceFd << '\n';
1545c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1546c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1547c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << fill << "Display frame: " << rectString(hwcLayer.displayFrame) <<
1548c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            '\n';
1549c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1550c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << fill << "Source crop: ";
1551c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (hwc1MinorVersion >= 3) {
1552c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << frectString(hwcLayer.sourceCropf) << '\n';
1553c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
1554c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << rectString(hwcLayer.sourceCropi) << '\n';
1555c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1556c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1557c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << fill << "Transform: " << hwc1TransformString(hwcLayer.transform);
1558c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "  Blend mode: " << hwc1BlendModeString(hwcLayer.blending);
1559c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (hwcLayer.planeAlpha != 0xFF) {
1560c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "  Alpha: " << alphaString(hwcLayer.planeAlpha / 255.0f);
1561c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1562c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << '\n';
1563c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1564c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (hwcLayer.hints != 0) {
1565c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << fill << "Hints:";
1566c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if ((hwcLayer.hints & HWC_HINT_TRIPLE_BUFFER) != 0) {
1567c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            output << " TripleBuffer";
1568c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1569c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if ((hwcLayer.hints & HWC_HINT_CLEAR_FB) != 0) {
1570c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            output << " ClearFB";
1571c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1572c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << '\n';
1573c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1574c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1575c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (hwcLayer.flags != 0) {
1576c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << fill << "Flags:";
1577c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if ((hwcLayer.flags & HWC_SKIP_LAYER) != 0) {
1578c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            output << " SkipLayer";
1579c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1580c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if ((hwcLayer.flags & HWC_IS_CURSOR_LAYER) != 0) {
1581c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            output << " IsCursorLayer";
1582c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1583c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << '\n';
1584c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1585c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1586c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return output.str();
1587c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1588c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1589c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string to_string(const hwc_display_contents_1_t& hwcContents,
1590c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        int32_t hwc1MinorVersion)
1591c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1592c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const char* fill = "      ";
1593c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1594c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::stringstream output;
1595c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << fill << "Geometry changed: " <<
1596c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ((hwcContents.flags & HWC_GEOMETRY_CHANGED) != 0 ? "Y\n" : "N\n");
1597c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1598c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << fill << hwcContents.numHwLayers << " Layer" <<
1599c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ((hwcContents.numHwLayers == 1) ? "\n" : "s\n");
1600c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t layer = 0; layer < hwcContents.numHwLayers; ++layer) {
1601c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << fill << "  Layer " << layer;
1602c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << to_string(hwcContents.hwLayers[layer], hwc1MinorVersion);
1603c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1604c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1605c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (hwcContents.outbuf != nullptr) {
1606c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << fill << "Output buffer: " << hwcContents.outbuf << "/" <<
1607c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwcContents.outbufAcquireFenceFd << '\n';
1608c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1609c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1610c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return output.str();
1611c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1612c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1613c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastd::string HWC2On1Adapter::Display::dump() const
1614c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1615c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1616c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1617c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::stringstream output;
1618c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1619c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "  Display " << mId << ": ";
1620c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << to_string(mType) << "  ";
1621c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "HWC1 ID: " << mHwc1Id << "  ";
1622c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "Power mode: " << to_string(mPowerMode) << "  ";
1623c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "Vsync: " << to_string(mVsyncEnabled) << '\n';
1624c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1625076ac670262e448c531e6db7727cfade325866caDan Stoza    output << "    Color modes [active]:";
1626076ac670262e448c531e6db7727cfade325866caDan Stoza    for (const auto& mode : mColorModes) {
1627076ac670262e448c531e6db7727cfade325866caDan Stoza        if (mode == mActiveColorMode) {
1628076ac670262e448c531e6db7727cfade325866caDan Stoza            output << " [" << mode << ']';
1629c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        } else {
1630076ac670262e448c531e6db7727cfade325866caDan Stoza            output << " " << mode;
1631c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1632c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1633c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << '\n';
1634c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1635076ac670262e448c531e6db7727cfade325866caDan Stoza    output << "    " << mConfigs.size() << " Config" <<
1636076ac670262e448c531e6db7727cfade325866caDan Stoza            (mConfigs.size() == 1 ? "" : "s") << " (* active)\n";
1637076ac670262e448c531e6db7727cfade325866caDan Stoza    for (const auto& config : mConfigs) {
1638076ac670262e448c531e6db7727cfade325866caDan Stoza        output << (config == mActiveConfig ? "    * " : "      ");
1639076ac670262e448c531e6db7727cfade325866caDan Stoza        output << config->toString(true) << '\n';
1640076ac670262e448c531e6db7727cfade325866caDan Stoza    }
1641076ac670262e448c531e6db7727cfade325866caDan Stoza
1642c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "    " << mLayers.size() << " Layer" <<
1643c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            (mLayers.size() == 1 ? "" : "s") << '\n';
1644c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (const auto& layer : mLayers) {
1645c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << layer->dump();
1646c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1647c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1648c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "    Client target: " << mClientTarget.getBuffer() << '\n';
1649c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1650c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mOutputBuffer.getBuffer() != nullptr) {
1651c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "    Output buffer: " << mOutputBuffer.getBuffer() << '\n';
1652c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1653c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1654c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1ReceivedContents) {
1655c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "    Last received HWC1 state\n";
1656c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << to_string(*mHwc1ReceivedContents, mDevice.mHwc1MinorVersion);
1657c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else if (mHwc1RequestedContents) {
1658c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "    Last requested HWC1 state\n";
1659c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << to_string(*mHwc1RequestedContents, mDevice.mHwc1MinorVersion);
1660c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1661c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1662c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return output.str();
1663c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1664c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1665c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::Config::setAttribute(HWC2::Attribute attribute,
1666c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        int32_t value)
1667c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1668c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mAttributes[attribute] = value;
1669c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1670c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1671c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozaint32_t HWC2On1Adapter::Display::Config::getAttribute(Attribute attribute) const
1672c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1673c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mAttributes.count(attribute) == 0) {
1674c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return -1;
1675c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1676c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return mAttributes.at(attribute);
1677c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1678c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1679076ac670262e448c531e6db7727cfade325866caDan Stozavoid HWC2On1Adapter::Display::Config::setHwc1Id(uint32_t id)
1680076ac670262e448c531e6db7727cfade325866caDan Stoza{
1681076ac670262e448c531e6db7727cfade325866caDan Stoza    int32_t colorTransform = getAttribute(ColorTransform);
1682076ac670262e448c531e6db7727cfade325866caDan Stoza    mHwc1Ids.emplace(colorTransform, id);
1683076ac670262e448c531e6db7727cfade325866caDan Stoza}
1684076ac670262e448c531e6db7727cfade325866caDan Stoza
1685076ac670262e448c531e6db7727cfade325866caDan Stozabool HWC2On1Adapter::Display::Config::hasHwc1Id(uint32_t id) const
1686076ac670262e448c531e6db7727cfade325866caDan Stoza{
1687076ac670262e448c531e6db7727cfade325866caDan Stoza    for (const auto& idPair : mHwc1Ids) {
1688076ac670262e448c531e6db7727cfade325866caDan Stoza        if (id == idPair.second) {
1689076ac670262e448c531e6db7727cfade325866caDan Stoza            return true;
1690076ac670262e448c531e6db7727cfade325866caDan Stoza        }
1691076ac670262e448c531e6db7727cfade325866caDan Stoza    }
1692076ac670262e448c531e6db7727cfade325866caDan Stoza    return false;
1693076ac670262e448c531e6db7727cfade325866caDan Stoza}
1694076ac670262e448c531e6db7727cfade325866caDan Stoza
1695076ac670262e448c531e6db7727cfade325866caDan Stozaint32_t HWC2On1Adapter::Display::Config::getColorModeForHwc1Id(
1696076ac670262e448c531e6db7727cfade325866caDan Stoza        uint32_t id) const
1697076ac670262e448c531e6db7727cfade325866caDan Stoza{
1698076ac670262e448c531e6db7727cfade325866caDan Stoza    for (const auto& idPair : mHwc1Ids) {
1699076ac670262e448c531e6db7727cfade325866caDan Stoza        if (id == idPair.second) {
1700076ac670262e448c531e6db7727cfade325866caDan Stoza            return idPair.first;
1701076ac670262e448c531e6db7727cfade325866caDan Stoza        }
1702076ac670262e448c531e6db7727cfade325866caDan Stoza    }
1703076ac670262e448c531e6db7727cfade325866caDan Stoza    return -1;
1704076ac670262e448c531e6db7727cfade325866caDan Stoza}
1705076ac670262e448c531e6db7727cfade325866caDan Stoza
1706076ac670262e448c531e6db7727cfade325866caDan StozaError HWC2On1Adapter::Display::Config::getHwc1IdForColorMode(int32_t mode,
1707076ac670262e448c531e6db7727cfade325866caDan Stoza        uint32_t* outId) const
1708076ac670262e448c531e6db7727cfade325866caDan Stoza{
1709076ac670262e448c531e6db7727cfade325866caDan Stoza    for (const auto& idPair : mHwc1Ids) {
1710076ac670262e448c531e6db7727cfade325866caDan Stoza        if (mode == idPair.first) {
1711076ac670262e448c531e6db7727cfade325866caDan Stoza            *outId = idPair.second;
1712076ac670262e448c531e6db7727cfade325866caDan Stoza            return Error::None;
1713076ac670262e448c531e6db7727cfade325866caDan Stoza        }
1714076ac670262e448c531e6db7727cfade325866caDan Stoza    }
1715076ac670262e448c531e6db7727cfade325866caDan Stoza    ALOGE("Unable to find HWC1 ID for color mode %d on config %u", mode, mId);
1716076ac670262e448c531e6db7727cfade325866caDan Stoza    return Error::BadParameter;
1717076ac670262e448c531e6db7727cfade325866caDan Stoza}
1718076ac670262e448c531e6db7727cfade325866caDan Stoza
1719076ac670262e448c531e6db7727cfade325866caDan Stozabool HWC2On1Adapter::Display::Config::merge(const Config& other)
1720076ac670262e448c531e6db7727cfade325866caDan Stoza{
1721076ac670262e448c531e6db7727cfade325866caDan Stoza    auto attributes = {HWC2::Attribute::Width, HWC2::Attribute::Height,
1722076ac670262e448c531e6db7727cfade325866caDan Stoza            HWC2::Attribute::VsyncPeriod, HWC2::Attribute::DpiX,
1723076ac670262e448c531e6db7727cfade325866caDan Stoza            HWC2::Attribute::DpiY};
1724076ac670262e448c531e6db7727cfade325866caDan Stoza    for (auto attribute : attributes) {
1725076ac670262e448c531e6db7727cfade325866caDan Stoza        if (getAttribute(attribute) != other.getAttribute(attribute)) {
1726076ac670262e448c531e6db7727cfade325866caDan Stoza            return false;
1727076ac670262e448c531e6db7727cfade325866caDan Stoza        }
1728076ac670262e448c531e6db7727cfade325866caDan Stoza    }
1729076ac670262e448c531e6db7727cfade325866caDan Stoza    int32_t otherColorTransform = other.getAttribute(ColorTransform);
1730076ac670262e448c531e6db7727cfade325866caDan Stoza    if (mHwc1Ids.count(otherColorTransform) != 0) {
1731076ac670262e448c531e6db7727cfade325866caDan Stoza        ALOGE("Attempted to merge two configs (%u and %u) which appear to be "
1732076ac670262e448c531e6db7727cfade325866caDan Stoza                "identical", mHwc1Ids.at(otherColorTransform),
1733076ac670262e448c531e6db7727cfade325866caDan Stoza                other.mHwc1Ids.at(otherColorTransform));
1734076ac670262e448c531e6db7727cfade325866caDan Stoza        return false;
1735076ac670262e448c531e6db7727cfade325866caDan Stoza    }
1736076ac670262e448c531e6db7727cfade325866caDan Stoza    mHwc1Ids.emplace(otherColorTransform,
1737076ac670262e448c531e6db7727cfade325866caDan Stoza            other.mHwc1Ids.at(otherColorTransform));
1738076ac670262e448c531e6db7727cfade325866caDan Stoza    return true;
1739076ac670262e448c531e6db7727cfade325866caDan Stoza}
1740076ac670262e448c531e6db7727cfade325866caDan Stoza
1741076ac670262e448c531e6db7727cfade325866caDan Stozastd::set<int32_t> HWC2On1Adapter::Display::Config::getColorTransforms() const
1742076ac670262e448c531e6db7727cfade325866caDan Stoza{
1743076ac670262e448c531e6db7727cfade325866caDan Stoza    std::set<int32_t> colorTransforms;
1744076ac670262e448c531e6db7727cfade325866caDan Stoza    for (const auto& idPair : mHwc1Ids) {
1745076ac670262e448c531e6db7727cfade325866caDan Stoza        colorTransforms.emplace(idPair.first);
1746076ac670262e448c531e6db7727cfade325866caDan Stoza    }
1747076ac670262e448c531e6db7727cfade325866caDan Stoza    return colorTransforms;
1748076ac670262e448c531e6db7727cfade325866caDan Stoza}
1749076ac670262e448c531e6db7727cfade325866caDan Stoza
1750076ac670262e448c531e6db7727cfade325866caDan Stozastd::string HWC2On1Adapter::Display::Config::toString(bool splitLine) const
1751c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1752c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::string output;
1753c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1754c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const size_t BUFFER_SIZE = 100;
1755c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    char buffer[BUFFER_SIZE] = {};
1756c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto writtenBytes = snprintf(buffer, BUFFER_SIZE,
1757076ac670262e448c531e6db7727cfade325866caDan Stoza            "%u x %u", mAttributes.at(HWC2::Attribute::Width),
1758c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            mAttributes.at(HWC2::Attribute::Height));
1759c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output.append(buffer, writtenBytes);
1760c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1761c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mAttributes.count(HWC2::Attribute::VsyncPeriod) != 0) {
1762c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        std::memset(buffer, 0, BUFFER_SIZE);
1763c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        writtenBytes = snprintf(buffer, BUFFER_SIZE, " @ %.1f Hz",
1764c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                1e9 / mAttributes.at(HWC2::Attribute::VsyncPeriod));
1765c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output.append(buffer, writtenBytes);
1766c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1767c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1768c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mAttributes.count(HWC2::Attribute::DpiX) != 0 &&
1769c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            mAttributes.at(HWC2::Attribute::DpiX) != -1) {
1770c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        std::memset(buffer, 0, BUFFER_SIZE);
1771c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        writtenBytes = snprintf(buffer, BUFFER_SIZE,
1772c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                ", DPI: %.1f x %.1f",
1773c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mAttributes.at(HWC2::Attribute::DpiX) / 1000.0f,
1774c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mAttributes.at(HWC2::Attribute::DpiY) / 1000.0f);
1775c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output.append(buffer, writtenBytes);
1776c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1777c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1778076ac670262e448c531e6db7727cfade325866caDan Stoza    std::memset(buffer, 0, BUFFER_SIZE);
1779076ac670262e448c531e6db7727cfade325866caDan Stoza    if (splitLine) {
1780076ac670262e448c531e6db7727cfade325866caDan Stoza        writtenBytes = snprintf(buffer, BUFFER_SIZE,
1781076ac670262e448c531e6db7727cfade325866caDan Stoza                "\n        HWC1 ID/Color transform:");
1782076ac670262e448c531e6db7727cfade325866caDan Stoza    } else {
1783076ac670262e448c531e6db7727cfade325866caDan Stoza        writtenBytes = snprintf(buffer, BUFFER_SIZE,
1784076ac670262e448c531e6db7727cfade325866caDan Stoza                ", HWC1 ID/Color transform:");
1785076ac670262e448c531e6db7727cfade325866caDan Stoza    }
1786076ac670262e448c531e6db7727cfade325866caDan Stoza    output.append(buffer, writtenBytes);
1787076ac670262e448c531e6db7727cfade325866caDan Stoza
1788076ac670262e448c531e6db7727cfade325866caDan Stoza
1789076ac670262e448c531e6db7727cfade325866caDan Stoza    for (const auto& id : mHwc1Ids) {
1790076ac670262e448c531e6db7727cfade325866caDan Stoza        int32_t colorTransform = id.first;
1791076ac670262e448c531e6db7727cfade325866caDan Stoza        uint32_t hwc1Id = id.second;
1792076ac670262e448c531e6db7727cfade325866caDan Stoza        std::memset(buffer, 0, BUFFER_SIZE);
1793076ac670262e448c531e6db7727cfade325866caDan Stoza        if (colorTransform == mDisplay.mActiveColorMode) {
1794076ac670262e448c531e6db7727cfade325866caDan Stoza            writtenBytes = snprintf(buffer, BUFFER_SIZE, " [%u/%d]", hwc1Id,
1795076ac670262e448c531e6db7727cfade325866caDan Stoza                    colorTransform);
1796076ac670262e448c531e6db7727cfade325866caDan Stoza        } else {
1797076ac670262e448c531e6db7727cfade325866caDan Stoza            writtenBytes = snprintf(buffer, BUFFER_SIZE, " %u/%d", hwc1Id,
1798076ac670262e448c531e6db7727cfade325866caDan Stoza                    colorTransform);
1799076ac670262e448c531e6db7727cfade325866caDan Stoza        }
1800076ac670262e448c531e6db7727cfade325866caDan Stoza        output.append(buffer, writtenBytes);
1801076ac670262e448c531e6db7727cfade325866caDan Stoza    }
1802076ac670262e448c531e6db7727cfade325866caDan Stoza
1803c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return output;
1804c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1805c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1806c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastd::shared_ptr<const HWC2On1Adapter::Display::Config>
1807c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        HWC2On1Adapter::Display::getConfig(hwc2_config_t configId) const
1808c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1809c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (configId > mConfigs.size() || !mConfigs[configId]->isOnDisplay(*this)) {
1810c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return nullptr;
1811c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1812c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return mConfigs[configId];
1813c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1814c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1815076ac670262e448c531e6db7727cfade325866caDan Stozavoid HWC2On1Adapter::Display::populateColorModes()
1816076ac670262e448c531e6db7727cfade325866caDan Stoza{
1817076ac670262e448c531e6db7727cfade325866caDan Stoza    mColorModes = mConfigs[0]->getColorTransforms();
1818076ac670262e448c531e6db7727cfade325866caDan Stoza    for (const auto& config : mConfigs) {
1819076ac670262e448c531e6db7727cfade325866caDan Stoza        std::set<int32_t> intersection;
1820076ac670262e448c531e6db7727cfade325866caDan Stoza        auto configModes = config->getColorTransforms();
1821076ac670262e448c531e6db7727cfade325866caDan Stoza        std::set_intersection(mColorModes.cbegin(), mColorModes.cend(),
1822076ac670262e448c531e6db7727cfade325866caDan Stoza                configModes.cbegin(), configModes.cend(),
1823076ac670262e448c531e6db7727cfade325866caDan Stoza                std::inserter(intersection, intersection.begin()));
1824076ac670262e448c531e6db7727cfade325866caDan Stoza        std::swap(intersection, mColorModes);
1825076ac670262e448c531e6db7727cfade325866caDan Stoza    }
1826076ac670262e448c531e6db7727cfade325866caDan Stoza}
1827076ac670262e448c531e6db7727cfade325866caDan Stoza
1828076ac670262e448c531e6db7727cfade325866caDan Stozavoid HWC2On1Adapter::Display::initializeActiveConfig()
1829076ac670262e448c531e6db7727cfade325866caDan Stoza{
1830076ac670262e448c531e6db7727cfade325866caDan Stoza    if (mDevice.mHwc1Device->getActiveConfig == nullptr) {
1831076ac670262e448c531e6db7727cfade325866caDan Stoza        ALOGV("getActiveConfig is null, choosing config 0");
1832076ac670262e448c531e6db7727cfade325866caDan Stoza        mActiveConfig = mConfigs[0];
1833076ac670262e448c531e6db7727cfade325866caDan Stoza        mActiveColorMode = -1;
1834076ac670262e448c531e6db7727cfade325866caDan Stoza        return;
1835076ac670262e448c531e6db7727cfade325866caDan Stoza    }
1836076ac670262e448c531e6db7727cfade325866caDan Stoza
1837076ac670262e448c531e6db7727cfade325866caDan Stoza    auto activeConfig = mDevice.mHwc1Device->getActiveConfig(
1838076ac670262e448c531e6db7727cfade325866caDan Stoza            mDevice.mHwc1Device, mHwc1Id);
1839076ac670262e448c531e6db7727cfade325866caDan Stoza    if (activeConfig >= 0) {
1840076ac670262e448c531e6db7727cfade325866caDan Stoza        for (const auto& config : mConfigs) {
1841076ac670262e448c531e6db7727cfade325866caDan Stoza            if (config->hasHwc1Id(activeConfig)) {
1842076ac670262e448c531e6db7727cfade325866caDan Stoza                ALOGV("Setting active config to %d for HWC1 config %u",
1843076ac670262e448c531e6db7727cfade325866caDan Stoza                        config->getId(), activeConfig);
1844076ac670262e448c531e6db7727cfade325866caDan Stoza                mActiveConfig = config;
1845076ac670262e448c531e6db7727cfade325866caDan Stoza                mActiveColorMode = config->getColorModeForHwc1Id(activeConfig);
1846076ac670262e448c531e6db7727cfade325866caDan Stoza                break;
1847076ac670262e448c531e6db7727cfade325866caDan Stoza            }
1848076ac670262e448c531e6db7727cfade325866caDan Stoza        }
1849076ac670262e448c531e6db7727cfade325866caDan Stoza        if (!mActiveConfig) {
1850076ac670262e448c531e6db7727cfade325866caDan Stoza            ALOGV("Unable to find active HWC1 config %u, defaulting to "
1851076ac670262e448c531e6db7727cfade325866caDan Stoza                    "config 0", activeConfig);
1852076ac670262e448c531e6db7727cfade325866caDan Stoza            mActiveConfig = mConfigs[0];
1853076ac670262e448c531e6db7727cfade325866caDan Stoza            mActiveColorMode = -1;
1854076ac670262e448c531e6db7727cfade325866caDan Stoza        }
1855076ac670262e448c531e6db7727cfade325866caDan Stoza    }
1856076ac670262e448c531e6db7727cfade325866caDan Stoza}
1857076ac670262e448c531e6db7727cfade325866caDan Stoza
1858c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::reallocateHwc1Contents()
1859c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1860c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Allocate an additional layer for the framebuffer target
1861c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto numLayers = mLayers.size() + 1;
1862c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    size_t size = sizeof(hwc_display_contents_1_t) +
1863c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            sizeof(hwc_layer_1_t) * numLayers;
1864c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] reallocateHwc1Contents creating %zd layer%s", mId,
1865c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            numLayers, numLayers != 1 ? "s" : "");
1866c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto contents =
1867c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            static_cast<hwc_display_contents_1_t*>(std::calloc(size, 1));
1868c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    contents->numHwLayers = numLayers;
1869c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1RequestedContents.reset(contents);
1870c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1871c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1872c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::assignHwc1LayerIds()
1873c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1874c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1LayerMap.clear();
1875c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    size_t nextHwc1Id = 0;
1876c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (auto& layer : mLayers) {
1877c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHwc1LayerMap[nextHwc1Id] = layer;
1878c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        layer->setHwc1Id(nextHwc1Id++);
1879c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1880c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1881c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1882c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::updateTypeChanges(const hwc_layer_1_t& hwc1Layer,
1883c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        const Layer& layer)
1884c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1885c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto layerId = layer.getId();
1886c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (hwc1Layer.compositionType) {
1887c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_FRAMEBUFFER:
1888c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            if (layer.getCompositionType() != Composition::Client) {
1889c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mChanges->addTypeChange(layerId, Composition::Client);
1890c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
1891c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
1892c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_OVERLAY:
1893c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            if (layer.getCompositionType() != Composition::Device) {
1894c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mChanges->addTypeChange(layerId, Composition::Device);
1895c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
1896c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
1897c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_BACKGROUND:
1898c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGE_IF(layer.getCompositionType() != Composition::SolidColor,
1899c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    "updateTypeChanges: HWC1 requested BACKGROUND, but HWC2"
1900c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    " wasn't expecting SolidColor");
1901c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
1902c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_FRAMEBUFFER_TARGET:
1903c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            // Do nothing, since it shouldn't be modified by HWC1
1904c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
1905c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_SIDEBAND:
1906c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGE_IF(layer.getCompositionType() != Composition::Sideband,
1907c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    "updateTypeChanges: HWC1 requested SIDEBAND, but HWC2"
1908c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    " wasn't expecting Sideband");
1909c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
1910c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_CURSOR_OVERLAY:
1911c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGE_IF(layer.getCompositionType() != Composition::Cursor,
1912c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    "updateTypeChanges: HWC1 requested CURSOR_OVERLAY, but"
1913c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    " HWC2 wasn't expecting Cursor");
1914c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
1915c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1916c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1917c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1918c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::updateLayerRequests(
1919c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        const hwc_layer_1_t& hwc1Layer, const Layer& layer)
1920c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1921c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if ((hwc1Layer.hints & HWC_HINT_CLEAR_FB) != 0) {
1922c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mChanges->addLayerRequest(layer.getId(),
1923c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                LayerRequest::ClearClientTarget);
1924c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1925c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1926c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1927c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::prepareFramebufferTarget()
1928c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1929c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // We check that mActiveConfig is valid in Display::prepare
1930c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    int32_t width = mActiveConfig->getAttribute(Attribute::Width);
1931c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    int32_t height = mActiveConfig->getAttribute(Attribute::Height);
1932c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1933c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto& hwc1Target = mHwc1RequestedContents->hwLayers[mLayers.size()];
1934c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.compositionType = HWC_FRAMEBUFFER_TARGET;
1935c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.releaseFenceFd = -1;
1936c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.hints = 0;
1937c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.flags = 0;
1938c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.transform = 0;
1939c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.blending = HWC_BLENDING_PREMULT;
1940c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mDevice.getHwc1MinorVersion() < 3) {
1941c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Target.sourceCropi = {0, 0, width, height};
1942c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
1943c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Target.sourceCropf = {0.0f, 0.0f, static_cast<float>(width),
1944c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                static_cast<float>(height)};
1945c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1946c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.displayFrame = {0, 0, width, height};
1947c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.planeAlpha = 255;
1948c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.visibleRegionScreen.numRects = 1;
1949c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto rects = static_cast<hwc_rect_t*>(std::malloc(sizeof(hwc_rect_t)));
1950c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    rects[0].left = 0;
1951c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    rects[0].top = 0;
1952c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    rects[0].right = width;
1953c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    rects[0].bottom = height;
1954c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.visibleRegionScreen.rects = rects;
1955c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1956c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // We will set this to the correct value in set
1957c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.acquireFenceFd = -1;
1958c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1959c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1960c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza// Layer functions
1961c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1962c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastd::atomic<hwc2_layer_t> HWC2On1Adapter::Layer::sNextId(1);
1963c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1964c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaHWC2On1Adapter::Layer::Layer(Display& display)
1965c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza  : mId(sNextId++),
1966c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDisplay(display),
1967fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    mDirtyCount(0),
1968fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    mBuffer(),
1969fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    mSurfaceDamage(),
1970c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mBlendMode(*this, BlendMode::None),
1971c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mColor(*this, {0, 0, 0, 0}),
1972c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mCompositionType(*this, Composition::Invalid),
1973c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDisplayFrame(*this, {0, 0, -1, -1}),
1974c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mPlaneAlpha(*this, 0.0f),
1975c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mSidebandStream(*this, nullptr),
1976c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mSourceCrop(*this, {0.0f, 0.0f, -1.0f, -1.0f}),
1977c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mTransform(*this, Transform::None),
1978c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mVisibleRegion(*this, std::vector<hwc_rect_t>()),
1979c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mZ(0),
1980fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    mReleaseFence(),
1981c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1Id(0),
19825df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    mHasUnsupportedDataspace(false),
1983c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHasUnsupportedPlaneAlpha(false) {}
1984c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1985c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozabool HWC2On1Adapter::SortLayersByZ::operator()(
1986c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        const std::shared_ptr<Layer>& lhs, const std::shared_ptr<Layer>& rhs)
1987c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1988c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return lhs->getZ() < rhs->getZ();
1989c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1990c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1991c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setBuffer(buffer_handle_t buffer,
1992c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        int32_t acquireFence)
1993c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1994c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("Setting acquireFence to %d for layer %" PRIu64, acquireFence, mId);
1995c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mBuffer.setBuffer(buffer);
1996c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mBuffer.setFence(acquireFence);
1997c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1998c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1999c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2000c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setCursorPosition(int32_t x, int32_t y)
2001c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2002c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mCompositionType.getValue() != Composition::Cursor) {
2003c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadLayer;
2004c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2005c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2006c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mDisplay.hasChanges()) {
2007c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::NotValidated;
2008c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2009c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2010c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto displayId = mDisplay.getHwc1Id();
2011c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto hwc1Device = mDisplay.getDevice().getHwc1Device();
2012c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Device->setCursorPositionAsync(hwc1Device, displayId, x, y);
2013c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
2014c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2015c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2016c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setSurfaceDamage(hwc_region_t damage)
2017c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2018c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mSurfaceDamage.resize(damage.numRects);
2019c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::copy_n(damage.rects, damage.numRects, mSurfaceDamage.begin());
2020c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
2021c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2022c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2023c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza// Layer state functions
2024c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2025c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setBlendMode(BlendMode mode)
2026c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2027c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mBlendMode.setPending(mode);
2028c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
2029c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2030c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2031c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setColor(hwc_color_t color)
2032c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2033c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mColor.setPending(color);
2034c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
2035c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2036c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2037c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setCompositionType(Composition type)
2038c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2039c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mCompositionType.setPending(type);
2040c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
2041c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2042c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
20435df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan StozaError HWC2On1Adapter::Layer::setDataspace(android_dataspace_t dataspace)
20445df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza{
20455df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    mHasUnsupportedDataspace = (dataspace != HAL_DATASPACE_UNKNOWN);
20465df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    return Error::None;
20475df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza}
20485df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza
2049c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setDisplayFrame(hwc_rect_t frame)
2050c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2051c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDisplayFrame.setPending(frame);
2052c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
2053c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2054c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2055c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setPlaneAlpha(float alpha)
2056c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2057c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mPlaneAlpha.setPending(alpha);
2058c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
2059c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2060c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2061c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setSidebandStream(const native_handle_t* stream)
2062c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2063c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mSidebandStream.setPending(stream);
2064c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
2065c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2066c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2067c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setSourceCrop(hwc_frect_t crop)
2068c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2069c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mSourceCrop.setPending(crop);
2070c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
2071c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2072c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2073c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setTransform(Transform transform)
2074c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2075c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mTransform.setPending(transform);
2076c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
2077c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2078c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2079c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setVisibleRegion(hwc_region_t rawVisible)
2080c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2081c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::vector<hwc_rect_t> visible(rawVisible.rects,
2082c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            rawVisible.rects + rawVisible.numRects);
2083c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mVisibleRegion.setPending(std::move(visible));
2084c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
2085c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2086c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2087c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setZ(uint32_t z)
2088c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2089c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mZ = z;
2090c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
2091c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2092c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2093c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Layer::addReleaseFence(int fenceFd)
2094c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2095c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("addReleaseFence %d to layer %" PRIu64, fenceFd, mId);
2096c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mReleaseFence.add(fenceFd);
2097c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2098c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2099c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozaconst sp<Fence>& HWC2On1Adapter::Layer::getReleaseFence() const
2100c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2101c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return mReleaseFence.get();
2102c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2103c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2104c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Layer::applyState(hwc_layer_1_t& hwc1Layer,
2105c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        bool applyAllState)
2106c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2107c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    applyCommonState(hwc1Layer, applyAllState);
2108c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto compositionType = mCompositionType.getPendingValue();
2109c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (compositionType == Composition::SolidColor) {
2110c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        applySolidColorState(hwc1Layer, applyAllState);
2111c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else if (compositionType == Composition::Sideband) {
2112c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        applySidebandState(hwc1Layer, applyAllState);
2113c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
2114c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        applyBufferState(hwc1Layer);
2115c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2116c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    applyCompositionType(hwc1Layer, applyAllState);
2117c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2118c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2119c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza// Layer dump helpers
2120c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2121c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string regionStrings(const std::vector<hwc_rect_t>& visibleRegion,
2122c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        const std::vector<hwc_rect_t>& surfaceDamage)
2123c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2124c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::string regions;
2125c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    regions += "        Visible Region";
2126c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    regions.resize(40, ' ');
2127c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    regions += "Surface Damage\n";
2128c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2129c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    size_t numPrinted = 0;
2130c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    size_t maxSize = std::max(visibleRegion.size(), surfaceDamage.size());
2131c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    while (numPrinted < maxSize) {
2132c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        std::string line("        ");
2133c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (visibleRegion.empty() && numPrinted == 0) {
2134c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            line += "None";
2135c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        } else if (numPrinted < visibleRegion.size()) {
2136c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            line += rectString(visibleRegion[numPrinted]);
2137c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2138c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        line.resize(40, ' ');
2139c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (surfaceDamage.empty() && numPrinted == 0) {
2140c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            line += "None";
2141c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        } else if (numPrinted < surfaceDamage.size()) {
2142c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            line += rectString(surfaceDamage[numPrinted]);
2143c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2144c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        line += '\n';
2145c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        regions += line;
2146c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ++numPrinted;
2147c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2148c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return regions;
2149c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2150c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2151c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastd::string HWC2On1Adapter::Layer::dump() const
2152c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2153c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::stringstream output;
2154c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const char* fill = "      ";
2155c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2156c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << fill << to_string(mCompositionType.getPendingValue());
2157c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << " Layer  HWC2/1: " << mId << "/" << mHwc1Id << "  ";
2158c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "Z: " << mZ;
2159c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mCompositionType.getValue() == HWC2::Composition::SolidColor) {
2160c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "  " << colorString(mColor.getValue());
2161c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else if (mCompositionType.getValue() == HWC2::Composition::Sideband) {
2162c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "  Handle: " << mSidebandStream.getValue() << '\n';
2163c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
2164c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "  Buffer: " << mBuffer.getBuffer() << "/" <<
2165c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mBuffer.getFence() << '\n';
2166c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << fill << "  Display frame [LTRB]: " <<
2167c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                rectString(mDisplayFrame.getValue()) << '\n';
2168c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << fill << "  Source crop: " <<
2169c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                frectString(mSourceCrop.getValue()) << '\n';
2170c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << fill << "  Transform: " << to_string(mTransform.getValue());
2171c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "  Blend mode: " << to_string(mBlendMode.getValue());
2172c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (mPlaneAlpha.getValue() != 1.0f) {
2173c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            output << "  Alpha: " <<
2174c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                alphaString(mPlaneAlpha.getValue()) << '\n';
2175c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        } else {
2176c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            output << '\n';
2177c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2178c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << regionStrings(mVisibleRegion.getValue(), mSurfaceDamage);
2179c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2180c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return output.str();
2181c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2182c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2183c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic int getHwc1Blending(HWC2::BlendMode blendMode)
2184c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2185c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (blendMode) {
2186c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case BlendMode::Coverage: return HWC_BLENDING_COVERAGE;
2187c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case BlendMode::Premultiplied: return HWC_BLENDING_PREMULT;
2188c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        default: return HWC_BLENDING_NONE;
2189c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2190c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2191c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2192c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Layer::applyCommonState(hwc_layer_1_t& hwc1Layer,
2193c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        bool applyAllState)
2194c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2195c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto minorVersion = mDisplay.getDevice().getHwc1MinorVersion();
2196c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (applyAllState || mBlendMode.isDirty()) {
2197c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Layer.blending = getHwc1Blending(mBlendMode.getPendingValue());
2198c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mBlendMode.latch();
2199c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2200c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (applyAllState || mDisplayFrame.isDirty()) {
2201c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Layer.displayFrame = mDisplayFrame.getPendingValue();
2202c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mDisplayFrame.latch();
2203c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2204c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (applyAllState || mPlaneAlpha.isDirty()) {
2205c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto pendingAlpha = mPlaneAlpha.getPendingValue();
2206c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (minorVersion < 2) {
2207c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            mHasUnsupportedPlaneAlpha = pendingAlpha < 1.0f;
2208c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        } else {
2209c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            hwc1Layer.planeAlpha =
2210c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    static_cast<uint8_t>(255.0f * pendingAlpha + 0.5f);
2211c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2212c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mPlaneAlpha.latch();
2213c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2214c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (applyAllState || mSourceCrop.isDirty()) {
2215c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (minorVersion < 3) {
2216c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto pending = mSourceCrop.getPendingValue();
2217c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            hwc1Layer.sourceCropi.left =
2218c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    static_cast<int32_t>(std::ceil(pending.left));
2219c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            hwc1Layer.sourceCropi.top =
2220c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    static_cast<int32_t>(std::ceil(pending.top));
2221c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            hwc1Layer.sourceCropi.right =
2222c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    static_cast<int32_t>(std::floor(pending.right));
2223c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            hwc1Layer.sourceCropi.bottom =
2224c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    static_cast<int32_t>(std::floor(pending.bottom));
2225c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        } else {
2226c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            hwc1Layer.sourceCropf = mSourceCrop.getPendingValue();
2227c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2228c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mSourceCrop.latch();
2229c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2230c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (applyAllState || mTransform.isDirty()) {
2231c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Layer.transform =
2232c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                static_cast<uint32_t>(mTransform.getPendingValue());
2233c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mTransform.latch();
2234c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2235c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (applyAllState || mVisibleRegion.isDirty()) {
2236c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& hwc1VisibleRegion = hwc1Layer.visibleRegionScreen;
2237c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2238c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        std::free(const_cast<hwc_rect_t*>(hwc1VisibleRegion.rects));
2239c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2240c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto pending = mVisibleRegion.getPendingValue();
2241c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc_rect_t* newRects = static_cast<hwc_rect_t*>(
2242c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                std::malloc(sizeof(hwc_rect_t) * pending.size()));
2243c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        std::copy(pending.begin(), pending.end(), newRects);
2244c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1VisibleRegion.rects = const_cast<const hwc_rect_t*>(newRects);
2245c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1VisibleRegion.numRects = pending.size();
2246c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mVisibleRegion.latch();
2247c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2248c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2249c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2250c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Layer::applySolidColorState(hwc_layer_1_t& hwc1Layer,
2251c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        bool applyAllState)
2252c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2253c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (applyAllState || mColor.isDirty()) {
2254c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Layer.backgroundColor = mColor.getPendingValue();
2255c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mColor.latch();
2256c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2257c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2258c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2259c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Layer::applySidebandState(hwc_layer_1_t& hwc1Layer,
2260c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        bool applyAllState)
2261c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2262c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (applyAllState || mSidebandStream.isDirty()) {
2263c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Layer.sidebandStream = mSidebandStream.getPendingValue();
2264c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mSidebandStream.latch();
2265c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2266c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2267c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2268c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Layer::applyBufferState(hwc_layer_1_t& hwc1Layer)
2269c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2270c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Layer.handle = mBuffer.getBuffer();
2271c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Layer.acquireFenceFd = mBuffer.getFence();
2272c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2273c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2274c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Layer::applyCompositionType(hwc_layer_1_t& hwc1Layer,
2275c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        bool applyAllState)
2276c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
22775df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    // HWC1 never supports color transforms or dataspaces and only sometimes
22785df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    // supports plane alpha (depending on the version). These require us to drop
22795df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    // some or all layers to client composition.
22805df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    if (mHasUnsupportedDataspace || mHasUnsupportedPlaneAlpha ||
22815df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza            mDisplay.hasColorTransform()) {
2282c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2283c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Layer.flags = HWC_SKIP_LAYER;
2284c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
2285c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2286c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2287c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (applyAllState || mCompositionType.isDirty()) {
2288c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Layer.flags = 0;
2289c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        switch (mCompositionType.getPendingValue()) {
2290c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            case Composition::Client:
2291c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2292c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwc1Layer.flags |= HWC_SKIP_LAYER;
2293c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                break;
2294c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            case Composition::Device:
2295c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2296c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                break;
2297c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            case Composition::SolidColor:
2298c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwc1Layer.compositionType = HWC_BACKGROUND;
2299c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                break;
2300c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            case Composition::Cursor:
2301c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2302c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                if (mDisplay.getDevice().getHwc1MinorVersion() >= 4) {
2303c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    hwc1Layer.hints |= HWC_IS_CURSOR_LAYER;
2304c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                }
2305c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                break;
2306c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            case Composition::Sideband:
2307c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                if (mDisplay.getDevice().getHwc1MinorVersion() < 4) {
2308c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    hwc1Layer.compositionType = HWC_SIDEBAND;
2309c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                } else {
2310c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2311c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    hwc1Layer.flags |= HWC_SKIP_LAYER;
2312c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                }
2313c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                break;
2314c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            default:
2315c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2316c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwc1Layer.flags |= HWC_SKIP_LAYER;
2317c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                break;
2318c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2319c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("Layer %" PRIu64 " %s set to %d", mId,
2320c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                to_string(mCompositionType.getPendingValue()).c_str(),
2321c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwc1Layer.compositionType);
2322c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV_IF(hwc1Layer.flags & HWC_SKIP_LAYER, "    and skipping");
2323c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mCompositionType.latch();
2324c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2325c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2326c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2327c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza// Adapter helpers
2328c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2329c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::populateCapabilities()
2330c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2331c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("populateCapabilities");
2332c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1MinorVersion >= 3U) {
2333c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        int supportedTypes = 0;
2334c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto result = mHwc1Device->query(mHwc1Device,
2335c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                HWC_DISPLAY_TYPES_SUPPORTED, &supportedTypes);
2336c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if ((result == 0) && ((supportedTypes & HWC_DISPLAY_VIRTUAL) != 0)) {
2337c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGI("Found support for HWC virtual displays");
2338c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            mHwc1SupportsVirtualDisplays = true;
2339c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2340c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2341c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1MinorVersion >= 4U) {
2342c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mCapabilities.insert(Capability::SidebandStream);
2343c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2344c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2345c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2346c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaHWC2On1Adapter::Display* HWC2On1Adapter::getDisplay(hwc2_display_t id)
2347c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2348fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2349c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2350c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto display = mDisplays.find(id);
2351c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (display == mDisplays.end()) {
2352c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return nullptr;
2353c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2354c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2355c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return display->second.get();
2356c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2357c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2358c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastd::tuple<HWC2On1Adapter::Layer*, Error> HWC2On1Adapter::getLayer(
2359c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc2_display_t displayId, hwc2_layer_t layerId)
2360c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2361c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto display = getDisplay(displayId);
2362c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!display) {
2363c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadDisplay);
2364c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2365c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2366c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto layerEntry = mLayers.find(layerId);
2367c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (layerEntry == mLayers.end()) {
2368c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadLayer);
2369c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2370c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2371c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto layer = layerEntry->second;
2372c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (layer->getDisplay().getId() != displayId) {
2373c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadLayer);
2374c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2375c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return std::make_tuple(layer.get(), Error::None);
2376c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2377c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2378c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::populatePrimary()
2379c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2380c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("populatePrimary");
2381c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2382fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2383c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2384c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto display =
2385c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            std::make_shared<Display>(*this, HWC2::DisplayType::Physical);
2386c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1DisplayMap[HWC_DISPLAY_PRIMARY] = display->getId();
2387c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    display->setHwc1Id(HWC_DISPLAY_PRIMARY);
2388c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    display->populateConfigs();
2389c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDisplays.emplace(display->getId(), std::move(display));
2390c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2391c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2392c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozabool HWC2On1Adapter::prepareAllDisplays()
2393c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2394c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ATRACE_CALL();
2395c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2396fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2397c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2398c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (const auto& displayPair : mDisplays) {
2399c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& display = displayPair.second;
2400c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (!display->prepare()) {
2401c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return false;
2402c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2403c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2404c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2405c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1DisplayMap.count(0) == 0) {
2406c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("prepareAllDisplays: Unable to find primary HWC1 display");
2407c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return false;
2408c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2409c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2410c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Always push the primary display
2411c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::vector<HWC2On1Adapter::Display::HWC1Contents> requestedContents;
2412c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto primaryDisplayId = mHwc1DisplayMap[HWC_DISPLAY_PRIMARY];
2413c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto& primaryDisplay = mDisplays[primaryDisplayId];
2414c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto primaryDisplayContents = primaryDisplay->cloneRequestedContents();
2415c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    requestedContents.push_back(std::move(primaryDisplayContents));
2416c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2417c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Push the external display, if present
2418c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1DisplayMap.count(HWC_DISPLAY_EXTERNAL) != 0) {
2419c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto externalDisplayId = mHwc1DisplayMap[HWC_DISPLAY_EXTERNAL];
2420c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& externalDisplay = mDisplays[externalDisplayId];
2421c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto externalDisplayContents =
2422c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                externalDisplay->cloneRequestedContents();
2423c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        requestedContents.push_back(std::move(externalDisplayContents));
2424c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
2425c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Even if an external display isn't present, we still need to send
2426c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // at least two displays down to HWC1
2427c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        requestedContents.push_back(nullptr);
2428c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2429c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2430c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Push the hardware virtual display, if supported and present
2431c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1MinorVersion >= 3) {
2432c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (mHwc1DisplayMap.count(HWC_DISPLAY_VIRTUAL) != 0) {
2433c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto virtualDisplayId = mHwc1DisplayMap[HWC_DISPLAY_VIRTUAL];
2434c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto& virtualDisplay = mDisplays[virtualDisplayId];
2435c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto virtualDisplayContents =
2436c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    virtualDisplay->cloneRequestedContents();
2437c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            requestedContents.push_back(std::move(virtualDisplayContents));
2438c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        } else {
2439c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            requestedContents.push_back(nullptr);
2440c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2441c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2442c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2443c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1Contents.clear();
2444c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (auto& displayContents : requestedContents) {
2445c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHwc1Contents.push_back(displayContents.get());
2446c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (!displayContents) {
2447c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            continue;
2448c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2449c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2450c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("Display %zd layers:", mHwc1Contents.size() - 1);
2451c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (size_t l = 0; l < displayContents->numHwLayers; ++l) {
2452c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto& layer = displayContents->hwLayers[l];
2453c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGV("  %zd: %d", l, layer.compositionType);
2454c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2455c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2456c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2457c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("Calling HWC1 prepare");
2458c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    {
2459c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ATRACE_NAME("HWC1 prepare");
2460c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHwc1Device->prepare(mHwc1Device, mHwc1Contents.size(),
2461c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mHwc1Contents.data());
2462c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2463c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2464c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t c = 0; c < mHwc1Contents.size(); ++c) {
2465c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& contents = mHwc1Contents[c];
2466c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (!contents) {
2467c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            continue;
2468c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2469c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("Display %zd layers:", c);
2470c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (size_t l = 0; l < contents->numHwLayers; ++l) {
2471c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGV("  %zd: %d", l, contents->hwLayers[l].compositionType);
2472c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2473c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2474c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2475c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Return the received contents to their respective displays
2476c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t hwc1Id = 0; hwc1Id < mHwc1Contents.size(); ++hwc1Id) {
2477c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (mHwc1Contents[hwc1Id] == nullptr) {
2478c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            continue;
2479c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2480c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2481c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto displayId = mHwc1DisplayMap[hwc1Id];
2482c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& display = mDisplays[displayId];
2483c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        display->setReceivedContents(std::move(requestedContents[hwc1Id]));
2484c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2485c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2486c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return true;
2487c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2488c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2489c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::setAllDisplays()
2490c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2491c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ATRACE_CALL();
2492c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2493fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2494c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2495c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Make sure we're ready to validate
2496c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t hwc1Id = 0; hwc1Id < mHwc1Contents.size(); ++hwc1Id) {
2497c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (mHwc1Contents[hwc1Id] == nullptr) {
2498c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            continue;
2499c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2500c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2501c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto displayId = mHwc1DisplayMap[hwc1Id];
2502c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& display = mDisplays[displayId];
2503c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        Error error = display->set(*mHwc1Contents[hwc1Id]);
2504c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (error != Error::None) {
2505c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGE("setAllDisplays: Failed to set display %zd: %s", hwc1Id,
2506c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    to_string(error).c_str());
2507c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return error;
2508c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2509c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2510c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2511c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("Calling HWC1 set");
2512c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    {
2513c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ATRACE_NAME("HWC1 set");
2514c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHwc1Device->set(mHwc1Device, mHwc1Contents.size(),
2515c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mHwc1Contents.data());
2516c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2517c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2518c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Add retire and release fences
2519c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t hwc1Id = 0; hwc1Id < mHwc1Contents.size(); ++hwc1Id) {
2520c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (mHwc1Contents[hwc1Id] == nullptr) {
2521c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            continue;
2522c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2523c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2524c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto displayId = mHwc1DisplayMap[hwc1Id];
2525c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& display = mDisplays[displayId];
2526c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto retireFenceFd = mHwc1Contents[hwc1Id]->retireFenceFd;
2527c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("setAllDisplays: Adding retire fence %d to display %zd",
2528c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                retireFenceFd, hwc1Id);
2529c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        display->addRetireFence(mHwc1Contents[hwc1Id]->retireFenceFd);
2530c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        display->addReleaseFences(*mHwc1Contents[hwc1Id]);
2531c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2532c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2533c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
2534c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2535c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2536c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::hwc1Invalidate()
2537c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2538c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("Received hwc1Invalidate");
2539c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2540fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2541c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2542c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // If the HWC2-side callback hasn't been registered yet, buffer this until
2543c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // it is registered
2544c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mCallbacks.count(Callback::Refresh) == 0) {
2545c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHasPendingInvalidate = true;
2546c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
2547c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2548c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2549c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto& callbackInfo = mCallbacks[Callback::Refresh];
2550c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::vector<hwc2_display_t> displays;
2551c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (const auto& displayPair : mDisplays) {
2552c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        displays.emplace_back(displayPair.first);
2553c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2554c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2555c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Call back without the state lock held
2556c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    lock.unlock();
2557c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2558c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto refresh = reinterpret_cast<HWC2_PFN_REFRESH>(callbackInfo.pointer);
2559c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (auto display : displays) {
2560c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        refresh(callbackInfo.data, display);
2561c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2562c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2563c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2564c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::hwc1Vsync(int hwc1DisplayId, int64_t timestamp)
2565c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2566c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("Received hwc1Vsync(%d, %" PRId64 ")", hwc1DisplayId, timestamp);
2567c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2568fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2569c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2570c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // If the HWC2-side callback hasn't been registered yet, buffer this until
2571c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // it is registered
2572c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mCallbacks.count(Callback::Vsync) == 0) {
2573c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mPendingVsyncs.emplace_back(hwc1DisplayId, timestamp);
2574c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
2575c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2576c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2577c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
2578c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("hwc1Vsync: Couldn't find display for HWC1 id %d", hwc1DisplayId);
2579c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
2580c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2581c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2582c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto& callbackInfo = mCallbacks[Callback::Vsync];
2583c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto displayId = mHwc1DisplayMap[hwc1DisplayId];
2584c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2585c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Call back without the state lock held
2586c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    lock.unlock();
2587c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2588c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto vsync = reinterpret_cast<HWC2_PFN_VSYNC>(callbackInfo.pointer);
2589c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    vsync(callbackInfo.data, displayId, timestamp);
2590c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2591c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2592c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::hwc1Hotplug(int hwc1DisplayId, int connected)
2593c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2594c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("Received hwc1Hotplug(%d, %d)", hwc1DisplayId, connected);
2595c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2596c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (hwc1DisplayId != HWC_DISPLAY_EXTERNAL) {
2597c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("hwc1Hotplug: Received hotplug for non-external display");
2598c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
2599c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2600c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2601fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2602c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2603c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // If the HWC2-side callback hasn't been registered yet, buffer this until
2604c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // it is registered
2605c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mCallbacks.count(Callback::Hotplug) == 0) {
2606c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mPendingHotplugs.emplace_back(hwc1DisplayId, connected);
2607c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
2608c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2609c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2610c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc2_display_t displayId = UINT64_MAX;
2611c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
2612c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (connected == 0) {
2613c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGW("hwc1Hotplug: Received disconnect for unconnected display");
2614c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return;
2615c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2616c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2617c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Create a new display on connect
2618c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto display = std::make_shared<HWC2On1Adapter::Display>(*this,
2619c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                HWC2::DisplayType::Physical);
2620c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        display->setHwc1Id(HWC_DISPLAY_EXTERNAL);
2621c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        display->populateConfigs();
2622c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        displayId = display->getId();
2623c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHwc1DisplayMap[HWC_DISPLAY_EXTERNAL] = displayId;
2624c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mDisplays.emplace(displayId, std::move(display));
2625c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
2626c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (connected != 0) {
2627c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGW("hwc1Hotplug: Received connect for previously connected "
2628c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    "display");
2629c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return;
2630c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2631c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2632c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Disconnect an existing display
2633c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        displayId = mHwc1DisplayMap[hwc1DisplayId];
2634c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHwc1DisplayMap.erase(HWC_DISPLAY_EXTERNAL);
2635c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mDisplays.erase(displayId);
2636c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2637c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2638c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto& callbackInfo = mCallbacks[Callback::Hotplug];
2639c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2640c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Call back without the state lock held
2641c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    lock.unlock();
2642c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2643c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(callbackInfo.pointer);
2644c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto hwc2Connected = (connected == 0) ?
2645c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            HWC2::Connection::Disconnected : HWC2::Connection::Connected;
2646c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hotplug(callbackInfo.data, displayId, static_cast<int32_t>(hwc2Connected));
2647c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2648c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2649c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza} // namespace android
2650