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