HWC2On1Adapter.cpp revision 5df2a86063c6a83813fc1aa3d8938a82f7ff8f14
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
78c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozanamespace android {
79c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
80c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::DisplayContentsDeleter::operator()(
81c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc_display_contents_1_t* contents)
82c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
83c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (contents != nullptr) {
84c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (size_t l = 0; l < contents->numHwLayers; ++l) {
85c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto& layer = contents->hwLayers[l];
86c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            std::free(const_cast<hwc_rect_t*>(layer.visibleRegionScreen.rects));
87c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
88c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
89c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::free(contents);
90c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
91c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
92c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozaclass HWC2On1Adapter::Callbacks : public hwc_procs_t {
93c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    public:
94c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        Callbacks(HWC2On1Adapter& adapter) : mAdapter(adapter) {
95c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            invalidate = &invalidateHook;
96c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            vsync = &vsyncHook;
97c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            hotplug = &hotplugHook;
98c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
99c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
100c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        static void invalidateHook(const hwc_procs_t* procs) {
101c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto callbacks = static_cast<const Callbacks*>(procs);
102c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            callbacks->mAdapter.hwc1Invalidate();
103c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
104c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
105c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        static void vsyncHook(const hwc_procs_t* procs, int display,
106c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                int64_t timestamp) {
107c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto callbacks = static_cast<const Callbacks*>(procs);
108c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            callbacks->mAdapter.hwc1Vsync(display, timestamp);
109c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
110c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
111c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        static void hotplugHook(const hwc_procs_t* procs, int display,
112c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                int connected) {
113c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto callbacks = static_cast<const Callbacks*>(procs);
114c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            callbacks->mAdapter.hwc1Hotplug(display, connected);
115c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
116c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
117c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    private:
118c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        HWC2On1Adapter& mAdapter;
119c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza};
120c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
121c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic int closeHook(hw_device_t* /*device*/)
122c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
123c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Do nothing, since the real work is done in the class destructor, but we
124c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // need to provide a valid function pointer for hwc2_close to call
125c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return 0;
126c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
127c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
128c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaHWC2On1Adapter::HWC2On1Adapter(hwc_composer_device_1_t* hwc1Device)
129c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza  : mDumpString(),
130c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1Device(hwc1Device),
131c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1MinorVersion(getMinorVersion(hwc1Device)),
132c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1SupportsVirtualDisplays(false),
133c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1Callbacks(std::make_unique<Callbacks>(*this)),
134c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mCapabilities(),
135c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mLayers(),
136c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1VirtualDisplay(),
137c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mStateMutex(),
138c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mCallbacks(),
139c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHasPendingInvalidate(false),
140c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mPendingVsyncs(),
141c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mPendingHotplugs(),
142c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDisplays(),
143c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1DisplayMap()
144c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
145c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    common.close = closeHook;
146c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    getCapabilities = getCapabilitiesHook;
147c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    getFunction = getFunctionHook;
148c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    populateCapabilities();
149c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    populatePrimary();
150c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1Device->registerProcs(mHwc1Device,
151c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            static_cast<const hwc_procs_t*>(mHwc1Callbacks.get()));
152c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
153c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
154c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaHWC2On1Adapter::~HWC2On1Adapter() {
155c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc_close_1(mHwc1Device);
156c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
157c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
158c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::doGetCapabilities(uint32_t* outCount,
159c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        int32_t* outCapabilities)
160c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
161c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (outCapabilities == nullptr) {
162c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        *outCount = mCapabilities.size();
163c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
164c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
165c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
166c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto capabilityIter = mCapabilities.cbegin();
167c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t written = 0; written < *outCount; ++written) {
168c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (capabilityIter == mCapabilities.cend()) {
169c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return;
170c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
171c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        outCapabilities[written] = static_cast<int32_t>(*capabilityIter);
172c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ++capabilityIter;
173c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
174c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
175c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
176c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozahwc2_function_pointer_t HWC2On1Adapter::doGetFunction(
177c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        FunctionDescriptor descriptor)
178c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
179c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (descriptor) {
180c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Device functions
181c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::CreateVirtualDisplay:
182c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
183c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    createVirtualDisplayHook);
184c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::DestroyVirtualDisplay:
185c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
186c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    destroyVirtualDisplayHook);
187c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::Dump:
188c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_DUMP>(dumpHook);
189c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetMaxVirtualDisplayCount:
190c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
191c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    getMaxVirtualDisplayCountHook);
192c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::RegisterCallback:
193c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_REGISTER_CALLBACK>(registerCallbackHook);
194c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
195c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Display functions
196c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::AcceptDisplayChanges:
197c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(
198c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::acceptChanges),
199c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::acceptChanges>);
200c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::CreateLayer:
201c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_CREATE_LAYER>(
202c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::createLayer),
203c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::createLayer, hwc2_layer_t*>);
204c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::DestroyLayer:
205c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_DESTROY_LAYER>(
206c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::destroyLayer),
207c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::destroyLayer, hwc2_layer_t>);
208c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetActiveConfig:
209c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_ACTIVE_CONFIG>(
210c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::getActiveConfig),
211c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::getActiveConfig, hwc2_config_t*>);
212c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetChangedCompositionTypes:
213c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(
214c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::getChangedCompositionTypes),
215c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::getChangedCompositionTypes, uint32_t*,
216c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    hwc2_layer_t*, int32_t*>);
217c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetDisplayAttribute:
218c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(
219c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    getDisplayAttributeHook);
220c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetDisplayConfigs:
221c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_DISPLAY_CONFIGS>(
222c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::getConfigs),
223c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::getConfigs, uint32_t*, hwc2_config_t*>);
224c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetDisplayName:
225c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_DISPLAY_NAME>(
226c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::getName),
227c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::getName, uint32_t*, char*>);
228c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetDisplayRequests:
229c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_DISPLAY_REQUESTS>(
230c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::getRequests),
231c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::getRequests, int32_t*, uint32_t*, hwc2_layer_t*,
232c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    int32_t*>);
233c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetDisplayType:
234c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_DISPLAY_TYPE>(
235c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::getType),
236c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::getType, int32_t*>);
237c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetDozeSupport:
238c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_DOZE_SUPPORT>(
239c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::getDozeSupport),
240c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::getDozeSupport, int32_t*>);
241ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza        case FunctionDescriptor::GetHdrCapabilities:
242ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza            return asFP<HWC2_PFN_GET_HDR_CAPABILITIES>(
243ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza                    displayHook<decltype(&Display::getHdrCapabilities),
244ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza                    &Display::getHdrCapabilities, uint32_t*, int32_t*, float*,
245ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza                    float*, float*>);
246c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetReleaseFences:
247c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_RELEASE_FENCES>(
248c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::getReleaseFences),
249c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::getReleaseFences, uint32_t*, hwc2_layer_t*,
250c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    int32_t*>);
251c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::PresentDisplay:
252c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_PRESENT_DISPLAY>(
253c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::present),
254c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::present, int32_t*>);
255c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetActiveConfig:
256c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_ACTIVE_CONFIG>(
257c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::setActiveConfig),
258c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::setActiveConfig, hwc2_config_t>);
259c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetClientTarget:
260c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_CLIENT_TARGET>(
261c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::setClientTarget),
262c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::setClientTarget, buffer_handle_t, int32_t,
263c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    int32_t>);
2645df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza        case FunctionDescriptor::SetColorTransform:
2655df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza            return asFP<HWC2_PFN_SET_COLOR_TRANSFORM>(setColorTransformHook);
266c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetOutputBuffer:
267c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_OUTPUT_BUFFER>(
268c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::setOutputBuffer),
269c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::setOutputBuffer, buffer_handle_t, int32_t>);
270c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetPowerMode:
271c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_POWER_MODE>(setPowerModeHook);
272c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetVsyncEnabled:
273c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_VSYNC_ENABLED>(setVsyncEnabledHook);
274c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::ValidateDisplay:
275c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_VALIDATE_DISPLAY>(
276c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::validate),
277c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::validate, uint32_t*, uint32_t*>);
278c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
279c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Layer functions
280c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetCursorPosition:
281c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_CURSOR_POSITION>(
282c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setCursorPosition),
283c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Layer::setCursorPosition, int32_t, int32_t>);
284c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerBuffer:
285c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_BUFFER>(
286c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setBuffer), &Layer::setBuffer,
287c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    buffer_handle_t, int32_t>);
288c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerSurfaceDamage:
289c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(
290c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setSurfaceDamage),
291c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Layer::setSurfaceDamage, hwc_region_t>);
292c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
293c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Layer state functions
294c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerBlendMode:
295c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_BLEND_MODE>(
296c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    setLayerBlendModeHook);
297c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerColor:
298c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_COLOR>(
299c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setColor), &Layer::setColor,
300c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    hwc_color_t>);
301c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerCompositionType:
302c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(
303c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    setLayerCompositionTypeHook);
3045df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza        case FunctionDescriptor::SetLayerDataspace:
3055df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza            return asFP<HWC2_PFN_SET_LAYER_DATASPACE>(setLayerDataspaceHook);
306c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerDisplayFrame:
307c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(
308c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setDisplayFrame),
309c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Layer::setDisplayFrame, hwc_rect_t>);
310c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerPlaneAlpha:
311c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(
312c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setPlaneAlpha),
313c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Layer::setPlaneAlpha, float>);
314c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerSidebandStream:
315c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_SIDEBAND_STREAM>(
316c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setSidebandStream),
317c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Layer::setSidebandStream, const native_handle_t*>);
318c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerSourceCrop:
319c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>(
320c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setSourceCrop),
321c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Layer::setSourceCrop, hwc_frect_t>);
322c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerTransform:
323c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_TRANSFORM>(setLayerTransformHook);
324c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerVisibleRegion:
325c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(
326c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setVisibleRegion),
327c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Layer::setVisibleRegion, hwc_region_t>);
328c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerZOrder:
329c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_Z_ORDER>(setLayerZOrderHook);
330c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
331c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        default:
332c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGE("doGetFunction: Unknown function descriptor: %d (%s)",
333c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    static_cast<int32_t>(descriptor),
334c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    to_string(descriptor).c_str());
335c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return nullptr;
336c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
337c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
338c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
339c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza// Device functions
340c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
341c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::createVirtualDisplay(uint32_t width,
342c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        uint32_t height, hwc2_display_t* outDisplay)
343c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
344fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
345c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
346c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1VirtualDisplay) {
347c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // We have already allocated our only HWC1 virtual display
348c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("createVirtualDisplay: HWC1 virtual display already allocated");
349c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::NoResources;
350c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
351c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
352c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (MAX_VIRTUAL_DISPLAY_DIMENSION != 0 &&
353c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            (width > MAX_VIRTUAL_DISPLAY_DIMENSION ||
354c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            height > MAX_VIRTUAL_DISPLAY_DIMENSION)) {
355c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("createVirtualDisplay: Can't create a virtual display with"
356c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                " a dimension > %u (tried %u x %u)",
357c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                MAX_VIRTUAL_DISPLAY_DIMENSION, width, height);
358c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::NoResources;
359c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
360c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
361c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1VirtualDisplay = std::make_shared<HWC2On1Adapter::Display>(*this,
362c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            HWC2::DisplayType::Virtual);
363c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1VirtualDisplay->populateConfigs(width, height);
364c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto displayId = mHwc1VirtualDisplay->getId();
365c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1DisplayMap[HWC_DISPLAY_VIRTUAL] = displayId;
366c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1VirtualDisplay->setHwc1Id(HWC_DISPLAY_VIRTUAL);
367c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDisplays.emplace(displayId, mHwc1VirtualDisplay);
368c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outDisplay = displayId;
369c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
370c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
371c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
372c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
373c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::destroyVirtualDisplay(hwc2_display_t displayId)
374c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
375fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
376c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
377c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!mHwc1VirtualDisplay || (mHwc1VirtualDisplay->getId() != displayId)) {
378c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadDisplay;
379c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
380c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
381c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1VirtualDisplay.reset();
382c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1DisplayMap.erase(HWC_DISPLAY_VIRTUAL);
383c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDisplays.erase(displayId);
384c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
385c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
386c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
387c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
388c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::dump(uint32_t* outSize, char* outBuffer)
389c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
390c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (outBuffer != nullptr) {
391c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto copiedBytes = mDumpString.copy(outBuffer, *outSize);
392c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        *outSize = static_cast<uint32_t>(copiedBytes);
393c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
394c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
395c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
396c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::stringstream output;
397c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
398c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "-- HWC2On1Adapter --\n";
399c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
400c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "Adapting to a HWC 1." << static_cast<int>(mHwc1MinorVersion) <<
401c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            " device\n";
402c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
403c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Attempt to acquire the lock for 1 second, but proceed without the lock
404c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // after that, so we can still get some information if we're deadlocked
405fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex,
406fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza            std::defer_lock);
407c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    lock.try_lock_for(1s);
408c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
409c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mCapabilities.empty()) {
410c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "Capabilities: None\n";
411c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
412c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "Capabilities:\n";
413c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (auto capability : mCapabilities) {
414c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            output << "  " << to_string(capability) << '\n';
415c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
416c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
417c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
418c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "Displays:\n";
419c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (const auto& element : mDisplays) {
420c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        const auto& display = element.second;
421c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << display->dump();
422c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
423c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << '\n';
424c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
425fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    // Release the lock before calling into HWC1, and since we no longer require
426fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    // mutual exclusion to access mCapabilities or mDisplays
427fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    lock.unlock();
428fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza
429c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1Device->dump) {
430c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "HWC1 dump:\n";
431c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        std::vector<char> hwc1Dump(4096);
432c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Call with size - 1 to preserve a null character at the end
433c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHwc1Device->dump(mHwc1Device, hwc1Dump.data(),
434c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                static_cast<int>(hwc1Dump.size() - 1));
435c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << hwc1Dump.data();
436c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
437c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
438c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDumpString = output.str();
439c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outSize = static_cast<uint32_t>(mDumpString.size());
440c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
441c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
442c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozauint32_t HWC2On1Adapter::getMaxVirtualDisplayCount()
443c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
444c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return mHwc1SupportsVirtualDisplays ? 1 : 0;
445c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
446c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
447c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic bool isValid(Callback descriptor) {
448c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (descriptor) {
449c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case Callback::Hotplug: // Fall-through
450c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case Callback::Refresh: // Fall-through
451c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case Callback::Vsync: return true;
452c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        default: return false;
453c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
454c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
455c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
456c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::registerCallback(Callback descriptor,
457c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer)
458c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
459c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!isValid(descriptor)) {
460c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadParameter;
461c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
462c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
463c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("registerCallback(%s, %p, %p)", to_string(descriptor).c_str(),
464c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            callbackData, pointer);
465c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
466fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
467c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
468c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mCallbacks[descriptor] = {callbackData, pointer};
469c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
470c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    bool hasPendingInvalidate = false;
471c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::vector<hwc2_display_t> displayIds;
472c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::vector<std::pair<hwc2_display_t, int64_t>> pendingVsyncs;
473c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::vector<std::pair<hwc2_display_t, int>> pendingHotplugs;
474c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
475c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (descriptor == Callback::Refresh) {
476c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hasPendingInvalidate = mHasPendingInvalidate;
477c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (hasPendingInvalidate) {
478c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            for (auto& displayPair : mDisplays) {
479c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                displayIds.emplace_back(displayPair.first);
480c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
481c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
482c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHasPendingInvalidate = false;
483c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else if (descriptor == Callback::Vsync) {
484c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (auto pending : mPendingVsyncs) {
485c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto hwc1DisplayId = pending.first;
486c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
487c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                ALOGE("hwc1Vsync: Couldn't find display for HWC1 id %d",
488c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                        hwc1DisplayId);
489c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                continue;
490c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
491c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto displayId = mHwc1DisplayMap[hwc1DisplayId];
492c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto timestamp = pending.second;
493c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            pendingVsyncs.emplace_back(displayId, timestamp);
494c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
495c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mPendingVsyncs.clear();
496c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else if (descriptor == Callback::Hotplug) {
497c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Hotplug the primary display
498c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        pendingHotplugs.emplace_back(mHwc1DisplayMap[HWC_DISPLAY_PRIMARY],
499c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                static_cast<int32_t>(Connection::Connected));
500c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
501c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (auto pending : mPendingHotplugs) {
502c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto hwc1DisplayId = pending.first;
503c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
504c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                ALOGE("hwc1Hotplug: Couldn't find display for HWC1 id %d",
505c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                        hwc1DisplayId);
506c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                continue;
507c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
508c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto displayId = mHwc1DisplayMap[hwc1DisplayId];
509c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto connected = pending.second;
510c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            pendingHotplugs.emplace_back(displayId, connected);
511c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
512c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
513c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
514c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Call pending callbacks without the state lock held
515c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    lock.unlock();
516c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
517c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (hasPendingInvalidate) {
518c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto refresh = reinterpret_cast<HWC2_PFN_REFRESH>(pointer);
519c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (auto displayId : displayIds) {
520c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            refresh(callbackData, displayId);
521c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
522c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
523c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!pendingVsyncs.empty()) {
524c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto vsync = reinterpret_cast<HWC2_PFN_VSYNC>(pointer);
525c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (auto& pendingVsync : pendingVsyncs) {
526c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            vsync(callbackData, pendingVsync.first, pendingVsync.second);
527c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
528c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
529c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!pendingHotplugs.empty()) {
530c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(pointer);
531c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (auto& pendingHotplug : pendingHotplugs) {
532c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            hotplug(callbackData, pendingHotplug.first, pendingHotplug.second);
533c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
534c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
535c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
536c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
537c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
538c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza// Display functions
539c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
540c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastd::atomic<hwc2_display_t> HWC2On1Adapter::Display::sNextId(1);
541c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
542c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaHWC2On1Adapter::Display::Display(HWC2On1Adapter& device, HWC2::DisplayType type)
543c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza  : mId(sNextId++),
544c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDevice(device),
545c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDirtyCount(0),
546c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mStateMutex(),
547c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mZIsDirty(false),
548c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1RequestedContents(nullptr),
549c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1ReceivedContents(nullptr),
550c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mRetireFence(),
551c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mChanges(),
552c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1Id(-1),
553c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mConfigs(),
554c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mActiveConfig(nullptr),
555c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mName(),
556c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mType(type),
557c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mPowerMode(PowerMode::Off),
558c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mVsyncEnabled(Vsync::Invalid),
559c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mClientTarget(),
560c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mOutputBuffer(),
5615df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    mHasColorTransform(false),
562fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    mLayers(),
563fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    mHwc1LayerMap() {}
564c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
565c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::acceptChanges()
566c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
567c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
568c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
569c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!mChanges) {
570c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("[%" PRIu64 "] acceptChanges failed, not validated", mId);
571c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::NotValidated;
572c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
573c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
574c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] acceptChanges", mId);
575c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
576c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (auto& change : mChanges->getTypeChanges()) {
577c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto layerId = change.first;
578c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto type = change.second;
579c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto layer = mDevice.mLayers[layerId];
580c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        layer->setCompositionType(type);
581c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
582c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
583c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mChanges->clearTypeChanges();
584c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
585c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1RequestedContents = std::move(mHwc1ReceivedContents);
586c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
587c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
588c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
589c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
590c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::createLayer(hwc2_layer_t* outLayerId)
591c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
592c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
593c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
594c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto layer = *mLayers.emplace(std::make_shared<Layer>(*this));
595c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDevice.mLayers.emplace(std::make_pair(layer->getId(), layer));
596c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outLayerId = layer->getId();
597c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] created layer %" PRIu64, mId, *outLayerId);
598c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
599c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
600c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
601c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::destroyLayer(hwc2_layer_t layerId)
602c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
603c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
604c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
605c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto mapLayer = mDevice.mLayers.find(layerId);
606c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mapLayer == mDevice.mLayers.end()) {
607c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("[%" PRIu64 "] destroyLayer(%" PRIu64 ") failed: no such layer",
608c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mId, layerId);
609c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadLayer;
610c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
611c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto layer = mapLayer->second;
612c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDevice.mLayers.erase(mapLayer);
613c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto zRange = mLayers.equal_range(layer);
614c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (auto current = zRange.first; current != zRange.second; ++current) {
615c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (**current == *layer) {
616c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            current = mLayers.erase(current);
617c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
618c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
619c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
620c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] destroyed layer %" PRIu64, mId, layerId);
621c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
622c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
623c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
624c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::getActiveConfig(hwc2_config_t* outConfig)
625c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
626c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
627c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
628c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!mActiveConfig) {
629c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("[%" PRIu64 "] getActiveConfig --> %s", mId,
630c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                to_string(Error::BadConfig).c_str());
631c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadConfig;
632c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
633c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto configId = mActiveConfig->getId();
634c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] getActiveConfig --> %u", mId, configId);
635c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outConfig = configId;
636c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
637c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
638c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
639c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::getAttribute(hwc2_config_t configId,
640c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        Attribute attribute, int32_t* outValue)
641c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
642c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
643c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
644c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (configId > mConfigs.size() || !mConfigs[configId]->isOnDisplay(*this)) {
645c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("[%" PRIu64 "] getAttribute failed: bad config (%u)", mId,
646c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                configId);
647c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadConfig;
648c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
649c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outValue = mConfigs[configId]->getAttribute(attribute);
650c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] getAttribute(%u, %s) --> %d", mId, configId,
651c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            to_string(attribute).c_str(), *outValue);
652c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
653c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
654c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
655c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::getChangedCompositionTypes(
656c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        uint32_t* outNumElements, hwc2_layer_t* outLayers, int32_t* outTypes)
657c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
658c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
659c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
660c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!mChanges) {
661c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("[%" PRIu64 "] getChangedCompositionTypes failed: not validated",
662c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mId);
663c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::NotValidated;
664c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
665c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
666c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if ((outLayers == nullptr) || (outTypes == nullptr)) {
667c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        *outNumElements = mChanges->getTypeChanges().size();
668c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::None;
669c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
670c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
671c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    uint32_t numWritten = 0;
672c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (const auto& element : mChanges->getTypeChanges()) {
673c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (numWritten == *outNumElements) {
674c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
675c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
676c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto layerId = element.first;
677c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto intType = static_cast<int32_t>(element.second);
678c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("Adding %" PRIu64 " %s", layerId,
679c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                to_string(element.second).c_str());
680c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        outLayers[numWritten] = layerId;
681c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        outTypes[numWritten] = intType;
682c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ++numWritten;
683c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
684c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outNumElements = numWritten;
685c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
686c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
687c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
688c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
689c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::getConfigs(uint32_t* outNumConfigs,
690c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc2_config_t* outConfigs)
691c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
692c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
693c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
694c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!outConfigs) {
695c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        *outNumConfigs = mConfigs.size();
696c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::None;
697c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
698c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    uint32_t numWritten = 0;
699c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (const auto& config : mConfigs) {
700c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (numWritten == *outNumConfigs) {
701c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
702c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
703c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        outConfigs[numWritten] = config->getId();
704c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ++numWritten;
705c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
706c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outNumConfigs = numWritten;
707c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
708c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
709c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
710c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::getDozeSupport(int32_t* outSupport)
711c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
712c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
713c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
714c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mDevice.mHwc1MinorVersion < 4 || mHwc1Id != 0) {
715c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        *outSupport = 0;
716c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
717c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        *outSupport = 1;
718c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
719c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
720c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
721c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
722ed40eba4c1264806a1b795bf45b0dea366ee9975Dan StozaError HWC2On1Adapter::Display::getHdrCapabilities(uint32_t* outNumTypes,
723ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza        int32_t* /*outTypes*/, float* /*outMaxLuminance*/,
724ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza        float* /*outMaxAverageLuminance*/, float* /*outMinLuminance*/)
725ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza{
726ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza    // This isn't supported on HWC1, so per the HWC2 header, return numTypes = 0
727ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza    *outNumTypes = 0;
728ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza    return Error::None;
729ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza}
730ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza
731c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::getName(uint32_t* outSize, char* outName)
732c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
733c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
734c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
735c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!outName) {
736c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        *outSize = mName.size();
737c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::None;
738c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
739c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto numCopied = mName.copy(outName, *outSize);
740c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outSize = numCopied;
741c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
742c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
743c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
744c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::getReleaseFences(uint32_t* outNumElements,
745c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc2_layer_t* outLayers, int32_t* outFences)
746c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
747c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
748c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
749c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    uint32_t numWritten = 0;
750c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    bool outputsNonNull = (outLayers != nullptr) && (outFences != nullptr);
751c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (const auto& layer : mLayers) {
752c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (outputsNonNull && (numWritten == *outNumElements)) {
753c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
754c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
755c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
756c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto releaseFence = layer->getReleaseFence();
757c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (releaseFence != Fence::NO_FENCE) {
758c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            if (outputsNonNull) {
759c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                outLayers[numWritten] = layer->getId();
760c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                outFences[numWritten] = releaseFence->dup();
761c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
762c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ++numWritten;
763c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
764c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
765c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outNumElements = numWritten;
766c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
767c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
768c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
769c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
770c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::getRequests(int32_t* outDisplayRequests,
771c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        uint32_t* outNumElements, hwc2_layer_t* outLayers,
772c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        int32_t* outLayerRequests)
773c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
774c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
775c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
776c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!mChanges) {
777c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::NotValidated;
778c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
779c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
780c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (outLayers == nullptr || outLayerRequests == nullptr) {
781c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        *outNumElements = mChanges->getNumLayerRequests();
782c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::None;
783c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
784c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
785c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outDisplayRequests = mChanges->getDisplayRequests();
786c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    uint32_t numWritten = 0;
787c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (const auto& request : mChanges->getLayerRequests()) {
788c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (numWritten == *outNumElements) {
789c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
790c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
791c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        outLayers[numWritten] = request.first;
792c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        outLayerRequests[numWritten] = static_cast<int32_t>(request.second);
793c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ++numWritten;
794c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
795c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
796c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
797c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
798c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
799c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::getType(int32_t* outType)
800c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
801c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
802c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
803c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outType = static_cast<int32_t>(mType);
804c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
805c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
806c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
807c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::present(int32_t* outRetireFence)
808c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
809c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
810c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
811c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mChanges) {
812c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        Error error = mDevice.setAllDisplays();
813c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (error != Error::None) {
814c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGE("[%" PRIu64 "] present: setAllDisplaysFailed (%s)", mId,
815c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    to_string(error).c_str());
816c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return error;
817c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
818c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
819c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
820c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outRetireFence = mRetireFence.get()->dup();
821c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] present returning retire fence %d", mId,
822c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            *outRetireFence);
823c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
824c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
825c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
826c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
827c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::setActiveConfig(hwc2_config_t configId)
828c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
829c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
830c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
831c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto config = getConfig(configId);
832c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!config) {
833c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadConfig;
834c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
835c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mActiveConfig = config;
836c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mDevice.mHwc1MinorVersion >= 4) {
837c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        int error = mDevice.mHwc1Device->setActiveConfig(mDevice.mHwc1Device,
838c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mHwc1Id, static_cast<int>(configId));
839c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE_IF(error != 0,
840c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                "setActiveConfig: Failed to set active config on HWC1 (%d)",
841c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                error);
842c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
843c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
844c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
845c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
846c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::setClientTarget(buffer_handle_t target,
847c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        int32_t acquireFence, int32_t /*dataspace*/)
848c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
849c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
850c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
851c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] setClientTarget(%p, %d)", mId, target, acquireFence);
852c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mClientTarget.setBuffer(target);
853c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mClientTarget.setFence(acquireFence);
854c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // dataspace can't be used by HWC1, so ignore it
855c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
856c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
857c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
8585df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan StozaError HWC2On1Adapter::Display::setColorTransform(android_color_transform_t hint)
8595df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza{
8605df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
8615df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza
8625df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    ALOGV("%" PRIu64 "] setColorTransform(%d)", mId,
8635df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza            static_cast<int32_t>(hint));
8645df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    mHasColorTransform = (hint != HAL_COLOR_TRANSFORM_IDENTITY);
8655df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    return Error::None;
8665df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza}
8675df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza
868c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::setOutputBuffer(buffer_handle_t buffer,
869c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        int32_t releaseFence)
870c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
871c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
872c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
873c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] setOutputBuffer(%p, %d)", mId, buffer, releaseFence);
874c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mOutputBuffer.setBuffer(buffer);
875c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mOutputBuffer.setFence(releaseFence);
876c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
877c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
878c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
879c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic bool isValid(PowerMode mode)
880c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
881c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (mode) {
882c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case PowerMode::Off: // Fall-through
883c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case PowerMode::DozeSuspend: // Fall-through
884c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case PowerMode::Doze: // Fall-through
885c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case PowerMode::On: return true;
886c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        default: return false;
887c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
888c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
889c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
890c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic int getHwc1PowerMode(PowerMode mode)
891c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
892c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (mode) {
893c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case PowerMode::Off: return HWC_POWER_MODE_OFF;
894c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case PowerMode::DozeSuspend: return HWC_POWER_MODE_DOZE_SUSPEND;
895c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case PowerMode::Doze: return HWC_POWER_MODE_DOZE;
896c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case PowerMode::On: return HWC_POWER_MODE_NORMAL;
897c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        default: return HWC_POWER_MODE_OFF;
898c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
899c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
900c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
901c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::setPowerMode(PowerMode mode)
902c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
903c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!isValid(mode)) {
904c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadParameter;
905c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
906c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mode == mPowerMode) {
907c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::None;
908c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
909c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
910c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
911c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
912c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    int error = 0;
913c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mDevice.mHwc1MinorVersion < 4) {
914c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        error = mDevice.mHwc1Device->blank(mDevice.mHwc1Device, mHwc1Id,
915c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mode == PowerMode::Off);
916c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
917c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        error = mDevice.mHwc1Device->setPowerMode(mDevice.mHwc1Device,
918c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mHwc1Id, getHwc1PowerMode(mode));
919c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
920c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGE_IF(error != 0, "setPowerMode: Failed to set power mode on HWC1 (%d)",
921c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            error);
922c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
923c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] setPowerMode(%s)", mId, to_string(mode).c_str());
924c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mPowerMode = mode;
925c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
926c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
927c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
928c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic bool isValid(Vsync enable) {
929c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (enable) {
930c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case Vsync::Enable: // Fall-through
931c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case Vsync::Disable: return true;
932c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        default: return false;
933c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
934c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
935c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
936c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::setVsyncEnabled(Vsync enable)
937c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
938c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!isValid(enable)) {
939c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadParameter;
940c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
941c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (enable == mVsyncEnabled) {
942c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::None;
943c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
944c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
945c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
946c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
947c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    int error = mDevice.mHwc1Device->eventControl(mDevice.mHwc1Device,
948c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            mHwc1Id, HWC_EVENT_VSYNC, enable == Vsync::Enable);
949c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGE_IF(error != 0, "setVsyncEnabled: Failed to set vsync on HWC1 (%d)",
950c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            error);
951c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
952c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mVsyncEnabled = enable;
953c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
954c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
955c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
956c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::validate(uint32_t* outNumTypes,
957c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        uint32_t* outNumRequests)
958c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
959c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
960c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
961c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] Entering validate", mId);
962c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
963c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!mChanges) {
964c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (!mDevice.prepareAllDisplays()) {
965c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return Error::BadDisplay;
966c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
967c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
968c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
969c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outNumTypes = mChanges->getNumTypes();
970c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outNumRequests = mChanges->getNumLayerRequests();
971c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] validate --> %u types, %u requests", mId, *outNumTypes,
972c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            *outNumRequests);
973c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (auto request : mChanges->getTypeChanges()) {
974c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("Layer %" PRIu64 " --> %s", request.first,
975c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                to_string(request.second).c_str());
976c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
977c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return *outNumTypes > 0 ? Error::HasChanges : Error::None;
978c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
979c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
980c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza// Display helpers
981c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
982c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::updateLayerZ(hwc2_layer_t layerId, uint32_t z)
983c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
984c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
985c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
986c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto mapLayer = mDevice.mLayers.find(layerId);
987c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mapLayer == mDevice.mLayers.end()) {
988c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("[%" PRIu64 "] updateLayerZ failed to find layer", mId);
989c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadLayer;
990c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
991c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
992c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto layer = mapLayer->second;
993c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto zRange = mLayers.equal_range(layer);
994c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    bool layerOnDisplay = false;
995c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (auto current = zRange.first; current != zRange.second; ++current) {
996c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (**current == *layer) {
997c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            if ((*current)->getZ() == z) {
998c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                // Don't change anything if the Z hasn't changed
999c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                return Error::None;
1000c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
1001c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            current = mLayers.erase(current);
1002c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            layerOnDisplay = true;
1003c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
1004c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1005c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1006c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1007c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!layerOnDisplay) {
1008c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("[%" PRIu64 "] updateLayerZ failed to find layer on display",
1009c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mId);
1010c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadLayer;
1011c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1012c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1013c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    layer->setZ(z);
1014c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mLayers.emplace(std::move(layer));
1015c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mZIsDirty = true;
1016c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1017c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1018c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1019c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1020c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic constexpr uint32_t ATTRIBUTES[] = {
1021c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    HWC_DISPLAY_VSYNC_PERIOD,
1022c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    HWC_DISPLAY_WIDTH,
1023c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    HWC_DISPLAY_HEIGHT,
1024c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    HWC_DISPLAY_DPI_X,
1025c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    HWC_DISPLAY_DPI_Y,
1026c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    HWC_DISPLAY_NO_ATTRIBUTE,
1027c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza};
1028c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic constexpr size_t NUM_ATTRIBUTES = sizeof(ATTRIBUTES) / sizeof(uint32_t);
1029c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1030c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic constexpr uint32_t ATTRIBUTE_MAP[] = {
1031c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    5, // HWC_DISPLAY_NO_ATTRIBUTE = 0
1032c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    0, // HWC_DISPLAY_VSYNC_PERIOD = 1,
1033c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    1, // HWC_DISPLAY_WIDTH = 2,
1034c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    2, // HWC_DISPLAY_HEIGHT = 3,
1035c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    3, // HWC_DISPLAY_DPI_X = 4,
1036c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    4, // HWC_DISPLAY_DPI_Y = 5,
1037c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza};
1038c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1039c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozatemplate <uint32_t attribute>
1040c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic constexpr bool attributesMatch()
1041c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1042c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return ATTRIBUTES[ATTRIBUTE_MAP[attribute]] == attribute;
1043c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1044c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic_assert(attributesMatch<HWC_DISPLAY_VSYNC_PERIOD>(),
1045c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        "Tables out of sync");
1046c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic_assert(attributesMatch<HWC_DISPLAY_WIDTH>(), "Tables out of sync");
1047c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic_assert(attributesMatch<HWC_DISPLAY_HEIGHT>(), "Tables out of sync");
1048c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic_assert(attributesMatch<HWC_DISPLAY_DPI_X>(), "Tables out of sync");
1049c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic_assert(attributesMatch<HWC_DISPLAY_DPI_Y>(), "Tables out of sync");
1050c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1051c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::populateConfigs()
1052c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1053c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1054c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1055c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] populateConfigs", mId);
1056c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1057c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1Id == -1) {
1058c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("populateConfigs: HWC1 ID not set");
1059c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
1060c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1061c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1062c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const size_t MAX_NUM_CONFIGS = 128;
1063c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    uint32_t configs[MAX_NUM_CONFIGS] = {};
1064c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    size_t numConfigs = MAX_NUM_CONFIGS;
1065c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDevice.mHwc1Device->getDisplayConfigs(mDevice.mHwc1Device, mHwc1Id,
1066c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            configs, &numConfigs);
1067c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1068c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t c = 0; c < numConfigs; ++c) {
1069c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        uint32_t hwc1ConfigId = configs[c];
1070c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc2_config_t id = static_cast<hwc2_config_t>(mConfigs.size());
1071c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mConfigs.emplace_back(
1072c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                std::make_shared<Config>(*this, id, hwc1ConfigId));
1073c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& config = mConfigs[id];
1074c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1075c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        int32_t values[NUM_ATTRIBUTES] = {};
1076c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mDevice.mHwc1Device->getDisplayAttributes(mDevice.mHwc1Device, mHwc1Id,
1077c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwc1ConfigId, ATTRIBUTES, values);
1078c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1079c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        config->setAttribute(Attribute::VsyncPeriod,
1080c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                values[ATTRIBUTE_MAP[HWC_DISPLAY_VSYNC_PERIOD]]);
1081c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        config->setAttribute(Attribute::Width,
1082c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                values[ATTRIBUTE_MAP[HWC_DISPLAY_WIDTH]]);
1083c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        config->setAttribute(Attribute::Height,
1084c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                values[ATTRIBUTE_MAP[HWC_DISPLAY_HEIGHT]]);
1085c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        config->setAttribute(Attribute::DpiX,
1086c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                values[ATTRIBUTE_MAP[HWC_DISPLAY_DPI_X]]);
1087c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        config->setAttribute(Attribute::DpiY,
1088c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                values[ATTRIBUTE_MAP[HWC_DISPLAY_DPI_Y]]);
1089c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1090c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("Found config: %s", config->toString().c_str());
1091c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1092c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1093c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("Getting active config");
1094c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mDevice.mHwc1Device->getActiveConfig != nullptr) {
1095c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto activeConfig = mDevice.mHwc1Device->getActiveConfig(
1096c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mDevice.mHwc1Device, mHwc1Id);
1097c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (activeConfig >= 0) {
1098c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGV("Setting active config to %d", activeConfig);
1099c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            mActiveConfig = mConfigs[activeConfig];
1100c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1101c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
1102c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("getActiveConfig is null, choosing config 0");
1103c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mActiveConfig = mConfigs[0];
1104c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1105c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1106c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1107c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::populateConfigs(uint32_t width, uint32_t height)
1108c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1109c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1110c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1111c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mConfigs.emplace_back(std::make_shared<Config>(*this, 0, 0));
1112c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto& config = mConfigs[0];
1113c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1114c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    config->setAttribute(Attribute::Width, static_cast<int32_t>(width));
1115c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    config->setAttribute(Attribute::Height, static_cast<int32_t>(height));
1116c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mActiveConfig = config;
1117c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1118c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1119c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozabool HWC2On1Adapter::Display::prepare()
1120c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1121c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1122c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1123c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Only prepare display contents for displays HWC1 knows about
1124c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1Id == -1) {
1125c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return true;
1126c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1127c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1128c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // It doesn't make sense to prepare a display for which there is no active
1129c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // config, so return early
1130c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!mActiveConfig) {
1131c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("[%" PRIu64 "] Attempted to prepare, but no config active", mId);
1132c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return false;
1133c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1134c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1135c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] Entering prepare", mId);
1136c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1137c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto currentCount = mHwc1RequestedContents ?
1138c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            mHwc1RequestedContents->numHwLayers : 0;
1139c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto requiredCount = mLayers.size() + 1;
1140c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "]   Requires %zd layers, %zd allocated in %p", mId,
1141c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            requiredCount, currentCount, mHwc1RequestedContents.get());
1142c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1143c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    bool layerCountChanged = (currentCount != requiredCount);
1144c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (layerCountChanged) {
1145c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        reallocateHwc1Contents();
1146c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1147c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1148c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    bool applyAllState = false;
1149c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (layerCountChanged || mZIsDirty) {
1150c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        assignHwc1LayerIds();
1151c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mZIsDirty = false;
1152c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        applyAllState = true;
1153c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1154c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1155c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1RequestedContents->retireFenceFd = -1;
1156c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1RequestedContents->flags = 0;
1157c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (isDirty() || applyAllState) {
1158c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHwc1RequestedContents->flags |= HWC_GEOMETRY_CHANGED;
1159c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1160c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1161c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (auto& layer : mLayers) {
1162c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& hwc1Layer = mHwc1RequestedContents->hwLayers[layer->getHwc1Id()];
1163c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Layer.releaseFenceFd = -1;
1164c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        layer->applyState(hwc1Layer, applyAllState);
1165c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1166c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1167c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1RequestedContents->outbuf = mOutputBuffer.getBuffer();
1168c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1RequestedContents->outbufAcquireFenceFd = mOutputBuffer.getFence();
1169c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1170c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    prepareFramebufferTarget();
1171c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1172c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return true;
1173c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1174c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1175c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic void cloneHWCRegion(hwc_region_t& region)
1176c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1177c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto size = sizeof(hwc_rect_t) * region.numRects;
1178c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto newRects = static_cast<hwc_rect_t*>(std::malloc(size));
1179c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::copy_n(region.rects, region.numRects, newRects);
1180c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    region.rects = newRects;
1181c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1182c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1183c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaHWC2On1Adapter::Display::HWC1Contents
1184c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        HWC2On1Adapter::Display::cloneRequestedContents() const
1185c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1186c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1187c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1188c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    size_t size = sizeof(hwc_display_contents_1_t) +
1189c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            sizeof(hwc_layer_1_t) * (mHwc1RequestedContents->numHwLayers);
1190c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto contents = static_cast<hwc_display_contents_1_t*>(std::malloc(size));
1191c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::memcpy(contents, mHwc1RequestedContents.get(), size);
1192c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t layerId = 0; layerId < contents->numHwLayers; ++layerId) {
1193c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& layer = contents->hwLayers[layerId];
1194c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Deep copy the regions to avoid double-frees
1195c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        cloneHWCRegion(layer.visibleRegionScreen);
1196c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        cloneHWCRegion(layer.surfaceDamage);
1197c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1198c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return HWC1Contents(contents);
1199c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1200c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1201c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::setReceivedContents(HWC1Contents contents)
1202c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1203c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1204c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1205c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1ReceivedContents = std::move(contents);
1206c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1207c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mChanges.reset(new Changes);
1208c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1209c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    size_t numLayers = mHwc1ReceivedContents->numHwLayers;
1210c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t hwc1Id = 0; hwc1Id < numLayers; ++hwc1Id) {
1211c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        const auto& receivedLayer = mHwc1ReceivedContents->hwLayers[hwc1Id];
1212c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (mHwc1LayerMap.count(hwc1Id) == 0) {
1213c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGE_IF(receivedLayer.compositionType != HWC_FRAMEBUFFER_TARGET,
1214c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    "setReceivedContents: HWC1 layer %zd doesn't have a"
1215c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    " matching HWC2 layer, and isn't the framebuffer target",
1216c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    hwc1Id);
1217c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            continue;
1218c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1219c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1220c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        Layer& layer = *mHwc1LayerMap[hwc1Id];
1221c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        updateTypeChanges(receivedLayer, layer);
1222c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        updateLayerRequests(receivedLayer, layer);
1223c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1224c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1225c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1226c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozabool HWC2On1Adapter::Display::hasChanges() const
1227c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1228c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1229c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return mChanges != nullptr;
1230c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1231c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1232c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::set(hwc_display_contents_1& hwcContents)
1233c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1234c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1235c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1236c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!mChanges || (mChanges->getNumTypes() > 0)) {
1237c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("[%" PRIu64 "] set failed: not validated", mId);
1238c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::NotValidated;
1239c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1240c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1241c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Set up the client/framebuffer target
1242c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto numLayers = hwcContents.numHwLayers;
1243c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1244c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Close acquire fences on FRAMEBUFFER layers, since they will not be used
1245c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // by HWC
1246c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t l = 0; l < numLayers - 1; ++l) {
1247c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& layer = hwcContents.hwLayers[l];
1248c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (layer.compositionType == HWC_FRAMEBUFFER) {
1249c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGV("Closing fence %d for layer %zd", layer.acquireFenceFd, l);
1250c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            close(layer.acquireFenceFd);
1251c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            layer.acquireFenceFd = -1;
1252c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1253c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1254c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1255c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto& clientTargetLayer = hwcContents.hwLayers[numLayers - 1];
1256c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (clientTargetLayer.compositionType == HWC_FRAMEBUFFER_TARGET) {
1257c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        clientTargetLayer.handle = mClientTarget.getBuffer();
1258c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        clientTargetLayer.acquireFenceFd = mClientTarget.getFence();
1259c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
1260c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("[%" PRIu64 "] set: last HWC layer wasn't FRAMEBUFFER_TARGET",
1261c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mId);
1262c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1263c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1264c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mChanges.reset();
1265c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1266c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1267c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1268c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1269c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::addRetireFence(int fenceFd)
1270c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1271c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1272c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mRetireFence.add(fenceFd);
1273c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1274c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1275c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::addReleaseFences(
1276c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        const hwc_display_contents_1_t& hwcContents)
1277c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1278c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1279c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1280c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    size_t numLayers = hwcContents.numHwLayers;
1281c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t hwc1Id = 0; hwc1Id < numLayers; ++hwc1Id) {
1282c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        const auto& receivedLayer = hwcContents.hwLayers[hwc1Id];
1283c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (mHwc1LayerMap.count(hwc1Id) == 0) {
1284c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            if (receivedLayer.compositionType != HWC_FRAMEBUFFER_TARGET) {
1285c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                ALOGE("addReleaseFences: HWC1 layer %zd doesn't have a"
1286c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                        " matching HWC2 layer, and isn't the framebuffer"
1287c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                        " target", hwc1Id);
1288c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
1289c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            // Close the framebuffer target release fence since we will use the
1290c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            // display retire fence instead
1291c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            if (receivedLayer.releaseFenceFd != -1) {
1292c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                close(receivedLayer.releaseFenceFd);
1293c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
1294c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            continue;
1295c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1296c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1297c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        Layer& layer = *mHwc1LayerMap[hwc1Id];
1298c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("Adding release fence %d to layer %" PRIu64,
1299c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                receivedLayer.releaseFenceFd, layer.getId());
1300c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        layer.addReleaseFence(receivedLayer.releaseFenceFd);
1301c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1302c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1303c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
13045df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stozabool HWC2On1Adapter::Display::hasColorTransform() const
13055df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza{
13065df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
13075df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    return mHasColorTransform;
13085df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza}
13095df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza
1310c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string hwc1CompositionString(int32_t type)
1311c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1312c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (type) {
1313c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_FRAMEBUFFER: return "Framebuffer";
1314c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_OVERLAY: return "Overlay";
1315c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_BACKGROUND: return "Background";
1316c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_FRAMEBUFFER_TARGET: return "FramebufferTarget";
1317c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_SIDEBAND: return "Sideband";
1318c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_CURSOR_OVERLAY: return "CursorOverlay";
1319c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        default:
1320c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return std::string("Unknown (") + std::to_string(type) + ")";
1321c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1322c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1323c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1324c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string hwc1TransformString(int32_t transform)
1325c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1326c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (transform) {
1327c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case 0: return "None";
1328c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_TRANSFORM_FLIP_H: return "FlipH";
1329c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_TRANSFORM_FLIP_V: return "FlipV";
1330c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_TRANSFORM_ROT_90: return "Rotate90";
1331c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_TRANSFORM_ROT_180: return "Rotate180";
1332c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_TRANSFORM_ROT_270: return "Rotate270";
1333c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_TRANSFORM_FLIP_H_ROT_90: return "FlipHRotate90";
1334c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_TRANSFORM_FLIP_V_ROT_90: return "FlipVRotate90";
1335c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        default:
1336c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return std::string("Unknown (") + std::to_string(transform) + ")";
1337c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1338c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1339c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1340c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string hwc1BlendModeString(int32_t mode)
1341c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1342c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (mode) {
1343c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_BLENDING_NONE: return "None";
1344c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_BLENDING_PREMULT: return "Premultiplied";
1345c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_BLENDING_COVERAGE: return "Coverage";
1346c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        default:
1347c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return std::string("Unknown (") + std::to_string(mode) + ")";
1348c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1349c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1350c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1351c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string rectString(hwc_rect_t rect)
1352c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1353c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::stringstream output;
1354c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "[" << rect.left << ", " << rect.top << ", ";
1355c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << rect.right << ", " << rect.bottom << "]";
1356c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return output.str();
1357c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1358c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1359c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string approximateFloatString(float f)
1360c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1361c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (static_cast<int32_t>(f) == f) {
1362c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return std::to_string(static_cast<int32_t>(f));
1363c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1364c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    int32_t truncated = static_cast<int32_t>(f * 10);
1365c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    bool approximate = (static_cast<float>(truncated) != f * 10);
1366c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const size_t BUFFER_SIZE = 32;
1367c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    char buffer[BUFFER_SIZE] = {};
1368c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto bytesWritten = snprintf(buffer, BUFFER_SIZE,
1369c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            "%s%.1f", approximate ? "~" : "", f);
1370c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return std::string(buffer, bytesWritten);
1371c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1372c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1373c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string frectString(hwc_frect_t frect)
1374c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1375c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::stringstream output;
1376c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "[" << approximateFloatString(frect.left) << ", ";
1377c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << approximateFloatString(frect.top) << ", ";
1378c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << approximateFloatString(frect.right) << ", ";
1379c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << approximateFloatString(frect.bottom) << "]";
1380c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return output.str();
1381c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1382c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1383c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string colorString(hwc_color_t color)
1384c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1385c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::stringstream output;
1386c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "RGBA [";
1387c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << static_cast<int32_t>(color.r) << ", ";
1388c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << static_cast<int32_t>(color.g) << ", ";
1389c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << static_cast<int32_t>(color.b) << ", ";
1390c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << static_cast<int32_t>(color.a) << "]";
1391c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return output.str();
1392c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1393c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1394c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string alphaString(float f)
1395c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1396c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const size_t BUFFER_SIZE = 8;
1397c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    char buffer[BUFFER_SIZE] = {};
1398c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto bytesWritten = snprintf(buffer, BUFFER_SIZE, "%.3f", f);
1399c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return std::string(buffer, bytesWritten);
1400c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1401c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1402c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string to_string(const hwc_layer_1_t& hwcLayer,
1403c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        int32_t hwc1MinorVersion)
1404c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1405c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const char* fill = "          ";
1406c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1407c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::stringstream output;
1408c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1409c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "  Composition: " <<
1410c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            hwc1CompositionString(hwcLayer.compositionType);
1411c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1412c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (hwcLayer.compositionType == HWC_BACKGROUND) {
1413c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "  Color: " << colorString(hwcLayer.backgroundColor) << '\n';
1414c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else if (hwcLayer.compositionType == HWC_SIDEBAND) {
1415c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "  Stream: " << hwcLayer.sidebandStream << '\n';
1416c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
1417c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "  Buffer: " << hwcLayer.handle << "/" <<
1418c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwcLayer.acquireFenceFd << '\n';
1419c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1420c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1421c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << fill << "Display frame: " << rectString(hwcLayer.displayFrame) <<
1422c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            '\n';
1423c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1424c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << fill << "Source crop: ";
1425c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (hwc1MinorVersion >= 3) {
1426c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << frectString(hwcLayer.sourceCropf) << '\n';
1427c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
1428c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << rectString(hwcLayer.sourceCropi) << '\n';
1429c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1430c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1431c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << fill << "Transform: " << hwc1TransformString(hwcLayer.transform);
1432c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "  Blend mode: " << hwc1BlendModeString(hwcLayer.blending);
1433c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (hwcLayer.planeAlpha != 0xFF) {
1434c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "  Alpha: " << alphaString(hwcLayer.planeAlpha / 255.0f);
1435c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1436c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << '\n';
1437c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1438c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (hwcLayer.hints != 0) {
1439c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << fill << "Hints:";
1440c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if ((hwcLayer.hints & HWC_HINT_TRIPLE_BUFFER) != 0) {
1441c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            output << " TripleBuffer";
1442c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1443c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if ((hwcLayer.hints & HWC_HINT_CLEAR_FB) != 0) {
1444c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            output << " ClearFB";
1445c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1446c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << '\n';
1447c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1448c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1449c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (hwcLayer.flags != 0) {
1450c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << fill << "Flags:";
1451c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if ((hwcLayer.flags & HWC_SKIP_LAYER) != 0) {
1452c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            output << " SkipLayer";
1453c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1454c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if ((hwcLayer.flags & HWC_IS_CURSOR_LAYER) != 0) {
1455c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            output << " IsCursorLayer";
1456c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1457c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << '\n';
1458c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1459c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1460c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return output.str();
1461c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1462c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1463c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string to_string(const hwc_display_contents_1_t& hwcContents,
1464c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        int32_t hwc1MinorVersion)
1465c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1466c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const char* fill = "      ";
1467c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1468c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::stringstream output;
1469c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << fill << "Geometry changed: " <<
1470c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ((hwcContents.flags & HWC_GEOMETRY_CHANGED) != 0 ? "Y\n" : "N\n");
1471c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1472c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << fill << hwcContents.numHwLayers << " Layer" <<
1473c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ((hwcContents.numHwLayers == 1) ? "\n" : "s\n");
1474c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t layer = 0; layer < hwcContents.numHwLayers; ++layer) {
1475c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << fill << "  Layer " << layer;
1476c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << to_string(hwcContents.hwLayers[layer], hwc1MinorVersion);
1477c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1478c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1479c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (hwcContents.outbuf != nullptr) {
1480c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << fill << "Output buffer: " << hwcContents.outbuf << "/" <<
1481c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwcContents.outbufAcquireFenceFd << '\n';
1482c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1483c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1484c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return output.str();
1485c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1486c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1487c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastd::string HWC2On1Adapter::Display::dump() const
1488c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1489c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1490c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1491c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::stringstream output;
1492c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1493c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "  Display " << mId << ": ";
1494c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << to_string(mType) << "  ";
1495c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "HWC1 ID: " << mHwc1Id << "  ";
1496c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "Power mode: " << to_string(mPowerMode) << "  ";
1497c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "Vsync: " << to_string(mVsyncEnabled) << '\n';
1498c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1499c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "    " << mConfigs.size() << " Config" <<
1500c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            (mConfigs.size() == 1 ? "" : "s") << " (* Active)\n";
1501c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (const auto& config : mConfigs) {
1502c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (config == mActiveConfig) {
1503c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            output << "    * " << config->toString();
1504c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        } else {
1505c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            output << "      " << config->toString();
1506c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1507c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1508c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << '\n';
1509c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1510c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "    " << mLayers.size() << " Layer" <<
1511c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            (mLayers.size() == 1 ? "" : "s") << '\n';
1512c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (const auto& layer : mLayers) {
1513c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << layer->dump();
1514c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1515c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1516c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "    Client target: " << mClientTarget.getBuffer() << '\n';
1517c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1518c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mOutputBuffer.getBuffer() != nullptr) {
1519c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "    Output buffer: " << mOutputBuffer.getBuffer() << '\n';
1520c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1521c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1522c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1ReceivedContents) {
1523c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "    Last received HWC1 state\n";
1524c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << to_string(*mHwc1ReceivedContents, mDevice.mHwc1MinorVersion);
1525c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else if (mHwc1RequestedContents) {
1526c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "    Last requested HWC1 state\n";
1527c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << to_string(*mHwc1RequestedContents, mDevice.mHwc1MinorVersion);
1528c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1529c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1530c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return output.str();
1531c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1532c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1533c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::Config::setAttribute(HWC2::Attribute attribute,
1534c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        int32_t value)
1535c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1536c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mAttributes[attribute] = value;
1537c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1538c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1539c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozaint32_t HWC2On1Adapter::Display::Config::getAttribute(Attribute attribute) const
1540c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1541c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mAttributes.count(attribute) == 0) {
1542c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return -1;
1543c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1544c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return mAttributes.at(attribute);
1545c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1546c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1547c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastd::string HWC2On1Adapter::Display::Config::toString() const
1548c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1549c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::string output;
1550c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1551c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const size_t BUFFER_SIZE = 100;
1552c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    char buffer[BUFFER_SIZE] = {};
1553c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto writtenBytes = snprintf(buffer, BUFFER_SIZE,
1554c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            "[%u] %u x %u", mHwcId,
1555c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            mAttributes.at(HWC2::Attribute::Width),
1556c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            mAttributes.at(HWC2::Attribute::Height));
1557c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output.append(buffer, writtenBytes);
1558c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1559c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mAttributes.count(HWC2::Attribute::VsyncPeriod) != 0) {
1560c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        std::memset(buffer, 0, BUFFER_SIZE);
1561c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        writtenBytes = snprintf(buffer, BUFFER_SIZE, " @ %.1f Hz",
1562c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                1e9 / mAttributes.at(HWC2::Attribute::VsyncPeriod));
1563c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output.append(buffer, writtenBytes);
1564c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1565c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1566c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mAttributes.count(HWC2::Attribute::DpiX) != 0 &&
1567c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            mAttributes.at(HWC2::Attribute::DpiX) != -1) {
1568c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        std::memset(buffer, 0, BUFFER_SIZE);
1569c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        writtenBytes = snprintf(buffer, BUFFER_SIZE,
1570c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                ", DPI: %.1f x %.1f",
1571c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mAttributes.at(HWC2::Attribute::DpiX) / 1000.0f,
1572c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mAttributes.at(HWC2::Attribute::DpiY) / 1000.0f);
1573c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output.append(buffer, writtenBytes);
1574c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1575c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1576c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return output;
1577c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1578c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1579c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastd::shared_ptr<const HWC2On1Adapter::Display::Config>
1580c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        HWC2On1Adapter::Display::getConfig(hwc2_config_t configId) const
1581c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1582c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (configId > mConfigs.size() || !mConfigs[configId]->isOnDisplay(*this)) {
1583c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return nullptr;
1584c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1585c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return mConfigs[configId];
1586c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1587c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1588c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::reallocateHwc1Contents()
1589c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1590c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Allocate an additional layer for the framebuffer target
1591c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto numLayers = mLayers.size() + 1;
1592c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    size_t size = sizeof(hwc_display_contents_1_t) +
1593c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            sizeof(hwc_layer_1_t) * numLayers;
1594c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] reallocateHwc1Contents creating %zd layer%s", mId,
1595c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            numLayers, numLayers != 1 ? "s" : "");
1596c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto contents =
1597c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            static_cast<hwc_display_contents_1_t*>(std::calloc(size, 1));
1598c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    contents->numHwLayers = numLayers;
1599c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1RequestedContents.reset(contents);
1600c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1601c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1602c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::assignHwc1LayerIds()
1603c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1604c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1LayerMap.clear();
1605c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    size_t nextHwc1Id = 0;
1606c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (auto& layer : mLayers) {
1607c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHwc1LayerMap[nextHwc1Id] = layer;
1608c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        layer->setHwc1Id(nextHwc1Id++);
1609c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1610c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1611c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1612c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::updateTypeChanges(const hwc_layer_1_t& hwc1Layer,
1613c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        const Layer& layer)
1614c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1615c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto layerId = layer.getId();
1616c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (hwc1Layer.compositionType) {
1617c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_FRAMEBUFFER:
1618c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            if (layer.getCompositionType() != Composition::Client) {
1619c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mChanges->addTypeChange(layerId, Composition::Client);
1620c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
1621c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
1622c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_OVERLAY:
1623c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            if (layer.getCompositionType() != Composition::Device) {
1624c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mChanges->addTypeChange(layerId, Composition::Device);
1625c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
1626c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
1627c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_BACKGROUND:
1628c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGE_IF(layer.getCompositionType() != Composition::SolidColor,
1629c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    "updateTypeChanges: HWC1 requested BACKGROUND, but HWC2"
1630c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    " wasn't expecting SolidColor");
1631c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
1632c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_FRAMEBUFFER_TARGET:
1633c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            // Do nothing, since it shouldn't be modified by HWC1
1634c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
1635c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_SIDEBAND:
1636c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGE_IF(layer.getCompositionType() != Composition::Sideband,
1637c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    "updateTypeChanges: HWC1 requested SIDEBAND, but HWC2"
1638c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    " wasn't expecting Sideband");
1639c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
1640c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_CURSOR_OVERLAY:
1641c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGE_IF(layer.getCompositionType() != Composition::Cursor,
1642c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    "updateTypeChanges: HWC1 requested CURSOR_OVERLAY, but"
1643c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    " HWC2 wasn't expecting Cursor");
1644c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
1645c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1646c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1647c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1648c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::updateLayerRequests(
1649c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        const hwc_layer_1_t& hwc1Layer, const Layer& layer)
1650c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1651c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if ((hwc1Layer.hints & HWC_HINT_CLEAR_FB) != 0) {
1652c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mChanges->addLayerRequest(layer.getId(),
1653c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                LayerRequest::ClearClientTarget);
1654c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1655c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1656c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1657c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::prepareFramebufferTarget()
1658c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1659c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // We check that mActiveConfig is valid in Display::prepare
1660c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    int32_t width = mActiveConfig->getAttribute(Attribute::Width);
1661c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    int32_t height = mActiveConfig->getAttribute(Attribute::Height);
1662c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1663c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto& hwc1Target = mHwc1RequestedContents->hwLayers[mLayers.size()];
1664c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.compositionType = HWC_FRAMEBUFFER_TARGET;
1665c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.releaseFenceFd = -1;
1666c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.hints = 0;
1667c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.flags = 0;
1668c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.transform = 0;
1669c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.blending = HWC_BLENDING_PREMULT;
1670c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mDevice.getHwc1MinorVersion() < 3) {
1671c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Target.sourceCropi = {0, 0, width, height};
1672c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
1673c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Target.sourceCropf = {0.0f, 0.0f, static_cast<float>(width),
1674c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                static_cast<float>(height)};
1675c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1676c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.displayFrame = {0, 0, width, height};
1677c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.planeAlpha = 255;
1678c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.visibleRegionScreen.numRects = 1;
1679c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto rects = static_cast<hwc_rect_t*>(std::malloc(sizeof(hwc_rect_t)));
1680c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    rects[0].left = 0;
1681c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    rects[0].top = 0;
1682c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    rects[0].right = width;
1683c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    rects[0].bottom = height;
1684c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.visibleRegionScreen.rects = rects;
1685c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1686c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // We will set this to the correct value in set
1687c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.acquireFenceFd = -1;
1688c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1689c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1690c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza// Layer functions
1691c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1692c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastd::atomic<hwc2_layer_t> HWC2On1Adapter::Layer::sNextId(1);
1693c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1694c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaHWC2On1Adapter::Layer::Layer(Display& display)
1695c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza  : mId(sNextId++),
1696c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDisplay(display),
1697fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    mDirtyCount(0),
1698fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    mBuffer(),
1699fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    mSurfaceDamage(),
1700c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mBlendMode(*this, BlendMode::None),
1701c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mColor(*this, {0, 0, 0, 0}),
1702c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mCompositionType(*this, Composition::Invalid),
1703c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDisplayFrame(*this, {0, 0, -1, -1}),
1704c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mPlaneAlpha(*this, 0.0f),
1705c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mSidebandStream(*this, nullptr),
1706c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mSourceCrop(*this, {0.0f, 0.0f, -1.0f, -1.0f}),
1707c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mTransform(*this, Transform::None),
1708c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mVisibleRegion(*this, std::vector<hwc_rect_t>()),
1709c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mZ(0),
1710fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    mReleaseFence(),
1711c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1Id(0),
17125df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    mHasUnsupportedDataspace(false),
1713c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHasUnsupportedPlaneAlpha(false) {}
1714c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1715c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozabool HWC2On1Adapter::SortLayersByZ::operator()(
1716c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        const std::shared_ptr<Layer>& lhs, const std::shared_ptr<Layer>& rhs)
1717c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1718c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return lhs->getZ() < rhs->getZ();
1719c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1720c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1721c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setBuffer(buffer_handle_t buffer,
1722c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        int32_t acquireFence)
1723c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1724c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("Setting acquireFence to %d for layer %" PRIu64, acquireFence, mId);
1725c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mBuffer.setBuffer(buffer);
1726c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mBuffer.setFence(acquireFence);
1727c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1728c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1729c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1730c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setCursorPosition(int32_t x, int32_t y)
1731c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1732c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mCompositionType.getValue() != Composition::Cursor) {
1733c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadLayer;
1734c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1735c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1736c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mDisplay.hasChanges()) {
1737c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::NotValidated;
1738c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1739c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1740c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto displayId = mDisplay.getHwc1Id();
1741c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto hwc1Device = mDisplay.getDevice().getHwc1Device();
1742c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Device->setCursorPositionAsync(hwc1Device, displayId, x, y);
1743c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1744c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1745c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1746c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setSurfaceDamage(hwc_region_t damage)
1747c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1748c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mSurfaceDamage.resize(damage.numRects);
1749c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::copy_n(damage.rects, damage.numRects, mSurfaceDamage.begin());
1750c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1751c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1752c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1753c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza// Layer state functions
1754c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1755c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setBlendMode(BlendMode mode)
1756c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1757c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mBlendMode.setPending(mode);
1758c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1759c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1760c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1761c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setColor(hwc_color_t color)
1762c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1763c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mColor.setPending(color);
1764c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1765c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1766c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1767c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setCompositionType(Composition type)
1768c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1769c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mCompositionType.setPending(type);
1770c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1771c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1772c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
17735df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan StozaError HWC2On1Adapter::Layer::setDataspace(android_dataspace_t dataspace)
17745df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza{
17755df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    mHasUnsupportedDataspace = (dataspace != HAL_DATASPACE_UNKNOWN);
17765df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    return Error::None;
17775df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza}
17785df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza
1779c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setDisplayFrame(hwc_rect_t frame)
1780c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1781c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDisplayFrame.setPending(frame);
1782c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1783c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1784c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1785c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setPlaneAlpha(float alpha)
1786c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1787c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mPlaneAlpha.setPending(alpha);
1788c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1789c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1790c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1791c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setSidebandStream(const native_handle_t* stream)
1792c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1793c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mSidebandStream.setPending(stream);
1794c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1795c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1796c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1797c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setSourceCrop(hwc_frect_t crop)
1798c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1799c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mSourceCrop.setPending(crop);
1800c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1801c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1802c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1803c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setTransform(Transform transform)
1804c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1805c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mTransform.setPending(transform);
1806c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1807c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1808c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1809c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setVisibleRegion(hwc_region_t rawVisible)
1810c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1811c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::vector<hwc_rect_t> visible(rawVisible.rects,
1812c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            rawVisible.rects + rawVisible.numRects);
1813c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mVisibleRegion.setPending(std::move(visible));
1814c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1815c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1816c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1817c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setZ(uint32_t z)
1818c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1819c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mZ = z;
1820c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1821c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1822c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1823c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Layer::addReleaseFence(int fenceFd)
1824c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1825c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("addReleaseFence %d to layer %" PRIu64, fenceFd, mId);
1826c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mReleaseFence.add(fenceFd);
1827c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1828c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1829c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozaconst sp<Fence>& HWC2On1Adapter::Layer::getReleaseFence() const
1830c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1831c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return mReleaseFence.get();
1832c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1833c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1834c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Layer::applyState(hwc_layer_1_t& hwc1Layer,
1835c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        bool applyAllState)
1836c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1837c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    applyCommonState(hwc1Layer, applyAllState);
1838c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto compositionType = mCompositionType.getPendingValue();
1839c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (compositionType == Composition::SolidColor) {
1840c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        applySolidColorState(hwc1Layer, applyAllState);
1841c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else if (compositionType == Composition::Sideband) {
1842c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        applySidebandState(hwc1Layer, applyAllState);
1843c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
1844c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        applyBufferState(hwc1Layer);
1845c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1846c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    applyCompositionType(hwc1Layer, applyAllState);
1847c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1848c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1849c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza// Layer dump helpers
1850c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1851c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string regionStrings(const std::vector<hwc_rect_t>& visibleRegion,
1852c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        const std::vector<hwc_rect_t>& surfaceDamage)
1853c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1854c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::string regions;
1855c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    regions += "        Visible Region";
1856c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    regions.resize(40, ' ');
1857c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    regions += "Surface Damage\n";
1858c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1859c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    size_t numPrinted = 0;
1860c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    size_t maxSize = std::max(visibleRegion.size(), surfaceDamage.size());
1861c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    while (numPrinted < maxSize) {
1862c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        std::string line("        ");
1863c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (visibleRegion.empty() && numPrinted == 0) {
1864c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            line += "None";
1865c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        } else if (numPrinted < visibleRegion.size()) {
1866c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            line += rectString(visibleRegion[numPrinted]);
1867c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1868c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        line.resize(40, ' ');
1869c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (surfaceDamage.empty() && numPrinted == 0) {
1870c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            line += "None";
1871c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        } else if (numPrinted < surfaceDamage.size()) {
1872c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            line += rectString(surfaceDamage[numPrinted]);
1873c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1874c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        line += '\n';
1875c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        regions += line;
1876c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ++numPrinted;
1877c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1878c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return regions;
1879c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1880c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1881c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastd::string HWC2On1Adapter::Layer::dump() const
1882c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1883c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::stringstream output;
1884c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const char* fill = "      ";
1885c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1886c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << fill << to_string(mCompositionType.getPendingValue());
1887c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << " Layer  HWC2/1: " << mId << "/" << mHwc1Id << "  ";
1888c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "Z: " << mZ;
1889c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mCompositionType.getValue() == HWC2::Composition::SolidColor) {
1890c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "  " << colorString(mColor.getValue());
1891c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else if (mCompositionType.getValue() == HWC2::Composition::Sideband) {
1892c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "  Handle: " << mSidebandStream.getValue() << '\n';
1893c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
1894c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "  Buffer: " << mBuffer.getBuffer() << "/" <<
1895c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mBuffer.getFence() << '\n';
1896c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << fill << "  Display frame [LTRB]: " <<
1897c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                rectString(mDisplayFrame.getValue()) << '\n';
1898c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << fill << "  Source crop: " <<
1899c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                frectString(mSourceCrop.getValue()) << '\n';
1900c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << fill << "  Transform: " << to_string(mTransform.getValue());
1901c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "  Blend mode: " << to_string(mBlendMode.getValue());
1902c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (mPlaneAlpha.getValue() != 1.0f) {
1903c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            output << "  Alpha: " <<
1904c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                alphaString(mPlaneAlpha.getValue()) << '\n';
1905c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        } else {
1906c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            output << '\n';
1907c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1908c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << regionStrings(mVisibleRegion.getValue(), mSurfaceDamage);
1909c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1910c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return output.str();
1911c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1912c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1913c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic int getHwc1Blending(HWC2::BlendMode blendMode)
1914c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1915c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (blendMode) {
1916c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case BlendMode::Coverage: return HWC_BLENDING_COVERAGE;
1917c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case BlendMode::Premultiplied: return HWC_BLENDING_PREMULT;
1918c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        default: return HWC_BLENDING_NONE;
1919c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1920c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1921c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1922c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Layer::applyCommonState(hwc_layer_1_t& hwc1Layer,
1923c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        bool applyAllState)
1924c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1925c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto minorVersion = mDisplay.getDevice().getHwc1MinorVersion();
1926c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (applyAllState || mBlendMode.isDirty()) {
1927c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Layer.blending = getHwc1Blending(mBlendMode.getPendingValue());
1928c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mBlendMode.latch();
1929c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1930c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (applyAllState || mDisplayFrame.isDirty()) {
1931c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Layer.displayFrame = mDisplayFrame.getPendingValue();
1932c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mDisplayFrame.latch();
1933c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1934c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (applyAllState || mPlaneAlpha.isDirty()) {
1935c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto pendingAlpha = mPlaneAlpha.getPendingValue();
1936c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (minorVersion < 2) {
1937c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            mHasUnsupportedPlaneAlpha = pendingAlpha < 1.0f;
1938c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        } else {
1939c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            hwc1Layer.planeAlpha =
1940c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    static_cast<uint8_t>(255.0f * pendingAlpha + 0.5f);
1941c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1942c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mPlaneAlpha.latch();
1943c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1944c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (applyAllState || mSourceCrop.isDirty()) {
1945c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (minorVersion < 3) {
1946c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto pending = mSourceCrop.getPendingValue();
1947c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            hwc1Layer.sourceCropi.left =
1948c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    static_cast<int32_t>(std::ceil(pending.left));
1949c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            hwc1Layer.sourceCropi.top =
1950c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    static_cast<int32_t>(std::ceil(pending.top));
1951c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            hwc1Layer.sourceCropi.right =
1952c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    static_cast<int32_t>(std::floor(pending.right));
1953c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            hwc1Layer.sourceCropi.bottom =
1954c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    static_cast<int32_t>(std::floor(pending.bottom));
1955c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        } else {
1956c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            hwc1Layer.sourceCropf = mSourceCrop.getPendingValue();
1957c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1958c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mSourceCrop.latch();
1959c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1960c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (applyAllState || mTransform.isDirty()) {
1961c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Layer.transform =
1962c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                static_cast<uint32_t>(mTransform.getPendingValue());
1963c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mTransform.latch();
1964c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1965c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (applyAllState || mVisibleRegion.isDirty()) {
1966c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& hwc1VisibleRegion = hwc1Layer.visibleRegionScreen;
1967c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1968c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        std::free(const_cast<hwc_rect_t*>(hwc1VisibleRegion.rects));
1969c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1970c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto pending = mVisibleRegion.getPendingValue();
1971c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc_rect_t* newRects = static_cast<hwc_rect_t*>(
1972c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                std::malloc(sizeof(hwc_rect_t) * pending.size()));
1973c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        std::copy(pending.begin(), pending.end(), newRects);
1974c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1VisibleRegion.rects = const_cast<const hwc_rect_t*>(newRects);
1975c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1VisibleRegion.numRects = pending.size();
1976c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mVisibleRegion.latch();
1977c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1978c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1979c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1980c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Layer::applySolidColorState(hwc_layer_1_t& hwc1Layer,
1981c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        bool applyAllState)
1982c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1983c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (applyAllState || mColor.isDirty()) {
1984c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Layer.backgroundColor = mColor.getPendingValue();
1985c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mColor.latch();
1986c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1987c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1988c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1989c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Layer::applySidebandState(hwc_layer_1_t& hwc1Layer,
1990c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        bool applyAllState)
1991c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1992c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (applyAllState || mSidebandStream.isDirty()) {
1993c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Layer.sidebandStream = mSidebandStream.getPendingValue();
1994c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mSidebandStream.latch();
1995c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1996c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1997c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1998c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Layer::applyBufferState(hwc_layer_1_t& hwc1Layer)
1999c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2000c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Layer.handle = mBuffer.getBuffer();
2001c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Layer.acquireFenceFd = mBuffer.getFence();
2002c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2003c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2004c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Layer::applyCompositionType(hwc_layer_1_t& hwc1Layer,
2005c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        bool applyAllState)
2006c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
20075df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    // HWC1 never supports color transforms or dataspaces and only sometimes
20085df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    // supports plane alpha (depending on the version). These require us to drop
20095df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    // some or all layers to client composition.
20105df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    if (mHasUnsupportedDataspace || mHasUnsupportedPlaneAlpha ||
20115df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza            mDisplay.hasColorTransform()) {
2012c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2013c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Layer.flags = HWC_SKIP_LAYER;
2014c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
2015c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2016c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2017c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (applyAllState || mCompositionType.isDirty()) {
2018c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Layer.flags = 0;
2019c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        switch (mCompositionType.getPendingValue()) {
2020c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            case Composition::Client:
2021c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2022c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwc1Layer.flags |= HWC_SKIP_LAYER;
2023c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                break;
2024c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            case Composition::Device:
2025c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2026c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                break;
2027c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            case Composition::SolidColor:
2028c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwc1Layer.compositionType = HWC_BACKGROUND;
2029c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                break;
2030c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            case Composition::Cursor:
2031c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2032c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                if (mDisplay.getDevice().getHwc1MinorVersion() >= 4) {
2033c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    hwc1Layer.hints |= HWC_IS_CURSOR_LAYER;
2034c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                }
2035c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                break;
2036c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            case Composition::Sideband:
2037c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                if (mDisplay.getDevice().getHwc1MinorVersion() < 4) {
2038c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    hwc1Layer.compositionType = HWC_SIDEBAND;
2039c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                } else {
2040c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2041c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    hwc1Layer.flags |= HWC_SKIP_LAYER;
2042c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                }
2043c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                break;
2044c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            default:
2045c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2046c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwc1Layer.flags |= HWC_SKIP_LAYER;
2047c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                break;
2048c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2049c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("Layer %" PRIu64 " %s set to %d", mId,
2050c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                to_string(mCompositionType.getPendingValue()).c_str(),
2051c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwc1Layer.compositionType);
2052c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV_IF(hwc1Layer.flags & HWC_SKIP_LAYER, "    and skipping");
2053c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mCompositionType.latch();
2054c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2055c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2056c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2057c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza// Adapter helpers
2058c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2059c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::populateCapabilities()
2060c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2061c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("populateCapabilities");
2062c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1MinorVersion >= 3U) {
2063c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        int supportedTypes = 0;
2064c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto result = mHwc1Device->query(mHwc1Device,
2065c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                HWC_DISPLAY_TYPES_SUPPORTED, &supportedTypes);
2066c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if ((result == 0) && ((supportedTypes & HWC_DISPLAY_VIRTUAL) != 0)) {
2067c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGI("Found support for HWC virtual displays");
2068c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            mHwc1SupportsVirtualDisplays = true;
2069c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2070c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2071c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1MinorVersion >= 4U) {
2072c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mCapabilities.insert(Capability::SidebandStream);
2073c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2074c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2075c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2076c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaHWC2On1Adapter::Display* HWC2On1Adapter::getDisplay(hwc2_display_t id)
2077c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2078fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2079c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2080c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto display = mDisplays.find(id);
2081c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (display == mDisplays.end()) {
2082c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return nullptr;
2083c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2084c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2085c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return display->second.get();
2086c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2087c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2088c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastd::tuple<HWC2On1Adapter::Layer*, Error> HWC2On1Adapter::getLayer(
2089c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc2_display_t displayId, hwc2_layer_t layerId)
2090c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2091c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto display = getDisplay(displayId);
2092c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!display) {
2093c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadDisplay);
2094c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2095c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2096c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto layerEntry = mLayers.find(layerId);
2097c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (layerEntry == mLayers.end()) {
2098c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadLayer);
2099c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2100c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2101c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto layer = layerEntry->second;
2102c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (layer->getDisplay().getId() != displayId) {
2103c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadLayer);
2104c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2105c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return std::make_tuple(layer.get(), Error::None);
2106c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2107c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2108c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::populatePrimary()
2109c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2110c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("populatePrimary");
2111c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2112fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2113c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2114c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto display =
2115c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            std::make_shared<Display>(*this, HWC2::DisplayType::Physical);
2116c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1DisplayMap[HWC_DISPLAY_PRIMARY] = display->getId();
2117c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    display->setHwc1Id(HWC_DISPLAY_PRIMARY);
2118c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    display->populateConfigs();
2119c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDisplays.emplace(display->getId(), std::move(display));
2120c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2121c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2122c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozabool HWC2On1Adapter::prepareAllDisplays()
2123c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2124c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ATRACE_CALL();
2125c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2126fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2127c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2128c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (const auto& displayPair : mDisplays) {
2129c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& display = displayPair.second;
2130c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (!display->prepare()) {
2131c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return false;
2132c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2133c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2134c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2135c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1DisplayMap.count(0) == 0) {
2136c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("prepareAllDisplays: Unable to find primary HWC1 display");
2137c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return false;
2138c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2139c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2140c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Always push the primary display
2141c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::vector<HWC2On1Adapter::Display::HWC1Contents> requestedContents;
2142c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto primaryDisplayId = mHwc1DisplayMap[HWC_DISPLAY_PRIMARY];
2143c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto& primaryDisplay = mDisplays[primaryDisplayId];
2144c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto primaryDisplayContents = primaryDisplay->cloneRequestedContents();
2145c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    requestedContents.push_back(std::move(primaryDisplayContents));
2146c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2147c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Push the external display, if present
2148c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1DisplayMap.count(HWC_DISPLAY_EXTERNAL) != 0) {
2149c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto externalDisplayId = mHwc1DisplayMap[HWC_DISPLAY_EXTERNAL];
2150c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& externalDisplay = mDisplays[externalDisplayId];
2151c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto externalDisplayContents =
2152c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                externalDisplay->cloneRequestedContents();
2153c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        requestedContents.push_back(std::move(externalDisplayContents));
2154c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
2155c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Even if an external display isn't present, we still need to send
2156c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // at least two displays down to HWC1
2157c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        requestedContents.push_back(nullptr);
2158c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2159c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2160c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Push the hardware virtual display, if supported and present
2161c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1MinorVersion >= 3) {
2162c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (mHwc1DisplayMap.count(HWC_DISPLAY_VIRTUAL) != 0) {
2163c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto virtualDisplayId = mHwc1DisplayMap[HWC_DISPLAY_VIRTUAL];
2164c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto& virtualDisplay = mDisplays[virtualDisplayId];
2165c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto virtualDisplayContents =
2166c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    virtualDisplay->cloneRequestedContents();
2167c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            requestedContents.push_back(std::move(virtualDisplayContents));
2168c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        } else {
2169c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            requestedContents.push_back(nullptr);
2170c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2171c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2172c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2173c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1Contents.clear();
2174c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (auto& displayContents : requestedContents) {
2175c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHwc1Contents.push_back(displayContents.get());
2176c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (!displayContents) {
2177c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            continue;
2178c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2179c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2180c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("Display %zd layers:", mHwc1Contents.size() - 1);
2181c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (size_t l = 0; l < displayContents->numHwLayers; ++l) {
2182c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto& layer = displayContents->hwLayers[l];
2183c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGV("  %zd: %d", l, layer.compositionType);
2184c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2185c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2186c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2187c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("Calling HWC1 prepare");
2188c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    {
2189c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ATRACE_NAME("HWC1 prepare");
2190c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHwc1Device->prepare(mHwc1Device, mHwc1Contents.size(),
2191c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mHwc1Contents.data());
2192c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2193c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2194c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t c = 0; c < mHwc1Contents.size(); ++c) {
2195c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& contents = mHwc1Contents[c];
2196c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (!contents) {
2197c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            continue;
2198c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2199c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("Display %zd layers:", c);
2200c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (size_t l = 0; l < contents->numHwLayers; ++l) {
2201c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGV("  %zd: %d", l, contents->hwLayers[l].compositionType);
2202c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2203c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2204c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2205c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Return the received contents to their respective displays
2206c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t hwc1Id = 0; hwc1Id < mHwc1Contents.size(); ++hwc1Id) {
2207c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (mHwc1Contents[hwc1Id] == nullptr) {
2208c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            continue;
2209c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2210c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2211c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto displayId = mHwc1DisplayMap[hwc1Id];
2212c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& display = mDisplays[displayId];
2213c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        display->setReceivedContents(std::move(requestedContents[hwc1Id]));
2214c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2215c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2216c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return true;
2217c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2218c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2219c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::setAllDisplays()
2220c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2221c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ATRACE_CALL();
2222c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2223fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2224c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2225c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Make sure we're ready to validate
2226c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t hwc1Id = 0; hwc1Id < mHwc1Contents.size(); ++hwc1Id) {
2227c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (mHwc1Contents[hwc1Id] == nullptr) {
2228c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            continue;
2229c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2230c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2231c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto displayId = mHwc1DisplayMap[hwc1Id];
2232c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& display = mDisplays[displayId];
2233c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        Error error = display->set(*mHwc1Contents[hwc1Id]);
2234c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (error != Error::None) {
2235c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGE("setAllDisplays: Failed to set display %zd: %s", hwc1Id,
2236c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    to_string(error).c_str());
2237c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return error;
2238c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2239c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2240c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2241c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("Calling HWC1 set");
2242c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    {
2243c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ATRACE_NAME("HWC1 set");
2244c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHwc1Device->set(mHwc1Device, mHwc1Contents.size(),
2245c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mHwc1Contents.data());
2246c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2247c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2248c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Add retire and release fences
2249c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t hwc1Id = 0; hwc1Id < mHwc1Contents.size(); ++hwc1Id) {
2250c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (mHwc1Contents[hwc1Id] == nullptr) {
2251c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            continue;
2252c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2253c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2254c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto displayId = mHwc1DisplayMap[hwc1Id];
2255c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& display = mDisplays[displayId];
2256c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto retireFenceFd = mHwc1Contents[hwc1Id]->retireFenceFd;
2257c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("setAllDisplays: Adding retire fence %d to display %zd",
2258c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                retireFenceFd, hwc1Id);
2259c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        display->addRetireFence(mHwc1Contents[hwc1Id]->retireFenceFd);
2260c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        display->addReleaseFences(*mHwc1Contents[hwc1Id]);
2261c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2262c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2263c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
2264c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2265c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2266c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::hwc1Invalidate()
2267c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2268c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("Received hwc1Invalidate");
2269c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2270fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2271c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2272c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // If the HWC2-side callback hasn't been registered yet, buffer this until
2273c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // it is registered
2274c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mCallbacks.count(Callback::Refresh) == 0) {
2275c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHasPendingInvalidate = true;
2276c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
2277c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2278c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2279c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto& callbackInfo = mCallbacks[Callback::Refresh];
2280c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::vector<hwc2_display_t> displays;
2281c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (const auto& displayPair : mDisplays) {
2282c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        displays.emplace_back(displayPair.first);
2283c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2284c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2285c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Call back without the state lock held
2286c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    lock.unlock();
2287c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2288c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto refresh = reinterpret_cast<HWC2_PFN_REFRESH>(callbackInfo.pointer);
2289c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (auto display : displays) {
2290c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        refresh(callbackInfo.data, display);
2291c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2292c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2293c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2294c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::hwc1Vsync(int hwc1DisplayId, int64_t timestamp)
2295c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2296c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("Received hwc1Vsync(%d, %" PRId64 ")", hwc1DisplayId, timestamp);
2297c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2298fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2299c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2300c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // If the HWC2-side callback hasn't been registered yet, buffer this until
2301c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // it is registered
2302c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mCallbacks.count(Callback::Vsync) == 0) {
2303c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mPendingVsyncs.emplace_back(hwc1DisplayId, timestamp);
2304c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
2305c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2306c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2307c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
2308c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("hwc1Vsync: Couldn't find display for HWC1 id %d", hwc1DisplayId);
2309c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
2310c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2311c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2312c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto& callbackInfo = mCallbacks[Callback::Vsync];
2313c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto displayId = mHwc1DisplayMap[hwc1DisplayId];
2314c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2315c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Call back without the state lock held
2316c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    lock.unlock();
2317c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2318c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto vsync = reinterpret_cast<HWC2_PFN_VSYNC>(callbackInfo.pointer);
2319c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    vsync(callbackInfo.data, displayId, timestamp);
2320c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2321c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2322c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::hwc1Hotplug(int hwc1DisplayId, int connected)
2323c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
2324c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("Received hwc1Hotplug(%d, %d)", hwc1DisplayId, connected);
2325c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2326c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (hwc1DisplayId != HWC_DISPLAY_EXTERNAL) {
2327c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("hwc1Hotplug: Received hotplug for non-external display");
2328c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
2329c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2330c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2331fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2332c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2333c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // If the HWC2-side callback hasn't been registered yet, buffer this until
2334c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // it is registered
2335c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mCallbacks.count(Callback::Hotplug) == 0) {
2336c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mPendingHotplugs.emplace_back(hwc1DisplayId, connected);
2337c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
2338c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2339c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2340c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc2_display_t displayId = UINT64_MAX;
2341c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
2342c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (connected == 0) {
2343c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGW("hwc1Hotplug: Received disconnect for unconnected display");
2344c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return;
2345c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2346c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2347c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Create a new display on connect
2348c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto display = std::make_shared<HWC2On1Adapter::Display>(*this,
2349c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                HWC2::DisplayType::Physical);
2350c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        display->setHwc1Id(HWC_DISPLAY_EXTERNAL);
2351c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        display->populateConfigs();
2352c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        displayId = display->getId();
2353c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHwc1DisplayMap[HWC_DISPLAY_EXTERNAL] = displayId;
2354c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mDisplays.emplace(displayId, std::move(display));
2355c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
2356c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (connected != 0) {
2357c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGW("hwc1Hotplug: Received connect for previously connected "
2358c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    "display");
2359c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return;
2360c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2361c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2362c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Disconnect an existing display
2363c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        displayId = mHwc1DisplayMap[hwc1DisplayId];
2364c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHwc1DisplayMap.erase(HWC_DISPLAY_EXTERNAL);
2365c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mDisplays.erase(displayId);
2366c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2367c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2368c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto& callbackInfo = mCallbacks[Callback::Hotplug];
2369c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2370c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Call back without the state lock held
2371c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    lock.unlock();
2372c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2373c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(callbackInfo.pointer);
2374c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto hwc2Connected = (connected == 0) ?
2375c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            HWC2::Connection::Disconnected : HWC2::Connection::Connected;
2376c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hotplug(callbackInfo.data, displayId, static_cast<int32_t>(hwc2Connected));
2377c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2378c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2379c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza} // namespace android
2380