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