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
17e29055f5fe4a2bc0f3f75d952ff417462dc607ccFabien Sanglard#include "hwc2on1adapter/HWC2On1Adapter.h"
18e29055f5fe4a2bc0f3f75d952ff417462dc607ccFabien Sanglard
19c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza//#define LOG_NDEBUG 0
20c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
21c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza#undef LOG_TAG
22c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza#define LOG_TAG "HWC2On1Adapter"
23c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza#define ATRACE_TAG ATRACE_TAG_GRAPHICS
24c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
25c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
26a5e161b1207ef447a51e99856097d69d4a6111e1Mark Salyzyn#include <inttypes.h>
27c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
28c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza#include <chrono>
29a5e161b1207ef447a51e99856097d69d4a6111e1Mark Salyzyn#include <cstdlib>
30c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza#include <sstream>
31c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
32a5e161b1207ef447a51e99856097d69d4a6111e1Mark Salyzyn#include <hardware/hwcomposer.h>
337823e124e00576e20e47ec717cbe8bc89f0f2bf2Mark Salyzyn#include <log/log.h>
34a5e161b1207ef447a51e99856097d69d4a6111e1Mark Salyzyn#include <utils/Trace.h>
35a5e161b1207ef447a51e99856097d69d4a6111e1Mark Salyzyn
36c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozausing namespace std::chrono_literals;
37c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
38c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic uint8_t getMinorVersion(struct hwc_composer_device_1* device)
39c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
40c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto version = device->common.version & HARDWARE_API_VERSION_2_MAJ_MIN_MASK;
41c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return (version >> 16) & 0xF;
42c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
43c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
44c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozatemplate <typename PFN, typename T>
45c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic hwc2_function_pointer_t asFP(T function)
46c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
47c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
48c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return reinterpret_cast<hwc2_function_pointer_t>(function);
49c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
50c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
51c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozausing namespace HWC2;
52c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
5328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wrightstatic constexpr Attribute ColorMode = static_cast<Attribute>(6);
54076ac670262e448c531e6db7727cfade325866caDan Stoza
55c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozanamespace android {
56c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
57c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozaclass HWC2On1Adapter::Callbacks : public hwc_procs_t {
58c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    public:
59c406791ead6d864ec693ad01a80c5f471bdc2a7aChih-Hung Hsieh        explicit Callbacks(HWC2On1Adapter& adapter) : mAdapter(adapter) {
60c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            invalidate = &invalidateHook;
61c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            vsync = &vsyncHook;
62c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            hotplug = &hotplugHook;
63c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
64c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
65c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        static void invalidateHook(const hwc_procs_t* procs) {
66c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto callbacks = static_cast<const Callbacks*>(procs);
67c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            callbacks->mAdapter.hwc1Invalidate();
68c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
69c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
70c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        static void vsyncHook(const hwc_procs_t* procs, int display,
71c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                int64_t timestamp) {
72c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto callbacks = static_cast<const Callbacks*>(procs);
73c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            callbacks->mAdapter.hwc1Vsync(display, timestamp);
74c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
75c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
76c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        static void hotplugHook(const hwc_procs_t* procs, int display,
77c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                int connected) {
78c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto callbacks = static_cast<const Callbacks*>(procs);
79c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            callbacks->mAdapter.hwc1Hotplug(display, connected);
80c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
81c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
82c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    private:
83c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        HWC2On1Adapter& mAdapter;
84c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza};
85c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
86c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic int closeHook(hw_device_t* /*device*/)
87c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
88c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Do nothing, since the real work is done in the class destructor, but we
89c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // need to provide a valid function pointer for hwc2_close to call
90c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return 0;
91c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
92c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
93c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaHWC2On1Adapter::HWC2On1Adapter(hwc_composer_device_1_t* hwc1Device)
94c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza  : mDumpString(),
95c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1Device(hwc1Device),
96c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1MinorVersion(getMinorVersion(hwc1Device)),
97c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1SupportsVirtualDisplays(false),
98eb3db61f914a2469fe632c48b46a0ce60c84c9d9Fabien Sanglard    mHwc1SupportsBackgroundColor(false),
99c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1Callbacks(std::make_unique<Callbacks>(*this)),
100c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mCapabilities(),
101c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mLayers(),
102c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1VirtualDisplay(),
103c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mStateMutex(),
104c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mCallbacks(),
105c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHasPendingInvalidate(false),
106c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mPendingVsyncs(),
107c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mPendingHotplugs(),
108c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDisplays(),
109c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1DisplayMap()
110c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
111c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    common.close = closeHook;
112c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    getCapabilities = getCapabilitiesHook;
113c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    getFunction = getFunctionHook;
114c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    populateCapabilities();
115c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    populatePrimary();
116c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1Device->registerProcs(mHwc1Device,
117c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            static_cast<const hwc_procs_t*>(mHwc1Callbacks.get()));
118c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
119c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
120c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaHWC2On1Adapter::~HWC2On1Adapter() {
121c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc_close_1(mHwc1Device);
122c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
123c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
124c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::doGetCapabilities(uint32_t* outCount,
12506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        int32_t* outCapabilities) {
126c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (outCapabilities == nullptr) {
127c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        *outCount = mCapabilities.size();
128c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
129c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
130c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
131c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto capabilityIter = mCapabilities.cbegin();
132c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t written = 0; written < *outCount; ++written) {
133c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (capabilityIter == mCapabilities.cend()) {
134c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return;
135c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
136c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        outCapabilities[written] = static_cast<int32_t>(*capabilityIter);
137c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ++capabilityIter;
138c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
139c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
140c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
141c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozahwc2_function_pointer_t HWC2On1Adapter::doGetFunction(
14206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        FunctionDescriptor descriptor) {
143c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (descriptor) {
144c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Device functions
145c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::CreateVirtualDisplay:
146c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_CREATE_VIRTUAL_DISPLAY>(
147c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    createVirtualDisplayHook);
148c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::DestroyVirtualDisplay:
149c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_DESTROY_VIRTUAL_DISPLAY>(
150c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    destroyVirtualDisplayHook);
151c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::Dump:
152c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_DUMP>(dumpHook);
153c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetMaxVirtualDisplayCount:
154c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT>(
155c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    getMaxVirtualDisplayCountHook);
156c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::RegisterCallback:
157c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_REGISTER_CALLBACK>(registerCallbackHook);
158c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
159c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Display functions
160c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::AcceptDisplayChanges:
161c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_ACCEPT_DISPLAY_CHANGES>(
162c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::acceptChanges),
163c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::acceptChanges>);
164c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::CreateLayer:
165c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_CREATE_LAYER>(
166c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::createLayer),
167c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::createLayer, hwc2_layer_t*>);
168c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::DestroyLayer:
169c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_DESTROY_LAYER>(
170c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::destroyLayer),
171c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::destroyLayer, hwc2_layer_t>);
172c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetActiveConfig:
173c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_ACTIVE_CONFIG>(
174c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::getActiveConfig),
175c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::getActiveConfig, hwc2_config_t*>);
176c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetChangedCompositionTypes:
177c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES>(
178c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::getChangedCompositionTypes),
179c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::getChangedCompositionTypes, uint32_t*,
180c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    hwc2_layer_t*, int32_t*>);
181076ac670262e448c531e6db7727cfade325866caDan Stoza        case FunctionDescriptor::GetColorModes:
182076ac670262e448c531e6db7727cfade325866caDan Stoza            return asFP<HWC2_PFN_GET_COLOR_MODES>(
183076ac670262e448c531e6db7727cfade325866caDan Stoza                    displayHook<decltype(&Display::getColorModes),
184076ac670262e448c531e6db7727cfade325866caDan Stoza                    &Display::getColorModes, uint32_t*, int32_t*>);
185c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetDisplayAttribute:
186c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_DISPLAY_ATTRIBUTE>(
187c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    getDisplayAttributeHook);
188c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetDisplayConfigs:
189c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_DISPLAY_CONFIGS>(
190c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::getConfigs),
191c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::getConfigs, uint32_t*, hwc2_config_t*>);
192c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetDisplayName:
193c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_DISPLAY_NAME>(
194c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::getName),
195c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::getName, uint32_t*, char*>);
196c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetDisplayRequests:
197c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_DISPLAY_REQUESTS>(
198c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::getRequests),
199c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::getRequests, int32_t*, uint32_t*, hwc2_layer_t*,
200c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    int32_t*>);
201c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetDisplayType:
202c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_DISPLAY_TYPE>(
203c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::getType),
204c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::getType, int32_t*>);
205c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetDozeSupport:
206c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_DOZE_SUPPORT>(
207c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::getDozeSupport),
208c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::getDozeSupport, int32_t*>);
209ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza        case FunctionDescriptor::GetHdrCapabilities:
210ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza            return asFP<HWC2_PFN_GET_HDR_CAPABILITIES>(
211ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza                    displayHook<decltype(&Display::getHdrCapabilities),
212ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza                    &Display::getHdrCapabilities, uint32_t*, int32_t*, float*,
213ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza                    float*, float*>);
214c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::GetReleaseFences:
215c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_GET_RELEASE_FENCES>(
216c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::getReleaseFences),
217c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::getReleaseFences, uint32_t*, hwc2_layer_t*,
218c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    int32_t*>);
219c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::PresentDisplay:
220c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_PRESENT_DISPLAY>(
221c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::present),
222c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::present, int32_t*>);
223c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetActiveConfig:
224c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_ACTIVE_CONFIG>(
225c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::setActiveConfig),
226c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::setActiveConfig, hwc2_config_t>);
227c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetClientTarget:
228c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_CLIENT_TARGET>(
229c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::setClientTarget),
230c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::setClientTarget, buffer_handle_t, int32_t,
2315cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza                    int32_t, hwc_region_t>);
232076ac670262e448c531e6db7727cfade325866caDan Stoza        case FunctionDescriptor::SetColorMode:
23328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            return asFP<HWC2_PFN_SET_COLOR_MODE>(setColorModeHook);
2345df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza        case FunctionDescriptor::SetColorTransform:
2355df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza            return asFP<HWC2_PFN_SET_COLOR_TRANSFORM>(setColorTransformHook);
236c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetOutputBuffer:
237c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_OUTPUT_BUFFER>(
238c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::setOutputBuffer),
239c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::setOutputBuffer, buffer_handle_t, int32_t>);
240c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetPowerMode:
241c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_POWER_MODE>(setPowerModeHook);
242c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetVsyncEnabled:
243c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_VSYNC_ENABLED>(setVsyncEnabledHook);
244c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::ValidateDisplay:
245c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_VALIDATE_DISPLAY>(
246c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    displayHook<decltype(&Display::validate),
247c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Display::validate, uint32_t*, uint32_t*>);
2489e45be3fa0134b4865686be8b8b6a5752ff555a1Fabien Sanglard        case FunctionDescriptor::GetClientTargetSupport:
2499e45be3fa0134b4865686be8b8b6a5752ff555a1Fabien Sanglard            return asFP<HWC2_PFN_GET_CLIENT_TARGET_SUPPORT>(
2509e45be3fa0134b4865686be8b8b6a5752ff555a1Fabien Sanglard                    displayHook<decltype(&Display::getClientTargetSupport),
2519e45be3fa0134b4865686be8b8b6a5752ff555a1Fabien Sanglard                    &Display::getClientTargetSupport, uint32_t, uint32_t,
2529e45be3fa0134b4865686be8b8b6a5752ff555a1Fabien Sanglard                                                      int32_t, int32_t>);
253c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
254c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Layer functions
255c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetCursorPosition:
256c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_CURSOR_POSITION>(
257c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setCursorPosition),
258c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Layer::setCursorPosition, int32_t, int32_t>);
259c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerBuffer:
260c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_BUFFER>(
261c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setBuffer), &Layer::setBuffer,
262c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    buffer_handle_t, int32_t>);
263c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerSurfaceDamage:
264c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_SURFACE_DAMAGE>(
265c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setSurfaceDamage),
266c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Layer::setSurfaceDamage, hwc_region_t>);
267c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
268c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Layer state functions
269c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerBlendMode:
270c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_BLEND_MODE>(
271c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    setLayerBlendModeHook);
272c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerColor:
273c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_COLOR>(
274c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setColor), &Layer::setColor,
275c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    hwc_color_t>);
276c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerCompositionType:
277c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_COMPOSITION_TYPE>(
278c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    setLayerCompositionTypeHook);
2795df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza        case FunctionDescriptor::SetLayerDataspace:
2805df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza            return asFP<HWC2_PFN_SET_LAYER_DATASPACE>(setLayerDataspaceHook);
281c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerDisplayFrame:
282c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_DISPLAY_FRAME>(
283c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setDisplayFrame),
284c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Layer::setDisplayFrame, hwc_rect_t>);
285c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerPlaneAlpha:
286c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_PLANE_ALPHA>(
287c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setPlaneAlpha),
288c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Layer::setPlaneAlpha, float>);
289c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerSidebandStream:
290c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_SIDEBAND_STREAM>(
291c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setSidebandStream),
292c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Layer::setSidebandStream, const native_handle_t*>);
293c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerSourceCrop:
294c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_SOURCE_CROP>(
295c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setSourceCrop),
296c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Layer::setSourceCrop, hwc_frect_t>);
297c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerTransform:
298c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_TRANSFORM>(setLayerTransformHook);
299c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerVisibleRegion:
300c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_VISIBLE_REGION>(
301c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    layerHook<decltype(&Layer::setVisibleRegion),
302c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    &Layer::setVisibleRegion, hwc_region_t>);
303c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case FunctionDescriptor::SetLayerZOrder:
304c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return asFP<HWC2_PFN_SET_LAYER_Z_ORDER>(setLayerZOrderHook);
305c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
306c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        default:
307c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGE("doGetFunction: Unknown function descriptor: %d (%s)",
308c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    static_cast<int32_t>(descriptor),
309c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    to_string(descriptor).c_str());
310c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return nullptr;
311c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
312c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
313c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
314c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza// Device functions
315c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
316c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::createVirtualDisplay(uint32_t width,
31706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        uint32_t height, hwc2_display_t* outDisplay) {
318fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
319c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
320c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1VirtualDisplay) {
321c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // We have already allocated our only HWC1 virtual display
322c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("createVirtualDisplay: HWC1 virtual display already allocated");
323c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::NoResources;
324c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
325c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
326c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1VirtualDisplay = std::make_shared<HWC2On1Adapter::Display>(*this,
327c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            HWC2::DisplayType::Virtual);
328c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1VirtualDisplay->populateConfigs(width, height);
329c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto displayId = mHwc1VirtualDisplay->getId();
330c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1DisplayMap[HWC_DISPLAY_VIRTUAL] = displayId;
331c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1VirtualDisplay->setHwc1Id(HWC_DISPLAY_VIRTUAL);
332c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDisplays.emplace(displayId, mHwc1VirtualDisplay);
333c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outDisplay = displayId;
334c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
335c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
336c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
337c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
33806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::destroyVirtualDisplay(hwc2_display_t displayId) {
339fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
340c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
341c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!mHwc1VirtualDisplay || (mHwc1VirtualDisplay->getId() != displayId)) {
342c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadDisplay;
343c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
344c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
345c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1VirtualDisplay.reset();
346c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1DisplayMap.erase(HWC_DISPLAY_VIRTUAL);
347c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDisplays.erase(displayId);
348c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
349c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
350c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
351c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
35206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardvoid HWC2On1Adapter::dump(uint32_t* outSize, char* outBuffer) {
353c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (outBuffer != nullptr) {
354c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto copiedBytes = mDumpString.copy(outBuffer, *outSize);
355c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        *outSize = static_cast<uint32_t>(copiedBytes);
356c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
357c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
358c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
359c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::stringstream output;
360c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
361c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "-- HWC2On1Adapter --\n";
362c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
363c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "Adapting to a HWC 1." << static_cast<int>(mHwc1MinorVersion) <<
364c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            " device\n";
365c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
366c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Attempt to acquire the lock for 1 second, but proceed without the lock
367c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // after that, so we can still get some information if we're deadlocked
368fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex,
369fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza            std::defer_lock);
370c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    lock.try_lock_for(1s);
371c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
372c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mCapabilities.empty()) {
373c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "Capabilities: None\n";
374c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
375c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "Capabilities:\n";
376c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (auto capability : mCapabilities) {
377c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            output << "  " << to_string(capability) << '\n';
378c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
379c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
380c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
381c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "Displays:\n";
382c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (const auto& element : mDisplays) {
383c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        const auto& display = element.second;
384c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << display->dump();
385c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
386c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << '\n';
387c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
388fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    // Release the lock before calling into HWC1, and since we no longer require
389fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    // mutual exclusion to access mCapabilities or mDisplays
390fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    lock.unlock();
391fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza
392c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1Device->dump) {
393c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "HWC1 dump:\n";
394c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        std::vector<char> hwc1Dump(4096);
395c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Call with size - 1 to preserve a null character at the end
396c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHwc1Device->dump(mHwc1Device, hwc1Dump.data(),
397c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                static_cast<int>(hwc1Dump.size() - 1));
398c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << hwc1Dump.data();
399c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
400c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
401c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDumpString = output.str();
402c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outSize = static_cast<uint32_t>(mDumpString.size());
403c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
404c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
40506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglarduint32_t HWC2On1Adapter::getMaxVirtualDisplayCount() {
406c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return mHwc1SupportsVirtualDisplays ? 1 : 0;
407c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
408c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
409c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic bool isValid(Callback descriptor) {
410c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (descriptor) {
411c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case Callback::Hotplug: // Fall-through
412c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case Callback::Refresh: // Fall-through
413c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case Callback::Vsync: return true;
414c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        default: return false;
415c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
416c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
417c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
418c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::registerCallback(Callback descriptor,
41906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer) {
420c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!isValid(descriptor)) {
421c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadParameter;
422c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
423c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
424c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("registerCallback(%s, %p, %p)", to_string(descriptor).c_str(),
425c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            callbackData, pointer);
426c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
427fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
428c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
429c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mCallbacks[descriptor] = {callbackData, pointer};
430c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
431c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    bool hasPendingInvalidate = false;
432c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::vector<hwc2_display_t> displayIds;
433c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::vector<std::pair<hwc2_display_t, int64_t>> pendingVsyncs;
434c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::vector<std::pair<hwc2_display_t, int>> pendingHotplugs;
435c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
436c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (descriptor == Callback::Refresh) {
437c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hasPendingInvalidate = mHasPendingInvalidate;
438c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (hasPendingInvalidate) {
439c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            for (auto& displayPair : mDisplays) {
440c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                displayIds.emplace_back(displayPair.first);
441c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
442c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
443c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHasPendingInvalidate = false;
444c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else if (descriptor == Callback::Vsync) {
445c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (auto pending : mPendingVsyncs) {
446c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto hwc1DisplayId = pending.first;
447c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
448c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                ALOGE("hwc1Vsync: Couldn't find display for HWC1 id %d",
449c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                        hwc1DisplayId);
450c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                continue;
451c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
452c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto displayId = mHwc1DisplayMap[hwc1DisplayId];
453c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto timestamp = pending.second;
454c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            pendingVsyncs.emplace_back(displayId, timestamp);
455c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
456c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mPendingVsyncs.clear();
457c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else if (descriptor == Callback::Hotplug) {
458c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Hotplug the primary display
459c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        pendingHotplugs.emplace_back(mHwc1DisplayMap[HWC_DISPLAY_PRIMARY],
460c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                static_cast<int32_t>(Connection::Connected));
461c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
462c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (auto pending : mPendingHotplugs) {
463c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto hwc1DisplayId = pending.first;
464c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
465c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                ALOGE("hwc1Hotplug: Couldn't find display for HWC1 id %d",
466c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                        hwc1DisplayId);
467c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                continue;
468c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
469c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto displayId = mHwc1DisplayMap[hwc1DisplayId];
470c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto connected = pending.second;
471c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            pendingHotplugs.emplace_back(displayId, connected);
472c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
473c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
474c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
475c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Call pending callbacks without the state lock held
476c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    lock.unlock();
477c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
478c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (hasPendingInvalidate) {
479c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto refresh = reinterpret_cast<HWC2_PFN_REFRESH>(pointer);
480c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (auto displayId : displayIds) {
481c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            refresh(callbackData, displayId);
482c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
483c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
484c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!pendingVsyncs.empty()) {
485c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto vsync = reinterpret_cast<HWC2_PFN_VSYNC>(pointer);
486c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (auto& pendingVsync : pendingVsyncs) {
487c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            vsync(callbackData, pendingVsync.first, pendingVsync.second);
488c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
489c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
490c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!pendingHotplugs.empty()) {
491c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(pointer);
492c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (auto& pendingHotplug : pendingHotplugs) {
493c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            hotplug(callbackData, pendingHotplug.first, pendingHotplug.second);
494c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
495c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
496c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
497c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
498c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
499c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza// Display functions
500c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
501c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastd::atomic<hwc2_display_t> HWC2On1Adapter::Display::sNextId(1);
502c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
503c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaHWC2On1Adapter::Display::Display(HWC2On1Adapter& device, HWC2::DisplayType type)
504c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza  : mId(sNextId++),
505c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDevice(device),
506c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mStateMutex(),
507c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1RequestedContents(nullptr),
508c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mRetireFence(),
509c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mChanges(),
510c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1Id(-1),
511c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mConfigs(),
512c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mActiveConfig(nullptr),
513c75ca51da3b41618c9633ca66f06b05daa98f276Michael Wright    mActiveColorMode(static_cast<android_color_mode_t>(-1)),
514c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mName(),
515c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mType(type),
516c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mPowerMode(PowerMode::Off),
517c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mVsyncEnabled(Vsync::Invalid),
518c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mClientTarget(),
519c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mOutputBuffer(),
5205df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    mHasColorTransform(false),
521fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    mLayers(),
52206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mHwc1LayerMap(),
52306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mNumAvailableRects(0),
52406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mNextAvailableRect(nullptr),
52506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mGeometryChanged(false)
52606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    {}
527c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
52806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Display::acceptChanges() {
529c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
530c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
531c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!mChanges) {
532c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("[%" PRIu64 "] acceptChanges failed, not validated", mId);
533c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::NotValidated;
534c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
535c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
536c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] acceptChanges", mId);
537c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
538c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (auto& change : mChanges->getTypeChanges()) {
539c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto layerId = change.first;
540c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto type = change.second;
54106d5e3590eb23144dd9de567663633160ba39302Fabien Sanglard        if (mDevice.mLayers.count(layerId) == 0) {
54206d5e3590eb23144dd9de567663633160ba39302Fabien Sanglard            // This should never happen but somehow does.
54306d5e3590eb23144dd9de567663633160ba39302Fabien Sanglard            ALOGW("Cannot accept change for unknown layer (%" PRIu64 ")",
54406d5e3590eb23144dd9de567663633160ba39302Fabien Sanglard                  layerId);
54506d5e3590eb23144dd9de567663633160ba39302Fabien Sanglard            continue;
54606d5e3590eb23144dd9de567663633160ba39302Fabien Sanglard        }
547c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto layer = mDevice.mLayers[layerId];
548c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        layer->setCompositionType(type);
549c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
550c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
551c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mChanges->clearTypeChanges();
552c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
553c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
554c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
555c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
55606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Display::createLayer(hwc2_layer_t* outLayerId) {
557c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
558c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
559c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto layer = *mLayers.emplace(std::make_shared<Layer>(*this));
560c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDevice.mLayers.emplace(std::make_pair(layer->getId(), layer));
561c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outLayerId = layer->getId();
562c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] created layer %" PRIu64, mId, *outLayerId);
56306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    markGeometryChanged();
564c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
565c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
566c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
56706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Display::destroyLayer(hwc2_layer_t layerId) {
568c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
569c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
570c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto mapLayer = mDevice.mLayers.find(layerId);
571c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mapLayer == mDevice.mLayers.end()) {
572c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("[%" PRIu64 "] destroyLayer(%" PRIu64 ") failed: no such layer",
573c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mId, layerId);
574c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadLayer;
575c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
576c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto layer = mapLayer->second;
577c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDevice.mLayers.erase(mapLayer);
578c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto zRange = mLayers.equal_range(layer);
579c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (auto current = zRange.first; current != zRange.second; ++current) {
580c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (**current == *layer) {
581c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            current = mLayers.erase(current);
582c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
583c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
584c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
585c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] destroyed layer %" PRIu64, mId, layerId);
58606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    markGeometryChanged();
587c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
588c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
589c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
59006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Display::getActiveConfig(hwc2_config_t* outConfig) {
591c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
592c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
593c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!mActiveConfig) {
594c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("[%" PRIu64 "] getActiveConfig --> %s", mId,
595c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                to_string(Error::BadConfig).c_str());
596c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadConfig;
597c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
598c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto configId = mActiveConfig->getId();
599c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] getActiveConfig --> %u", mId, configId);
600c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outConfig = configId;
601c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
602c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
603c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
604c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::getAttribute(hwc2_config_t configId,
60506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        Attribute attribute, int32_t* outValue) {
606c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
607c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
608c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (configId > mConfigs.size() || !mConfigs[configId]->isOnDisplay(*this)) {
609c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("[%" PRIu64 "] getAttribute failed: bad config (%u)", mId,
610c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                configId);
611c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadConfig;
612c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
613c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outValue = mConfigs[configId]->getAttribute(attribute);
614c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] getAttribute(%u, %s) --> %d", mId, configId,
615c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            to_string(attribute).c_str(), *outValue);
616c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
617c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
618c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
619c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::getChangedCompositionTypes(
62006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        uint32_t* outNumElements, hwc2_layer_t* outLayers, int32_t* outTypes) {
621c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
622c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
623c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!mChanges) {
624c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("[%" PRIu64 "] getChangedCompositionTypes failed: not validated",
625c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mId);
626c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::NotValidated;
627c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
628c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
629c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if ((outLayers == nullptr) || (outTypes == nullptr)) {
630c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        *outNumElements = mChanges->getTypeChanges().size();
631c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::None;
632c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
633c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
634c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    uint32_t numWritten = 0;
635c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (const auto& element : mChanges->getTypeChanges()) {
636c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (numWritten == *outNumElements) {
637c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
638c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
639c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto layerId = element.first;
640c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto intType = static_cast<int32_t>(element.second);
641c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("Adding %" PRIu64 " %s", layerId,
642c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                to_string(element.second).c_str());
643c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        outLayers[numWritten] = layerId;
644c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        outTypes[numWritten] = intType;
645c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ++numWritten;
646c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
647c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outNumElements = numWritten;
648c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
649c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
650c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
651c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
652076ac670262e448c531e6db7727cfade325866caDan StozaError HWC2On1Adapter::Display::getColorModes(uint32_t* outNumModes,
65306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        int32_t* outModes) {
654076ac670262e448c531e6db7727cfade325866caDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
655076ac670262e448c531e6db7727cfade325866caDan Stoza
656076ac670262e448c531e6db7727cfade325866caDan Stoza    if (!outModes) {
657076ac670262e448c531e6db7727cfade325866caDan Stoza        *outNumModes = mColorModes.size();
658076ac670262e448c531e6db7727cfade325866caDan Stoza        return Error::None;
659076ac670262e448c531e6db7727cfade325866caDan Stoza    }
660076ac670262e448c531e6db7727cfade325866caDan Stoza    uint32_t numModes = std::min(*outNumModes,
661076ac670262e448c531e6db7727cfade325866caDan Stoza            static_cast<uint32_t>(mColorModes.size()));
662076ac670262e448c531e6db7727cfade325866caDan Stoza    std::copy_n(mColorModes.cbegin(), numModes, outModes);
663076ac670262e448c531e6db7727cfade325866caDan Stoza    *outNumModes = numModes;
664076ac670262e448c531e6db7727cfade325866caDan Stoza    return Error::None;
665076ac670262e448c531e6db7727cfade325866caDan Stoza}
666076ac670262e448c531e6db7727cfade325866caDan Stoza
667c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::getConfigs(uint32_t* outNumConfigs,
66806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        hwc2_config_t* outConfigs) {
669c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
670c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
671c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!outConfigs) {
672c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        *outNumConfigs = mConfigs.size();
673c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::None;
674c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
675c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    uint32_t numWritten = 0;
676c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (const auto& config : mConfigs) {
677c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (numWritten == *outNumConfigs) {
678c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
679c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
680c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        outConfigs[numWritten] = config->getId();
681c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ++numWritten;
682c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
683c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outNumConfigs = numWritten;
684c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
685c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
686c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
68706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Display::getDozeSupport(int32_t* outSupport) {
688c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
689c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
690c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mDevice.mHwc1MinorVersion < 4 || mHwc1Id != 0) {
691c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        *outSupport = 0;
692c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
693c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        *outSupport = 1;
694c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
695c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
696c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
697c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
698ed40eba4c1264806a1b795bf45b0dea366ee9975Dan StozaError HWC2On1Adapter::Display::getHdrCapabilities(uint32_t* outNumTypes,
699ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza        int32_t* /*outTypes*/, float* /*outMaxLuminance*/,
70006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        float* /*outMaxAverageLuminance*/, float* /*outMinLuminance*/) {
701ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza    // This isn't supported on HWC1, so per the HWC2 header, return numTypes = 0
702ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza    *outNumTypes = 0;
703ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza    return Error::None;
704ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza}
705ed40eba4c1264806a1b795bf45b0dea366ee9975Dan Stoza
70606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Display::getName(uint32_t* outSize, char* outName) {
707c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
708c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
709c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!outName) {
710c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        *outSize = mName.size();
711c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::None;
712c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
713c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto numCopied = mName.copy(outName, *outSize);
714c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outSize = numCopied;
715c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
716c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
717c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
718c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::getReleaseFences(uint32_t* outNumElements,
71906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        hwc2_layer_t* outLayers, int32_t* outFences) {
720c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
721c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
722c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    uint32_t numWritten = 0;
723c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    bool outputsNonNull = (outLayers != nullptr) && (outFences != nullptr);
724c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (const auto& layer : mLayers) {
725c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (outputsNonNull && (numWritten == *outNumElements)) {
726c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
727c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
728c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
729c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto releaseFence = layer->getReleaseFence();
730c859147db5e9d5aa8a5043c0111e2799e1db042bFabien Sanglard        if (releaseFence != MiniFence::NO_FENCE) {
731c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            if (outputsNonNull) {
732c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                outLayers[numWritten] = layer->getId();
733c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                outFences[numWritten] = releaseFence->dup();
734c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
735c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ++numWritten;
736c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
737c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
738c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outNumElements = numWritten;
739c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
740c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
741c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
742c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
743c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::getRequests(int32_t* outDisplayRequests,
744c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        uint32_t* outNumElements, hwc2_layer_t* outLayers,
74506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        int32_t* outLayerRequests) {
746c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
747c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
748c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!mChanges) {
749c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::NotValidated;
750c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
751c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
752c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (outLayers == nullptr || outLayerRequests == nullptr) {
753c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        *outNumElements = mChanges->getNumLayerRequests();
754c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::None;
755c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
756c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
757601938c35aa5162ac669004aff8c44d8c25345f0Fabien Sanglard    // Display requests (HWC2::DisplayRequest) are not supported by hwc1:
758601938c35aa5162ac669004aff8c44d8c25345f0Fabien Sanglard    // A hwc1 has always zero requests for the client.
759601938c35aa5162ac669004aff8c44d8c25345f0Fabien Sanglard    *outDisplayRequests = 0;
760601938c35aa5162ac669004aff8c44d8c25345f0Fabien Sanglard
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
77406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Display::getType(int32_t* outType) {
775c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
776c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
777c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outType = static_cast<int32_t>(mType);
778c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
779c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
780c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
78106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Display::present(int32_t* outRetireFence) {
782c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
783c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
784c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mChanges) {
785c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        Error error = mDevice.setAllDisplays();
786c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (error != Error::None) {
787c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGE("[%" PRIu64 "] present: setAllDisplaysFailed (%s)", mId,
788c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    to_string(error).c_str());
789c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return error;
790c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
791c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
792c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
793c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outRetireFence = mRetireFence.get()->dup();
794c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] present returning retire fence %d", mId,
795c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            *outRetireFence);
796c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
797c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
798c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
799c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
80006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Display::setActiveConfig(hwc2_config_t configId) {
801c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
802c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
803c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto config = getConfig(configId);
804c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!config) {
805c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadConfig;
806c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
807076ac670262e448c531e6db7727cfade325866caDan Stoza    if (config == mActiveConfig) {
808076ac670262e448c531e6db7727cfade325866caDan Stoza        return Error::None;
809076ac670262e448c531e6db7727cfade325866caDan Stoza    }
810076ac670262e448c531e6db7727cfade325866caDan Stoza
811c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mDevice.mHwc1MinorVersion >= 4) {
812076ac670262e448c531e6db7727cfade325866caDan Stoza        uint32_t hwc1Id = 0;
813076ac670262e448c531e6db7727cfade325866caDan Stoza        auto error = config->getHwc1IdForColorMode(mActiveColorMode, &hwc1Id);
814076ac670262e448c531e6db7727cfade325866caDan Stoza        if (error != Error::None) {
815076ac670262e448c531e6db7727cfade325866caDan Stoza            return error;
816076ac670262e448c531e6db7727cfade325866caDan Stoza        }
817076ac670262e448c531e6db7727cfade325866caDan Stoza
818076ac670262e448c531e6db7727cfade325866caDan Stoza        int intError = mDevice.mHwc1Device->setActiveConfig(mDevice.mHwc1Device,
819076ac670262e448c531e6db7727cfade325866caDan Stoza                mHwc1Id, static_cast<int>(hwc1Id));
820076ac670262e448c531e6db7727cfade325866caDan Stoza        if (intError != 0) {
821076ac670262e448c531e6db7727cfade325866caDan Stoza            ALOGE("setActiveConfig: Failed to set active config on HWC1 (%d)",
822076ac670262e448c531e6db7727cfade325866caDan Stoza                intError);
823076ac670262e448c531e6db7727cfade325866caDan Stoza            return Error::BadConfig;
824076ac670262e448c531e6db7727cfade325866caDan Stoza        }
825076ac670262e448c531e6db7727cfade325866caDan Stoza        mActiveConfig = config;
826c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
827076ac670262e448c531e6db7727cfade325866caDan Stoza
828c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
829c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
830c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
831c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::setClientTarget(buffer_handle_t target,
83206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        int32_t acquireFence, int32_t /*dataspace*/, hwc_region_t /*damage*/) {
833c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
834c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
835c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] setClientTarget(%p, %d)", mId, target, acquireFence);
836c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mClientTarget.setBuffer(target);
837c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mClientTarget.setFence(acquireFence);
8385cf424bc129f01ee12c7a4fbea1664276d29f970Dan Stoza    // dataspace and damage can't be used by HWC1, so ignore them
839c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
840c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
841c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
84206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Display::setColorMode(android_color_mode_t mode) {
843076ac670262e448c531e6db7727cfade325866caDan Stoza    std::unique_lock<std::recursive_mutex> lock (mStateMutex);
844076ac670262e448c531e6db7727cfade325866caDan Stoza
845076ac670262e448c531e6db7727cfade325866caDan Stoza    ALOGV("[%" PRIu64 "] setColorMode(%d)", mId, mode);
846076ac670262e448c531e6db7727cfade325866caDan Stoza
847076ac670262e448c531e6db7727cfade325866caDan Stoza    if (mode == mActiveColorMode) {
848076ac670262e448c531e6db7727cfade325866caDan Stoza        return Error::None;
849076ac670262e448c531e6db7727cfade325866caDan Stoza    }
850076ac670262e448c531e6db7727cfade325866caDan Stoza    if (mColorModes.count(mode) == 0) {
851076ac670262e448c531e6db7727cfade325866caDan Stoza        ALOGE("[%" PRIu64 "] Mode %d not found in mColorModes", mId, mode);
852076ac670262e448c531e6db7727cfade325866caDan Stoza        return Error::Unsupported;
853076ac670262e448c531e6db7727cfade325866caDan Stoza    }
854076ac670262e448c531e6db7727cfade325866caDan Stoza
855076ac670262e448c531e6db7727cfade325866caDan Stoza    uint32_t hwc1Config = 0;
856076ac670262e448c531e6db7727cfade325866caDan Stoza    auto error = mActiveConfig->getHwc1IdForColorMode(mode, &hwc1Config);
857076ac670262e448c531e6db7727cfade325866caDan Stoza    if (error != Error::None) {
858076ac670262e448c531e6db7727cfade325866caDan Stoza        return error;
859076ac670262e448c531e6db7727cfade325866caDan Stoza    }
860076ac670262e448c531e6db7727cfade325866caDan Stoza
861076ac670262e448c531e6db7727cfade325866caDan Stoza    ALOGV("[%" PRIu64 "] Setting HWC1 config %u", mId, hwc1Config);
862076ac670262e448c531e6db7727cfade325866caDan Stoza    int intError = mDevice.mHwc1Device->setActiveConfig(mDevice.mHwc1Device,
863076ac670262e448c531e6db7727cfade325866caDan Stoza            mHwc1Id, hwc1Config);
864076ac670262e448c531e6db7727cfade325866caDan Stoza    if (intError != 0) {
865076ac670262e448c531e6db7727cfade325866caDan Stoza        ALOGE("[%" PRIu64 "] Failed to set HWC1 config (%d)", mId, intError);
866076ac670262e448c531e6db7727cfade325866caDan Stoza        return Error::Unsupported;
867076ac670262e448c531e6db7727cfade325866caDan Stoza    }
868076ac670262e448c531e6db7727cfade325866caDan Stoza
869076ac670262e448c531e6db7727cfade325866caDan Stoza    mActiveColorMode = mode;
870076ac670262e448c531e6db7727cfade325866caDan Stoza    return Error::None;
871076ac670262e448c531e6db7727cfade325866caDan Stoza}
872076ac670262e448c531e6db7727cfade325866caDan Stoza
87306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Display::setColorTransform(android_color_transform_t hint) {
8745df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
8755df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza
8765df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    ALOGV("%" PRIu64 "] setColorTransform(%d)", mId,
8775df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza            static_cast<int32_t>(hint));
8785df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    mHasColorTransform = (hint != HAL_COLOR_TRANSFORM_IDENTITY);
8795df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    return Error::None;
8805df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza}
8815df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza
882c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::setOutputBuffer(buffer_handle_t buffer,
88306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        int32_t releaseFence) {
884c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
885c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
886c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] setOutputBuffer(%p, %d)", mId, buffer, releaseFence);
887c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mOutputBuffer.setBuffer(buffer);
888c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mOutputBuffer.setFence(releaseFence);
889c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
890c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
891c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
89206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardstatic bool isValid(PowerMode mode) {
893c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (mode) {
894c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case PowerMode::Off: // Fall-through
895c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case PowerMode::DozeSuspend: // Fall-through
896c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case PowerMode::Doze: // Fall-through
897c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case PowerMode::On: return true;
898c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
899c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
900c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
90106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardstatic int getHwc1PowerMode(PowerMode mode) {
902c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (mode) {
903c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case PowerMode::Off: return HWC_POWER_MODE_OFF;
904c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case PowerMode::DozeSuspend: return HWC_POWER_MODE_DOZE_SUSPEND;
905c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case PowerMode::Doze: return HWC_POWER_MODE_DOZE;
906c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case PowerMode::On: return HWC_POWER_MODE_NORMAL;
907c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
908c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
909c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
91006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Display::setPowerMode(PowerMode mode) {
911c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!isValid(mode)) {
912c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadParameter;
913c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
914c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mode == mPowerMode) {
915c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::None;
916c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
917c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
918c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
919c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
920c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    int error = 0;
921c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mDevice.mHwc1MinorVersion < 4) {
922c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        error = mDevice.mHwc1Device->blank(mDevice.mHwc1Device, mHwc1Id,
923c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mode == PowerMode::Off);
924c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
925c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        error = mDevice.mHwc1Device->setPowerMode(mDevice.mHwc1Device,
926c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mHwc1Id, getHwc1PowerMode(mode));
927c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
928c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGE_IF(error != 0, "setPowerMode: Failed to set power mode on HWC1 (%d)",
929c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            error);
930c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
931c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] setPowerMode(%s)", mId, to_string(mode).c_str());
932c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mPowerMode = mode;
933c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
934c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
935c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
936c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic bool isValid(Vsync enable) {
937c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (enable) {
938c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case Vsync::Enable: // Fall-through
939c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case Vsync::Disable: return true;
94006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        case Vsync::Invalid: return false;
941c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
942c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
943c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
94406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Display::setVsyncEnabled(Vsync enable) {
945c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!isValid(enable)) {
946c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadParameter;
947c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
948c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (enable == mVsyncEnabled) {
949c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::None;
950c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
951c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
952c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
953c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
954c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    int error = mDevice.mHwc1Device->eventControl(mDevice.mHwc1Device,
955c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            mHwc1Id, HWC_EVENT_VSYNC, enable == Vsync::Enable);
956c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGE_IF(error != 0, "setVsyncEnabled: Failed to set vsync on HWC1 (%d)",
957c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            error);
958c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
959c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mVsyncEnabled = enable;
960c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
961c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
962c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
963c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Display::validate(uint32_t* outNumTypes,
96406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        uint32_t* outNumRequests) {
965c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
966c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
967c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!mChanges) {
968c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (!mDevice.prepareAllDisplays()) {
969c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return Error::BadDisplay;
970c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
97106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    } else {
97206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        ALOGE("Validate was called more than once!");
973c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
974c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
975c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outNumTypes = mChanges->getNumTypes();
976c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    *outNumRequests = mChanges->getNumLayerRequests();
977c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] validate --> %u types, %u requests", mId, *outNumTypes,
978c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            *outNumRequests);
979c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (auto request : mChanges->getTypeChanges()) {
980c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("Layer %" PRIu64 " --> %s", request.first,
981c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                to_string(request.second).c_str());
982c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
983c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return *outNumTypes > 0 ? Error::HasChanges : Error::None;
984c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
985c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
98606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Display::updateLayerZ(hwc2_layer_t layerId, uint32_t z) {
987c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
988c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
989c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto mapLayer = mDevice.mLayers.find(layerId);
990c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mapLayer == mDevice.mLayers.end()) {
991c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("[%" PRIu64 "] updateLayerZ failed to find layer", mId);
992c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadLayer;
993c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
994c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
995c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto layer = mapLayer->second;
996c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto zRange = mLayers.equal_range(layer);
997c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    bool layerOnDisplay = false;
998c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (auto current = zRange.first; current != zRange.second; ++current) {
999c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (**current == *layer) {
1000c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            if ((*current)->getZ() == z) {
1001c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                // Don't change anything if the Z hasn't changed
1002c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                return Error::None;
1003c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
1004c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            current = mLayers.erase(current);
1005c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            layerOnDisplay = true;
1006c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
1007c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1008c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1009c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1010c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!layerOnDisplay) {
1011c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("[%" PRIu64 "] updateLayerZ failed to find layer on display",
1012c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mId);
1013c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadLayer;
1014c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1015c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1016c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    layer->setZ(z);
1017c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mLayers.emplace(std::move(layer));
101806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    markGeometryChanged();
1019c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1020c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1021c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1022c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
10239e45be3fa0134b4865686be8b8b6a5752ff555a1Fabien SanglardError HWC2On1Adapter::Display::getClientTargetSupport(uint32_t width, uint32_t height,
10249e45be3fa0134b4865686be8b8b6a5752ff555a1Fabien Sanglard                                      int32_t format, int32_t dataspace){
10259e45be3fa0134b4865686be8b8b6a5752ff555a1Fabien Sanglard    if (mActiveConfig == nullptr) {
10269e45be3fa0134b4865686be8b8b6a5752ff555a1Fabien Sanglard        return Error::Unsupported;
10279e45be3fa0134b4865686be8b8b6a5752ff555a1Fabien Sanglard    }
10289e45be3fa0134b4865686be8b8b6a5752ff555a1Fabien Sanglard
10299e45be3fa0134b4865686be8b8b6a5752ff555a1Fabien Sanglard    if (width == mActiveConfig->getAttribute(Attribute::Width) &&
10309e45be3fa0134b4865686be8b8b6a5752ff555a1Fabien Sanglard            height == mActiveConfig->getAttribute(Attribute::Height) &&
10319e45be3fa0134b4865686be8b8b6a5752ff555a1Fabien Sanglard            format == HAL_PIXEL_FORMAT_RGBA_8888 &&
10329e45be3fa0134b4865686be8b8b6a5752ff555a1Fabien Sanglard            dataspace == HAL_DATASPACE_UNKNOWN) {
10339e45be3fa0134b4865686be8b8b6a5752ff555a1Fabien Sanglard        return Error::None;
10349e45be3fa0134b4865686be8b8b6a5752ff555a1Fabien Sanglard    }
10359e45be3fa0134b4865686be8b8b6a5752ff555a1Fabien Sanglard
10369e45be3fa0134b4865686be8b8b6a5752ff555a1Fabien Sanglard    return Error::Unsupported;
10379e45be3fa0134b4865686be8b8b6a5752ff555a1Fabien Sanglard}
10389e45be3fa0134b4865686be8b8b6a5752ff555a1Fabien Sanglard
1039076ac670262e448c531e6db7727cfade325866caDan Stozastatic constexpr uint32_t ATTRIBUTES_WITH_COLOR[] = {
1040c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    HWC_DISPLAY_VSYNC_PERIOD,
1041c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    HWC_DISPLAY_WIDTH,
1042c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    HWC_DISPLAY_HEIGHT,
1043c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    HWC_DISPLAY_DPI_X,
1044c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    HWC_DISPLAY_DPI_Y,
1045076ac670262e448c531e6db7727cfade325866caDan Stoza    HWC_DISPLAY_COLOR_TRANSFORM,
1046c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    HWC_DISPLAY_NO_ATTRIBUTE,
1047c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza};
1048c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1049076ac670262e448c531e6db7727cfade325866caDan Stozastatic constexpr uint32_t ATTRIBUTES_WITHOUT_COLOR[] = {
1050076ac670262e448c531e6db7727cfade325866caDan Stoza    HWC_DISPLAY_VSYNC_PERIOD,
1051076ac670262e448c531e6db7727cfade325866caDan Stoza    HWC_DISPLAY_WIDTH,
1052076ac670262e448c531e6db7727cfade325866caDan Stoza    HWC_DISPLAY_HEIGHT,
1053076ac670262e448c531e6db7727cfade325866caDan Stoza    HWC_DISPLAY_DPI_X,
1054076ac670262e448c531e6db7727cfade325866caDan Stoza    HWC_DISPLAY_DPI_Y,
1055076ac670262e448c531e6db7727cfade325866caDan Stoza    HWC_DISPLAY_NO_ATTRIBUTE,
1056076ac670262e448c531e6db7727cfade325866caDan Stoza};
1057076ac670262e448c531e6db7727cfade325866caDan Stoza
1058076ac670262e448c531e6db7727cfade325866caDan Stozastatic constexpr size_t NUM_ATTRIBUTES_WITH_COLOR =
1059076ac670262e448c531e6db7727cfade325866caDan Stoza        sizeof(ATTRIBUTES_WITH_COLOR) / sizeof(uint32_t);
1060076ac670262e448c531e6db7727cfade325866caDan Stozastatic_assert(sizeof(ATTRIBUTES_WITH_COLOR) > sizeof(ATTRIBUTES_WITHOUT_COLOR),
1061076ac670262e448c531e6db7727cfade325866caDan Stoza        "Attribute tables have unexpected sizes");
1062076ac670262e448c531e6db7727cfade325866caDan Stoza
1063076ac670262e448c531e6db7727cfade325866caDan Stozastatic constexpr uint32_t ATTRIBUTE_MAP_WITH_COLOR[] = {
1064076ac670262e448c531e6db7727cfade325866caDan Stoza    6, // HWC_DISPLAY_NO_ATTRIBUTE = 0
1065076ac670262e448c531e6db7727cfade325866caDan Stoza    0, // HWC_DISPLAY_VSYNC_PERIOD = 1,
1066076ac670262e448c531e6db7727cfade325866caDan Stoza    1, // HWC_DISPLAY_WIDTH = 2,
1067076ac670262e448c531e6db7727cfade325866caDan Stoza    2, // HWC_DISPLAY_HEIGHT = 3,
1068076ac670262e448c531e6db7727cfade325866caDan Stoza    3, // HWC_DISPLAY_DPI_X = 4,
1069076ac670262e448c531e6db7727cfade325866caDan Stoza    4, // HWC_DISPLAY_DPI_Y = 5,
1070076ac670262e448c531e6db7727cfade325866caDan Stoza    5, // HWC_DISPLAY_COLOR_TRANSFORM = 6,
1071076ac670262e448c531e6db7727cfade325866caDan Stoza};
1072076ac670262e448c531e6db7727cfade325866caDan Stoza
1073076ac670262e448c531e6db7727cfade325866caDan Stozastatic constexpr uint32_t ATTRIBUTE_MAP_WITHOUT_COLOR[] = {
1074c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    5, // HWC_DISPLAY_NO_ATTRIBUTE = 0
1075c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    0, // HWC_DISPLAY_VSYNC_PERIOD = 1,
1076c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    1, // HWC_DISPLAY_WIDTH = 2,
1077c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    2, // HWC_DISPLAY_HEIGHT = 3,
1078c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    3, // HWC_DISPLAY_DPI_X = 4,
1079c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    4, // HWC_DISPLAY_DPI_Y = 5,
1080c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza};
1081c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1082c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozatemplate <uint32_t attribute>
1083c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic constexpr bool attributesMatch()
1084c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza{
1085076ac670262e448c531e6db7727cfade325866caDan Stoza    bool match = (attribute ==
1086076ac670262e448c531e6db7727cfade325866caDan Stoza            ATTRIBUTES_WITH_COLOR[ATTRIBUTE_MAP_WITH_COLOR[attribute]]);
1087076ac670262e448c531e6db7727cfade325866caDan Stoza    if (attribute == HWC_DISPLAY_COLOR_TRANSFORM) {
1088076ac670262e448c531e6db7727cfade325866caDan Stoza        return match;
1089076ac670262e448c531e6db7727cfade325866caDan Stoza    }
1090076ac670262e448c531e6db7727cfade325866caDan Stoza
1091076ac670262e448c531e6db7727cfade325866caDan Stoza    return match && (attribute ==
1092076ac670262e448c531e6db7727cfade325866caDan Stoza            ATTRIBUTES_WITHOUT_COLOR[ATTRIBUTE_MAP_WITHOUT_COLOR[attribute]]);
1093c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1094c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic_assert(attributesMatch<HWC_DISPLAY_VSYNC_PERIOD>(),
1095c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        "Tables out of sync");
1096c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic_assert(attributesMatch<HWC_DISPLAY_WIDTH>(), "Tables out of sync");
1097c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic_assert(attributesMatch<HWC_DISPLAY_HEIGHT>(), "Tables out of sync");
1098c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic_assert(attributesMatch<HWC_DISPLAY_DPI_X>(), "Tables out of sync");
1099c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic_assert(attributesMatch<HWC_DISPLAY_DPI_Y>(), "Tables out of sync");
1100076ac670262e448c531e6db7727cfade325866caDan Stozastatic_assert(attributesMatch<HWC_DISPLAY_COLOR_TRANSFORM>(),
1101076ac670262e448c531e6db7727cfade325866caDan Stoza        "Tables out of sync");
1102c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
110306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardvoid HWC2On1Adapter::Display::populateConfigs() {
1104c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1105c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1106c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("[%" PRIu64 "] populateConfigs", mId);
1107c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1108c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1Id == -1) {
1109c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("populateConfigs: HWC1 ID not set");
1110c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
1111c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1112c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1113c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const size_t MAX_NUM_CONFIGS = 128;
1114c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    uint32_t configs[MAX_NUM_CONFIGS] = {};
1115c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    size_t numConfigs = MAX_NUM_CONFIGS;
1116c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDevice.mHwc1Device->getDisplayConfigs(mDevice.mHwc1Device, mHwc1Id,
1117c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            configs, &numConfigs);
1118c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1119c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t c = 0; c < numConfigs; ++c) {
1120c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        uint32_t hwc1ConfigId = configs[c];
1121076ac670262e448c531e6db7727cfade325866caDan Stoza        auto newConfig = std::make_shared<Config>(*this);
1122076ac670262e448c531e6db7727cfade325866caDan Stoza
1123076ac670262e448c531e6db7727cfade325866caDan Stoza        int32_t values[NUM_ATTRIBUTES_WITH_COLOR] = {};
1124076ac670262e448c531e6db7727cfade325866caDan Stoza        bool hasColor = true;
1125076ac670262e448c531e6db7727cfade325866caDan Stoza        auto result = mDevice.mHwc1Device->getDisplayAttributes(
1126076ac670262e448c531e6db7727cfade325866caDan Stoza                mDevice.mHwc1Device, mHwc1Id, hwc1ConfigId,
1127076ac670262e448c531e6db7727cfade325866caDan Stoza                ATTRIBUTES_WITH_COLOR, values);
1128076ac670262e448c531e6db7727cfade325866caDan Stoza        if (result != 0) {
1129076ac670262e448c531e6db7727cfade325866caDan Stoza            mDevice.mHwc1Device->getDisplayAttributes(mDevice.mHwc1Device,
1130076ac670262e448c531e6db7727cfade325866caDan Stoza                    mHwc1Id, hwc1ConfigId, ATTRIBUTES_WITHOUT_COLOR, values);
1131076ac670262e448c531e6db7727cfade325866caDan Stoza            hasColor = false;
1132076ac670262e448c531e6db7727cfade325866caDan Stoza        }
1133076ac670262e448c531e6db7727cfade325866caDan Stoza
1134076ac670262e448c531e6db7727cfade325866caDan Stoza        auto attributeMap = hasColor ?
1135076ac670262e448c531e6db7727cfade325866caDan Stoza                ATTRIBUTE_MAP_WITH_COLOR : ATTRIBUTE_MAP_WITHOUT_COLOR;
1136076ac670262e448c531e6db7727cfade325866caDan Stoza
1137076ac670262e448c531e6db7727cfade325866caDan Stoza        newConfig->setAttribute(Attribute::VsyncPeriod,
1138076ac670262e448c531e6db7727cfade325866caDan Stoza                values[attributeMap[HWC_DISPLAY_VSYNC_PERIOD]]);
1139076ac670262e448c531e6db7727cfade325866caDan Stoza        newConfig->setAttribute(Attribute::Width,
1140076ac670262e448c531e6db7727cfade325866caDan Stoza                values[attributeMap[HWC_DISPLAY_WIDTH]]);
1141076ac670262e448c531e6db7727cfade325866caDan Stoza        newConfig->setAttribute(Attribute::Height,
1142076ac670262e448c531e6db7727cfade325866caDan Stoza                values[attributeMap[HWC_DISPLAY_HEIGHT]]);
1143076ac670262e448c531e6db7727cfade325866caDan Stoza        newConfig->setAttribute(Attribute::DpiX,
1144076ac670262e448c531e6db7727cfade325866caDan Stoza                values[attributeMap[HWC_DISPLAY_DPI_X]]);
1145076ac670262e448c531e6db7727cfade325866caDan Stoza        newConfig->setAttribute(Attribute::DpiY,
1146076ac670262e448c531e6db7727cfade325866caDan Stoza                values[attributeMap[HWC_DISPLAY_DPI_Y]]);
1147076ac670262e448c531e6db7727cfade325866caDan Stoza        if (hasColor) {
114828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            // In HWC1, color modes are referred to as color transforms. To avoid confusion with
114928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            // the HWC2 concept of color transforms, we internally refer to them as color modes for
115028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            // both HWC1 and 2.
115128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            newConfig->setAttribute(ColorMode,
1152076ac670262e448c531e6db7727cfade325866caDan Stoza                    values[attributeMap[HWC_DISPLAY_COLOR_TRANSFORM]]);
1153076ac670262e448c531e6db7727cfade325866caDan Stoza        }
1154076ac670262e448c531e6db7727cfade325866caDan Stoza
115528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        // We can only do this after attempting to read the color mode
1156076ac670262e448c531e6db7727cfade325866caDan Stoza        newConfig->setHwc1Id(hwc1ConfigId);
1157076ac670262e448c531e6db7727cfade325866caDan Stoza
1158076ac670262e448c531e6db7727cfade325866caDan Stoza        for (auto& existingConfig : mConfigs) {
1159076ac670262e448c531e6db7727cfade325866caDan Stoza            if (existingConfig->merge(*newConfig)) {
1160076ac670262e448c531e6db7727cfade325866caDan Stoza                ALOGV("Merged config %d with existing config %u: %s",
1161076ac670262e448c531e6db7727cfade325866caDan Stoza                        hwc1ConfigId, existingConfig->getId(),
1162076ac670262e448c531e6db7727cfade325866caDan Stoza                        existingConfig->toString().c_str());
1163076ac670262e448c531e6db7727cfade325866caDan Stoza                newConfig.reset();
1164076ac670262e448c531e6db7727cfade325866caDan Stoza                break;
1165076ac670262e448c531e6db7727cfade325866caDan Stoza            }
1166076ac670262e448c531e6db7727cfade325866caDan Stoza        }
1167076ac670262e448c531e6db7727cfade325866caDan Stoza
1168076ac670262e448c531e6db7727cfade325866caDan Stoza        // If it wasn't merged with any existing config, add it to the end
1169076ac670262e448c531e6db7727cfade325866caDan Stoza        if (newConfig) {
1170076ac670262e448c531e6db7727cfade325866caDan Stoza            newConfig->setId(static_cast<hwc2_config_t>(mConfigs.size()));
1171076ac670262e448c531e6db7727cfade325866caDan Stoza            ALOGV("Found new config %u: %s", newConfig->getId(),
1172076ac670262e448c531e6db7727cfade325866caDan Stoza                    newConfig->toString().c_str());
1173076ac670262e448c531e6db7727cfade325866caDan Stoza            mConfigs.emplace_back(std::move(newConfig));
1174c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1175c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1176076ac670262e448c531e6db7727cfade325866caDan Stoza
1177076ac670262e448c531e6db7727cfade325866caDan Stoza    initializeActiveConfig();
1178076ac670262e448c531e6db7727cfade325866caDan Stoza    populateColorModes();
1179c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1180c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
118106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardvoid HWC2On1Adapter::Display::populateConfigs(uint32_t width, uint32_t height) {
1182c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1183c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1184076ac670262e448c531e6db7727cfade325866caDan Stoza    mConfigs.emplace_back(std::make_shared<Config>(*this));
1185c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto& config = mConfigs[0];
1186c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1187c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    config->setAttribute(Attribute::Width, static_cast<int32_t>(width));
1188c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    config->setAttribute(Attribute::Height, static_cast<int32_t>(height));
1189076ac670262e448c531e6db7727cfade325866caDan Stoza    config->setHwc1Id(0);
1190076ac670262e448c531e6db7727cfade325866caDan Stoza    config->setId(0);
1191c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mActiveConfig = config;
1192c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1193c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
119406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardbool HWC2On1Adapter::Display::prepare() {
1195c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1196c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1197c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Only prepare display contents for displays HWC1 knows about
1198c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1Id == -1) {
1199c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return true;
1200c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1201c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1202c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // It doesn't make sense to prepare a display for which there is no active
1203c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // config, so return early
1204c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!mActiveConfig) {
1205c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("[%" PRIu64 "] Attempted to prepare, but no config active", mId);
1206c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return false;
1207c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1208c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
120906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    allocateRequestedContents();
121006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    assignHwc1LayerIds();
1211c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1212c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1RequestedContents->retireFenceFd = -1;
1213c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1RequestedContents->flags = 0;
121406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    if (mGeometryChanged) {
1215c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHwc1RequestedContents->flags |= HWC_GEOMETRY_CHANGED;
1216c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
121706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mHwc1RequestedContents->outbuf = mOutputBuffer.getBuffer();
121806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mHwc1RequestedContents->outbufAcquireFenceFd = mOutputBuffer.getFence();
1219c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
122006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    // +1 is for framebuffer target layer.
122106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mHwc1RequestedContents->numHwLayers = mLayers.size() + 1;
1222c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (auto& layer : mLayers) {
1223c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& hwc1Layer = mHwc1RequestedContents->hwLayers[layer->getHwc1Id()];
1224c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Layer.releaseFenceFd = -1;
122516ab8191fee19ed977daf31cf5b460851162fb6dFabien Sanglard        hwc1Layer.acquireFenceFd = -1;
1226999a7fdad2a48d0517f515cc6ea6c7324aa28228Fabien Sanglard        ALOGV("Applying states for layer %" PRIu64 " ", layer->getId());
122706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        layer->applyState(hwc1Layer);
1228c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1229c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1230c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    prepareFramebufferTarget();
1231c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
123206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    resetGeometryMarker();
1233c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
123406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    return true;
1235c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1236c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
123706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardvoid HWC2On1Adapter::Display::generateChanges() {
1238c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1239c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1240c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mChanges.reset(new Changes);
1241c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
124206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    size_t numLayers = mHwc1RequestedContents->numHwLayers;
1243c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t hwc1Id = 0; hwc1Id < numLayers; ++hwc1Id) {
124406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        const auto& receivedLayer = mHwc1RequestedContents->hwLayers[hwc1Id];
1245c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (mHwc1LayerMap.count(hwc1Id) == 0) {
1246c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGE_IF(receivedLayer.compositionType != HWC_FRAMEBUFFER_TARGET,
124706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard                    "generateChanges: HWC1 layer %zd doesn't have a"
1248c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    " matching HWC2 layer, and isn't the framebuffer target",
1249c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    hwc1Id);
1250c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            continue;
1251c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1252c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1253c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        Layer& layer = *mHwc1LayerMap[hwc1Id];
1254c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        updateTypeChanges(receivedLayer, layer);
1255c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        updateLayerRequests(receivedLayer, layer);
1256c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1257c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1258c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
125906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardbool HWC2On1Adapter::Display::hasChanges() const {
1260c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1261c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return mChanges != nullptr;
1262c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1263c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
126406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Display::set(hwc_display_contents_1& hwcContents) {
1265c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1266c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1267c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!mChanges || (mChanges->getNumTypes() > 0)) {
1268c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("[%" PRIu64 "] set failed: not validated", mId);
1269c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::NotValidated;
1270c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1271c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1272c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Set up the client/framebuffer target
1273c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto numLayers = hwcContents.numHwLayers;
1274c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1275c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Close acquire fences on FRAMEBUFFER layers, since they will not be used
1276c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // by HWC
1277c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t l = 0; l < numLayers - 1; ++l) {
1278c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& layer = hwcContents.hwLayers[l];
1279c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (layer.compositionType == HWC_FRAMEBUFFER) {
1280c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGV("Closing fence %d for layer %zd", layer.acquireFenceFd, l);
1281c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            close(layer.acquireFenceFd);
1282c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            layer.acquireFenceFd = -1;
1283c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1284c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1285c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1286c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto& clientTargetLayer = hwcContents.hwLayers[numLayers - 1];
1287c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (clientTargetLayer.compositionType == HWC_FRAMEBUFFER_TARGET) {
1288c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        clientTargetLayer.handle = mClientTarget.getBuffer();
1289c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        clientTargetLayer.acquireFenceFd = mClientTarget.getFence();
1290c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
1291c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("[%" PRIu64 "] set: last HWC layer wasn't FRAMEBUFFER_TARGET",
1292c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mId);
1293c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1294c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1295c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mChanges.reset();
1296c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1297c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1298c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1299c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
130006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardvoid HWC2On1Adapter::Display::addRetireFence(int fenceFd) {
1301c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1302c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mRetireFence.add(fenceFd);
1303c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1304c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1305c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::addReleaseFences(
130606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        const hwc_display_contents_1_t& hwcContents) {
1307c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1308c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1309c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    size_t numLayers = hwcContents.numHwLayers;
1310c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t hwc1Id = 0; hwc1Id < numLayers; ++hwc1Id) {
1311c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        const auto& receivedLayer = hwcContents.hwLayers[hwc1Id];
1312c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (mHwc1LayerMap.count(hwc1Id) == 0) {
1313c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            if (receivedLayer.compositionType != HWC_FRAMEBUFFER_TARGET) {
1314c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                ALOGE("addReleaseFences: HWC1 layer %zd doesn't have a"
1315c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                        " matching HWC2 layer, and isn't the framebuffer"
1316c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                        " target", hwc1Id);
1317c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
1318c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            // Close the framebuffer target release fence since we will use the
1319c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            // display retire fence instead
1320c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            if (receivedLayer.releaseFenceFd != -1) {
1321c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                close(receivedLayer.releaseFenceFd);
1322c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
1323c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            continue;
1324c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1325c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1326c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        Layer& layer = *mHwc1LayerMap[hwc1Id];
1327c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("Adding release fence %d to layer %" PRIu64,
1328c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                receivedLayer.releaseFenceFd, layer.getId());
1329c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        layer.addReleaseFence(receivedLayer.releaseFenceFd);
1330c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1331c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1332c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
133306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardbool HWC2On1Adapter::Display::hasColorTransform() const {
13345df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
13355df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    return mHasColorTransform;
13365df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza}
13375df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza
133806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardstatic std::string hwc1CompositionString(int32_t type) {
1339c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (type) {
1340c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_FRAMEBUFFER: return "Framebuffer";
1341c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_OVERLAY: return "Overlay";
1342c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_BACKGROUND: return "Background";
1343c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_FRAMEBUFFER_TARGET: return "FramebufferTarget";
1344c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_SIDEBAND: return "Sideband";
1345c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_CURSOR_OVERLAY: return "CursorOverlay";
1346c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        default:
1347c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return std::string("Unknown (") + std::to_string(type) + ")";
1348c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1349c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1350c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
135106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardstatic std::string hwc1TransformString(int32_t transform) {
1352c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (transform) {
1353c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case 0: return "None";
1354c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_TRANSFORM_FLIP_H: return "FlipH";
1355c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_TRANSFORM_FLIP_V: return "FlipV";
1356c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_TRANSFORM_ROT_90: return "Rotate90";
1357c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_TRANSFORM_ROT_180: return "Rotate180";
1358c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_TRANSFORM_ROT_270: return "Rotate270";
1359c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_TRANSFORM_FLIP_H_ROT_90: return "FlipHRotate90";
1360c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_TRANSFORM_FLIP_V_ROT_90: return "FlipVRotate90";
1361c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        default:
1362c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return std::string("Unknown (") + std::to_string(transform) + ")";
1363c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1364c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1365c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
136606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardstatic std::string hwc1BlendModeString(int32_t mode) {
1367c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (mode) {
1368c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_BLENDING_NONE: return "None";
1369c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_BLENDING_PREMULT: return "Premultiplied";
1370c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_BLENDING_COVERAGE: return "Coverage";
1371c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        default:
1372c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return std::string("Unknown (") + std::to_string(mode) + ")";
1373c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1374c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1375c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
137606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardstatic std::string rectString(hwc_rect_t rect) {
1377c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::stringstream output;
1378c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "[" << rect.left << ", " << rect.top << ", ";
1379c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << rect.right << ", " << rect.bottom << "]";
1380c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return output.str();
1381c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1382c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
138306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardstatic std::string approximateFloatString(float f) {
1384c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (static_cast<int32_t>(f) == f) {
1385c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return std::to_string(static_cast<int32_t>(f));
1386c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1387c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    int32_t truncated = static_cast<int32_t>(f * 10);
1388c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    bool approximate = (static_cast<float>(truncated) != f * 10);
1389c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const size_t BUFFER_SIZE = 32;
1390c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    char buffer[BUFFER_SIZE] = {};
1391c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto bytesWritten = snprintf(buffer, BUFFER_SIZE,
1392c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            "%s%.1f", approximate ? "~" : "", f);
1393c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return std::string(buffer, bytesWritten);
1394c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1395c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
139606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardstatic std::string frectString(hwc_frect_t frect) {
1397c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::stringstream output;
1398c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "[" << approximateFloatString(frect.left) << ", ";
1399c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << approximateFloatString(frect.top) << ", ";
1400c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << approximateFloatString(frect.right) << ", ";
1401c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << approximateFloatString(frect.bottom) << "]";
1402c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return output.str();
1403c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1404c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
140506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardstatic std::string colorString(hwc_color_t color) {
1406c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::stringstream output;
1407c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "RGBA [";
1408c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << static_cast<int32_t>(color.r) << ", ";
1409c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << static_cast<int32_t>(color.g) << ", ";
1410c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << static_cast<int32_t>(color.b) << ", ";
1411c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << static_cast<int32_t>(color.a) << "]";
1412c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return output.str();
1413c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1414c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
141506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardstatic std::string alphaString(float f) {
1416c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const size_t BUFFER_SIZE = 8;
1417c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    char buffer[BUFFER_SIZE] = {};
1418c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto bytesWritten = snprintf(buffer, BUFFER_SIZE, "%.3f", f);
1419c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return std::string(buffer, bytesWritten);
1420c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1421c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1422c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string to_string(const hwc_layer_1_t& hwcLayer,
142306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        int32_t hwc1MinorVersion) {
1424c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const char* fill = "          ";
1425c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1426c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::stringstream output;
1427c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1428c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "  Composition: " <<
1429c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            hwc1CompositionString(hwcLayer.compositionType);
1430c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1431c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (hwcLayer.compositionType == HWC_BACKGROUND) {
1432c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "  Color: " << colorString(hwcLayer.backgroundColor) << '\n';
1433c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else if (hwcLayer.compositionType == HWC_SIDEBAND) {
1434c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "  Stream: " << hwcLayer.sidebandStream << '\n';
1435c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
1436c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "  Buffer: " << hwcLayer.handle << "/" <<
1437c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwcLayer.acquireFenceFd << '\n';
1438c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1439c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1440c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << fill << "Display frame: " << rectString(hwcLayer.displayFrame) <<
1441c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            '\n';
1442c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1443c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << fill << "Source crop: ";
1444c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (hwc1MinorVersion >= 3) {
1445c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << frectString(hwcLayer.sourceCropf) << '\n';
1446c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
1447c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << rectString(hwcLayer.sourceCropi) << '\n';
1448c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1449c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1450c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << fill << "Transform: " << hwc1TransformString(hwcLayer.transform);
1451c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "  Blend mode: " << hwc1BlendModeString(hwcLayer.blending);
1452c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (hwcLayer.planeAlpha != 0xFF) {
1453c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "  Alpha: " << alphaString(hwcLayer.planeAlpha / 255.0f);
1454c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1455c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << '\n';
1456c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1457c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (hwcLayer.hints != 0) {
1458c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << fill << "Hints:";
1459c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if ((hwcLayer.hints & HWC_HINT_TRIPLE_BUFFER) != 0) {
1460c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            output << " TripleBuffer";
1461c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1462c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if ((hwcLayer.hints & HWC_HINT_CLEAR_FB) != 0) {
1463c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            output << " ClearFB";
1464c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1465c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << '\n';
1466c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1467c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1468c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (hwcLayer.flags != 0) {
1469c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << fill << "Flags:";
1470c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if ((hwcLayer.flags & HWC_SKIP_LAYER) != 0) {
1471c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            output << " SkipLayer";
1472c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1473c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if ((hwcLayer.flags & HWC_IS_CURSOR_LAYER) != 0) {
1474c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            output << " IsCursorLayer";
1475c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1476c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << '\n';
1477c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1478c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1479c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return output.str();
1480c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1481c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1482c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string to_string(const hwc_display_contents_1_t& hwcContents,
148306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        int32_t hwc1MinorVersion) {
1484c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const char* fill = "      ";
1485c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1486c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::stringstream output;
1487c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << fill << "Geometry changed: " <<
1488c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ((hwcContents.flags & HWC_GEOMETRY_CHANGED) != 0 ? "Y\n" : "N\n");
1489c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1490c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << fill << hwcContents.numHwLayers << " Layer" <<
1491c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ((hwcContents.numHwLayers == 1) ? "\n" : "s\n");
1492c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t layer = 0; layer < hwcContents.numHwLayers; ++layer) {
1493c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << fill << "  Layer " << layer;
1494c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << to_string(hwcContents.hwLayers[layer], hwc1MinorVersion);
1495c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1496c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1497c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (hwcContents.outbuf != nullptr) {
1498c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << fill << "Output buffer: " << hwcContents.outbuf << "/" <<
1499c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwcContents.outbufAcquireFenceFd << '\n';
1500c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1501c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1502c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return output.str();
1503c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1504c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
150506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardstd::string HWC2On1Adapter::Display::dump() const {
1506c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::unique_lock<std::recursive_mutex> lock(mStateMutex);
1507c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1508c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::stringstream output;
1509c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1510c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "  Display " << mId << ": ";
1511c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << to_string(mType) << "  ";
1512c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "HWC1 ID: " << mHwc1Id << "  ";
1513c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "Power mode: " << to_string(mPowerMode) << "  ";
1514c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "Vsync: " << to_string(mVsyncEnabled) << '\n';
1515c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1516076ac670262e448c531e6db7727cfade325866caDan Stoza    output << "    Color modes [active]:";
1517076ac670262e448c531e6db7727cfade325866caDan Stoza    for (const auto& mode : mColorModes) {
1518076ac670262e448c531e6db7727cfade325866caDan Stoza        if (mode == mActiveColorMode) {
1519076ac670262e448c531e6db7727cfade325866caDan Stoza            output << " [" << mode << ']';
1520c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        } else {
1521076ac670262e448c531e6db7727cfade325866caDan Stoza            output << " " << mode;
1522c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
1523c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1524c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << '\n';
1525c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1526076ac670262e448c531e6db7727cfade325866caDan Stoza    output << "    " << mConfigs.size() << " Config" <<
1527076ac670262e448c531e6db7727cfade325866caDan Stoza            (mConfigs.size() == 1 ? "" : "s") << " (* active)\n";
1528076ac670262e448c531e6db7727cfade325866caDan Stoza    for (const auto& config : mConfigs) {
1529076ac670262e448c531e6db7727cfade325866caDan Stoza        output << (config == mActiveConfig ? "    * " : "      ");
1530076ac670262e448c531e6db7727cfade325866caDan Stoza        output << config->toString(true) << '\n';
1531076ac670262e448c531e6db7727cfade325866caDan Stoza    }
1532076ac670262e448c531e6db7727cfade325866caDan Stoza
1533c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "    " << mLayers.size() << " Layer" <<
1534c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            (mLayers.size() == 1 ? "" : "s") << '\n';
1535c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (const auto& layer : mLayers) {
1536c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << layer->dump();
1537c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1538c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1539c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "    Client target: " << mClientTarget.getBuffer() << '\n';
1540c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1541c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mOutputBuffer.getBuffer() != nullptr) {
1542c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "    Output buffer: " << mOutputBuffer.getBuffer() << '\n';
1543c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1544c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
154506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    if (mHwc1RequestedContents) {
1546c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "    Last requested HWC1 state\n";
1547c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << to_string(*mHwc1RequestedContents, mDevice.mHwc1MinorVersion);
1548c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1549c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1550c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return output.str();
1551c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1552c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
155306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardhwc_rect_t* HWC2On1Adapter::Display::GetRects(size_t numRects) {
155406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    if (numRects == 0) {
155506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        return nullptr;
155606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    }
155706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard
155806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    if (numRects > mNumAvailableRects) {
155906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        // This should NEVER happen since we calculated how many rects the
156006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        // display would need.
156106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        ALOGE("Rect allocation failure! SF is likely to crash soon!");
156206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        return nullptr;
156306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard
156406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    }
156506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    hwc_rect_t* rects = mNextAvailableRect;
156606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mNextAvailableRect += numRects;
156706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mNumAvailableRects -= numRects;
156806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    return rects;
156906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard}
157006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard
157106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardhwc_display_contents_1* HWC2On1Adapter::Display::getDisplayContents() {
157206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    return mHwc1RequestedContents.get();
157306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard}
157406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard
1575c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::Config::setAttribute(HWC2::Attribute attribute,
157606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        int32_t value) {
1577c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mAttributes[attribute] = value;
1578c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1579c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
158006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardint32_t HWC2On1Adapter::Display::Config::getAttribute(Attribute attribute) const {
1581c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mAttributes.count(attribute) == 0) {
1582c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return -1;
1583c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1584c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return mAttributes.at(attribute);
1585c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1586c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
158706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardvoid HWC2On1Adapter::Display::Config::setHwc1Id(uint32_t id) {
158828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    android_color_mode_t colorMode = static_cast<android_color_mode_t>(getAttribute(ColorMode));
158928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    mHwc1Ids.emplace(colorMode, id);
1590076ac670262e448c531e6db7727cfade325866caDan Stoza}
1591076ac670262e448c531e6db7727cfade325866caDan Stoza
159206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardbool HWC2On1Adapter::Display::Config::hasHwc1Id(uint32_t id) const {
1593076ac670262e448c531e6db7727cfade325866caDan Stoza    for (const auto& idPair : mHwc1Ids) {
1594076ac670262e448c531e6db7727cfade325866caDan Stoza        if (id == idPair.second) {
1595076ac670262e448c531e6db7727cfade325866caDan Stoza            return true;
1596076ac670262e448c531e6db7727cfade325866caDan Stoza        }
1597076ac670262e448c531e6db7727cfade325866caDan Stoza    }
1598076ac670262e448c531e6db7727cfade325866caDan Stoza    return false;
1599076ac670262e448c531e6db7727cfade325866caDan Stoza}
1600076ac670262e448c531e6db7727cfade325866caDan Stoza
160128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael WrightError HWC2On1Adapter::Display::Config::getColorModeForHwc1Id(
160206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        uint32_t id, android_color_mode_t* outMode) const {
1603076ac670262e448c531e6db7727cfade325866caDan Stoza    for (const auto& idPair : mHwc1Ids) {
1604076ac670262e448c531e6db7727cfade325866caDan Stoza        if (id == idPair.second) {
160528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            *outMode = idPair.first;
160628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            return Error::None;
1607076ac670262e448c531e6db7727cfade325866caDan Stoza        }
1608076ac670262e448c531e6db7727cfade325866caDan Stoza    }
160928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    ALOGE("Unable to find color mode for HWC ID %" PRIu32 " on config %u", id, mId);
161028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return Error::BadParameter;
1611076ac670262e448c531e6db7727cfade325866caDan Stoza}
1612076ac670262e448c531e6db7727cfade325866caDan Stoza
161328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael WrightError HWC2On1Adapter::Display::Config::getHwc1IdForColorMode(android_color_mode_t mode,
161406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        uint32_t* outId) const {
1615076ac670262e448c531e6db7727cfade325866caDan Stoza    for (const auto& idPair : mHwc1Ids) {
1616076ac670262e448c531e6db7727cfade325866caDan Stoza        if (mode == idPair.first) {
1617076ac670262e448c531e6db7727cfade325866caDan Stoza            *outId = idPair.second;
1618076ac670262e448c531e6db7727cfade325866caDan Stoza            return Error::None;
1619076ac670262e448c531e6db7727cfade325866caDan Stoza        }
1620076ac670262e448c531e6db7727cfade325866caDan Stoza    }
1621076ac670262e448c531e6db7727cfade325866caDan Stoza    ALOGE("Unable to find HWC1 ID for color mode %d on config %u", mode, mId);
1622076ac670262e448c531e6db7727cfade325866caDan Stoza    return Error::BadParameter;
1623076ac670262e448c531e6db7727cfade325866caDan Stoza}
1624076ac670262e448c531e6db7727cfade325866caDan Stoza
162506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardbool HWC2On1Adapter::Display::Config::merge(const Config& other) {
1626076ac670262e448c531e6db7727cfade325866caDan Stoza    auto attributes = {HWC2::Attribute::Width, HWC2::Attribute::Height,
1627076ac670262e448c531e6db7727cfade325866caDan Stoza            HWC2::Attribute::VsyncPeriod, HWC2::Attribute::DpiX,
1628076ac670262e448c531e6db7727cfade325866caDan Stoza            HWC2::Attribute::DpiY};
1629076ac670262e448c531e6db7727cfade325866caDan Stoza    for (auto attribute : attributes) {
1630076ac670262e448c531e6db7727cfade325866caDan Stoza        if (getAttribute(attribute) != other.getAttribute(attribute)) {
1631076ac670262e448c531e6db7727cfade325866caDan Stoza            return false;
1632076ac670262e448c531e6db7727cfade325866caDan Stoza        }
1633076ac670262e448c531e6db7727cfade325866caDan Stoza    }
163428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    android_color_mode_t otherColorMode =
163528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            static_cast<android_color_mode_t>(other.getAttribute(ColorMode));
163628f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    if (mHwc1Ids.count(otherColorMode) != 0) {
1637076ac670262e448c531e6db7727cfade325866caDan Stoza        ALOGE("Attempted to merge two configs (%u and %u) which appear to be "
163828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                "identical", mHwc1Ids.at(otherColorMode),
163928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                other.mHwc1Ids.at(otherColorMode));
1640076ac670262e448c531e6db7727cfade325866caDan Stoza        return false;
1641076ac670262e448c531e6db7727cfade325866caDan Stoza    }
164228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    mHwc1Ids.emplace(otherColorMode,
164328f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright            other.mHwc1Ids.at(otherColorMode));
1644076ac670262e448c531e6db7727cfade325866caDan Stoza    return true;
1645076ac670262e448c531e6db7727cfade325866caDan Stoza}
1646076ac670262e448c531e6db7727cfade325866caDan Stoza
164706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardstd::set<android_color_mode_t> HWC2On1Adapter::Display::Config::getColorModes() const {
164828f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    std::set<android_color_mode_t> colorModes;
1649076ac670262e448c531e6db7727cfade325866caDan Stoza    for (const auto& idPair : mHwc1Ids) {
165028f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        colorModes.emplace(idPair.first);
1651076ac670262e448c531e6db7727cfade325866caDan Stoza    }
165228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    return colorModes;
1653076ac670262e448c531e6db7727cfade325866caDan Stoza}
1654076ac670262e448c531e6db7727cfade325866caDan Stoza
165506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardstd::string HWC2On1Adapter::Display::Config::toString(bool splitLine) const {
1656c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::string output;
1657c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1658c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const size_t BUFFER_SIZE = 100;
1659c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    char buffer[BUFFER_SIZE] = {};
1660c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto writtenBytes = snprintf(buffer, BUFFER_SIZE,
1661076ac670262e448c531e6db7727cfade325866caDan Stoza            "%u x %u", mAttributes.at(HWC2::Attribute::Width),
1662c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            mAttributes.at(HWC2::Attribute::Height));
1663c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output.append(buffer, writtenBytes);
1664c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1665c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mAttributes.count(HWC2::Attribute::VsyncPeriod) != 0) {
1666c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        std::memset(buffer, 0, BUFFER_SIZE);
1667c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        writtenBytes = snprintf(buffer, BUFFER_SIZE, " @ %.1f Hz",
1668c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                1e9 / mAttributes.at(HWC2::Attribute::VsyncPeriod));
1669c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output.append(buffer, writtenBytes);
1670c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1671c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1672c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mAttributes.count(HWC2::Attribute::DpiX) != 0 &&
1673c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            mAttributes.at(HWC2::Attribute::DpiX) != -1) {
1674c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        std::memset(buffer, 0, BUFFER_SIZE);
1675c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        writtenBytes = snprintf(buffer, BUFFER_SIZE,
1676c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                ", DPI: %.1f x %.1f",
1677c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mAttributes.at(HWC2::Attribute::DpiX) / 1000.0f,
1678c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mAttributes.at(HWC2::Attribute::DpiY) / 1000.0f);
1679c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output.append(buffer, writtenBytes);
1680c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1681c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1682076ac670262e448c531e6db7727cfade325866caDan Stoza    std::memset(buffer, 0, BUFFER_SIZE);
1683076ac670262e448c531e6db7727cfade325866caDan Stoza    if (splitLine) {
1684076ac670262e448c531e6db7727cfade325866caDan Stoza        writtenBytes = snprintf(buffer, BUFFER_SIZE,
1685076ac670262e448c531e6db7727cfade325866caDan Stoza                "\n        HWC1 ID/Color transform:");
1686076ac670262e448c531e6db7727cfade325866caDan Stoza    } else {
1687076ac670262e448c531e6db7727cfade325866caDan Stoza        writtenBytes = snprintf(buffer, BUFFER_SIZE,
1688076ac670262e448c531e6db7727cfade325866caDan Stoza                ", HWC1 ID/Color transform:");
1689076ac670262e448c531e6db7727cfade325866caDan Stoza    }
1690076ac670262e448c531e6db7727cfade325866caDan Stoza    output.append(buffer, writtenBytes);
1691076ac670262e448c531e6db7727cfade325866caDan Stoza
1692076ac670262e448c531e6db7727cfade325866caDan Stoza
1693076ac670262e448c531e6db7727cfade325866caDan Stoza    for (const auto& id : mHwc1Ids) {
169428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        android_color_mode_t colorMode = id.first;
1695076ac670262e448c531e6db7727cfade325866caDan Stoza        uint32_t hwc1Id = id.second;
1696076ac670262e448c531e6db7727cfade325866caDan Stoza        std::memset(buffer, 0, BUFFER_SIZE);
169728f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        if (colorMode == mDisplay.mActiveColorMode) {
1698076ac670262e448c531e6db7727cfade325866caDan Stoza            writtenBytes = snprintf(buffer, BUFFER_SIZE, " [%u/%d]", hwc1Id,
169928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                    colorMode);
1700076ac670262e448c531e6db7727cfade325866caDan Stoza        } else {
1701076ac670262e448c531e6db7727cfade325866caDan Stoza            writtenBytes = snprintf(buffer, BUFFER_SIZE, " %u/%d", hwc1Id,
170228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright                    colorMode);
1703076ac670262e448c531e6db7727cfade325866caDan Stoza        }
1704076ac670262e448c531e6db7727cfade325866caDan Stoza        output.append(buffer, writtenBytes);
1705076ac670262e448c531e6db7727cfade325866caDan Stoza    }
1706076ac670262e448c531e6db7727cfade325866caDan Stoza
1707c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return output;
1708c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1709c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1710c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastd::shared_ptr<const HWC2On1Adapter::Display::Config>
171106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        HWC2On1Adapter::Display::getConfig(hwc2_config_t configId) const {
1712c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (configId > mConfigs.size() || !mConfigs[configId]->isOnDisplay(*this)) {
1713c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return nullptr;
1714c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1715c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return mConfigs[configId];
1716c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1717c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
171806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardvoid HWC2On1Adapter::Display::populateColorModes() {
171928f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright    mColorModes = mConfigs[0]->getColorModes();
1720076ac670262e448c531e6db7727cfade325866caDan Stoza    for (const auto& config : mConfigs) {
172128f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        std::set<android_color_mode_t> intersection;
172228f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        auto configModes = config->getColorModes();
1723076ac670262e448c531e6db7727cfade325866caDan Stoza        std::set_intersection(mColorModes.cbegin(), mColorModes.cend(),
1724076ac670262e448c531e6db7727cfade325866caDan Stoza                configModes.cbegin(), configModes.cend(),
1725076ac670262e448c531e6db7727cfade325866caDan Stoza                std::inserter(intersection, intersection.begin()));
1726076ac670262e448c531e6db7727cfade325866caDan Stoza        std::swap(intersection, mColorModes);
1727076ac670262e448c531e6db7727cfade325866caDan Stoza    }
1728076ac670262e448c531e6db7727cfade325866caDan Stoza}
1729076ac670262e448c531e6db7727cfade325866caDan Stoza
173006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardvoid HWC2On1Adapter::Display::initializeActiveConfig() {
1731076ac670262e448c531e6db7727cfade325866caDan Stoza    if (mDevice.mHwc1Device->getActiveConfig == nullptr) {
1732076ac670262e448c531e6db7727cfade325866caDan Stoza        ALOGV("getActiveConfig is null, choosing config 0");
1733076ac670262e448c531e6db7727cfade325866caDan Stoza        mActiveConfig = mConfigs[0];
173428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright        mActiveColorMode = HAL_COLOR_MODE_NATIVE;
1735076ac670262e448c531e6db7727cfade325866caDan Stoza        return;
1736076ac670262e448c531e6db7727cfade325866caDan Stoza    }
1737076ac670262e448c531e6db7727cfade325866caDan Stoza
1738076ac670262e448c531e6db7727cfade325866caDan Stoza    auto activeConfig = mDevice.mHwc1Device->getActiveConfig(
1739076ac670262e448c531e6db7727cfade325866caDan Stoza            mDevice.mHwc1Device, mHwc1Id);
1740b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard
1741b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard    // Some devices startup without an activeConfig:
1742b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard    // We need to set one ourselves.
1743b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard    if (activeConfig == HWC_ERROR) {
1744b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard        ALOGV("There is no active configuration: Picking the first one: 0.");
1745b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard        const int defaultIndex = 0;
1746b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard        mDevice.mHwc1Device->setActiveConfig(mDevice.mHwc1Device, mHwc1Id, defaultIndex);
1747b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard        activeConfig = defaultIndex;
1748b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard    }
1749b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard
1750b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard    for (const auto& config : mConfigs) {
1751b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard        if (config->hasHwc1Id(activeConfig)) {
1752b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard            ALOGE("Setting active config to %d for HWC1 config %u", config->getId(), activeConfig);
1753b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard            mActiveConfig = config;
1754b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard            if (config->getColorModeForHwc1Id(activeConfig, &mActiveColorMode) != Error::None) {
1755b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard                // This should never happen since we checked for the config's presence before
1756b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard                // setting it as active.
1757b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard                ALOGE("Unable to find color mode for active HWC1 config %d", config->getId());
1758b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard                mActiveColorMode = HAL_COLOR_MODE_NATIVE;
1759076ac670262e448c531e6db7727cfade325866caDan Stoza            }
1760b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard            break;
1761076ac670262e448c531e6db7727cfade325866caDan Stoza        }
1762076ac670262e448c531e6db7727cfade325866caDan Stoza    }
1763b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard    if (!mActiveConfig) {
1764b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard        ALOGV("Unable to find active HWC1 config %u, defaulting to "
1765b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard                "config 0", activeConfig);
1766b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard        mActiveConfig = mConfigs[0];
1767b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard        mActiveColorMode = HAL_COLOR_MODE_NATIVE;
1768b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard    }
1769b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard
1770b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard
1771b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard
1772b7432cc57cd957fb18f68d7976c5829b3a3a7751Fabien Sanglard
1773076ac670262e448c531e6db7727cfade325866caDan Stoza}
1774076ac670262e448c531e6db7727cfade325866caDan Stoza
177506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardvoid HWC2On1Adapter::Display::allocateRequestedContents() {
177606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    // What needs to be allocated:
177706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    // 1 hwc_display_contents_1_t
177806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    // 1 hwc_layer_1_t for each layer
177906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    // 1 hwc_rect_t for each layer's surfaceDamage
178006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    // 1 hwc_rect_t for each layer's visibleRegion
178106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    // 1 hwc_layer_1_t for the framebuffer
178206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    // 1 hwc_rect_t for the framebuffer's visibleRegion
178306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard
178406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    // Count # of surfaceDamage
178506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    size_t numSurfaceDamages = 0;
178606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    for (const auto& layer : mLayers) {
178706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        numSurfaceDamages += layer->getNumSurfaceDamages();
178806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    }
178906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard
179006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    // Count # of visibleRegions (start at 1 for mandatory framebuffer target
179106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    // region)
179206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    size_t numVisibleRegion = 1;
179306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    for (const auto& layer : mLayers) {
179406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        numVisibleRegion += layer->getNumVisibleRegions();
179506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    }
179606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard
179706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    size_t numRects = numVisibleRegion + numSurfaceDamages;
1798c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto numLayers = mLayers.size() + 1;
1799c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    size_t size = sizeof(hwc_display_contents_1_t) +
180006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            sizeof(hwc_layer_1_t) * numLayers +
180106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            sizeof(hwc_rect_t) * numRects;
180206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    auto contents = static_cast<hwc_display_contents_1_t*>(std::calloc(size, 1));
1803c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1RequestedContents.reset(contents);
180406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mNextAvailableRect = reinterpret_cast<hwc_rect_t*>(&contents->hwLayers[numLayers]);
180506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mNumAvailableRects = numRects;
1806c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1807c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
180806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardvoid HWC2On1Adapter::Display::assignHwc1LayerIds() {
1809c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1LayerMap.clear();
1810c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    size_t nextHwc1Id = 0;
1811c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (auto& layer : mLayers) {
1812c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHwc1LayerMap[nextHwc1Id] = layer;
1813c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        layer->setHwc1Id(nextHwc1Id++);
1814c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1815c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1816c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1817c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::updateTypeChanges(const hwc_layer_1_t& hwc1Layer,
181806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        const Layer& layer) {
1819c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto layerId = layer.getId();
1820c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (hwc1Layer.compositionType) {
1821c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_FRAMEBUFFER:
1822c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            if (layer.getCompositionType() != Composition::Client) {
1823c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mChanges->addTypeChange(layerId, Composition::Client);
1824c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
1825c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
1826c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_OVERLAY:
1827c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            if (layer.getCompositionType() != Composition::Device) {
1828c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mChanges->addTypeChange(layerId, Composition::Device);
1829c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            }
1830c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
1831c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_BACKGROUND:
1832c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGE_IF(layer.getCompositionType() != Composition::SolidColor,
1833c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    "updateTypeChanges: HWC1 requested BACKGROUND, but HWC2"
1834c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    " wasn't expecting SolidColor");
1835c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
1836c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_FRAMEBUFFER_TARGET:
1837c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            // Do nothing, since it shouldn't be modified by HWC1
1838c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
1839c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_SIDEBAND:
1840c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGE_IF(layer.getCompositionType() != Composition::Sideband,
1841c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    "updateTypeChanges: HWC1 requested SIDEBAND, but HWC2"
1842c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    " wasn't expecting Sideband");
1843c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
1844c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case HWC_CURSOR_OVERLAY:
1845c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGE_IF(layer.getCompositionType() != Composition::Cursor,
1846c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    "updateTypeChanges: HWC1 requested CURSOR_OVERLAY, but"
1847c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    " HWC2 wasn't expecting Cursor");
1848c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            break;
1849c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1850c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1851c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1852c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozavoid HWC2On1Adapter::Display::updateLayerRequests(
185306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        const hwc_layer_1_t& hwc1Layer, const Layer& layer) {
1854c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if ((hwc1Layer.hints & HWC_HINT_CLEAR_FB) != 0) {
1855c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mChanges->addLayerRequest(layer.getId(),
1856c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                LayerRequest::ClearClientTarget);
1857c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1858c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1859c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
186006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardvoid HWC2On1Adapter::Display::prepareFramebufferTarget() {
1861c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // We check that mActiveConfig is valid in Display::prepare
1862c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    int32_t width = mActiveConfig->getAttribute(Attribute::Width);
1863c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    int32_t height = mActiveConfig->getAttribute(Attribute::Height);
1864c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1865c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto& hwc1Target = mHwc1RequestedContents->hwLayers[mLayers.size()];
1866c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.compositionType = HWC_FRAMEBUFFER_TARGET;
1867c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.releaseFenceFd = -1;
1868c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.hints = 0;
1869c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.flags = 0;
1870c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.transform = 0;
1871c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.blending = HWC_BLENDING_PREMULT;
1872c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mDevice.getHwc1MinorVersion() < 3) {
1873c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Target.sourceCropi = {0, 0, width, height};
1874c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
1875c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Target.sourceCropf = {0.0f, 0.0f, static_cast<float>(width),
1876c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                static_cast<float>(height)};
1877c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1878c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.displayFrame = {0, 0, width, height};
1879c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.planeAlpha = 255;
188006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard
1881c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.visibleRegionScreen.numRects = 1;
188206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    hwc_rect_t* rects = GetRects(1);
1883c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    rects[0].left = 0;
1884c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    rects[0].top = 0;
1885c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    rects[0].right = width;
1886c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    rects[0].bottom = height;
1887c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.visibleRegionScreen.rects = rects;
1888c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1889c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // We will set this to the correct value in set
1890c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Target.acquireFenceFd = -1;
1891c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1892c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1893c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza// Layer functions
1894c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1895c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastd::atomic<hwc2_layer_t> HWC2On1Adapter::Layer::sNextId(1);
1896c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1897c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaHWC2On1Adapter::Layer::Layer(Display& display)
1898c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza  : mId(sNextId++),
1899c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDisplay(display),
1900fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    mBuffer(),
1901fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    mSurfaceDamage(),
190206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mBlendMode(BlendMode::None),
190306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mColor({0, 0, 0, 0}),
190406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mCompositionType(Composition::Invalid),
190506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mDisplayFrame({0, 0, -1, -1}),
190606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mPlaneAlpha(0.0f),
190706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mSidebandStream(nullptr),
190806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mSourceCrop({0.0f, 0.0f, -1.0f, -1.0f}),
190906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mTransform(Transform::None),
191006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mVisibleRegion(),
1911c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mZ(0),
1912fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    mReleaseFence(),
1913c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1Id(0),
191406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mHasUnsupportedPlaneAlpha(false) {}
1915c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1916c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozabool HWC2On1Adapter::SortLayersByZ::operator()(
191706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        const std::shared_ptr<Layer>& lhs, const std::shared_ptr<Layer>& rhs) {
1918c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return lhs->getZ() < rhs->getZ();
1919c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1920c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1921c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan StozaError HWC2On1Adapter::Layer::setBuffer(buffer_handle_t buffer,
192206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        int32_t acquireFence) {
1923c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("Setting acquireFence to %d for layer %" PRIu64, acquireFence, mId);
1924c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mBuffer.setBuffer(buffer);
1925c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mBuffer.setFence(acquireFence);
1926c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1927c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1928c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
192906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Layer::setCursorPosition(int32_t x, int32_t y) {
193006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    if (mCompositionType != Composition::Cursor) {
1931c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::BadLayer;
1932c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1933c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1934c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mDisplay.hasChanges()) {
1935c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return Error::NotValidated;
1936c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
1937c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1938c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto displayId = mDisplay.getHwc1Id();
1939c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto hwc1Device = mDisplay.getDevice().getHwc1Device();
1940c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Device->setCursorPositionAsync(hwc1Device, displayId, x, y);
1941c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1942c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1943c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
194406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Layer::setSurfaceDamage(hwc_region_t damage) {
1945356bcd4144e87f570fe412e2bd31b1af796b429fFabien Sanglard    // HWC1 supports surface damage starting only with version 1.5.
1946356bcd4144e87f570fe412e2bd31b1af796b429fFabien Sanglard    if (mDisplay.getDevice().mHwc1MinorVersion < 5) {
1947356bcd4144e87f570fe412e2bd31b1af796b429fFabien Sanglard        return Error::None;
1948356bcd4144e87f570fe412e2bd31b1af796b429fFabien Sanglard    }
1949c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mSurfaceDamage.resize(damage.numRects);
1950c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::copy_n(damage.rects, damage.numRects, mSurfaceDamage.begin());
1951c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1952c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1953c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
1954c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza// Layer state functions
1955c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
195606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Layer::setBlendMode(BlendMode mode) {
195706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mBlendMode = mode;
195806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mDisplay.markGeometryChanged();
1959c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1960c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1961c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
196206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Layer::setColor(hwc_color_t color) {
196306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mColor = color;
196406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mDisplay.markGeometryChanged();
1965c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1966c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1967c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
196806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Layer::setCompositionType(Composition type) {
196906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mCompositionType = type;
197006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mDisplay.markGeometryChanged();
1971c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1972c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1973c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
197406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Layer::setDataspace(android_dataspace_t) {
19755df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    return Error::None;
19765df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza}
19775df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza
197806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Layer::setDisplayFrame(hwc_rect_t frame) {
197906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mDisplayFrame = frame;
198006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mDisplay.markGeometryChanged();
1981c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1982c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1983c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
198406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Layer::setPlaneAlpha(float alpha) {
198506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mPlaneAlpha = alpha;
198606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mDisplay.markGeometryChanged();
1987c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1988c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1989c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
199006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Layer::setSidebandStream(const native_handle_t* stream) {
199106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mSidebandStream = stream;
199206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mDisplay.markGeometryChanged();
1993c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
1994c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
1995c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
199606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Layer::setSourceCrop(hwc_frect_t crop) {
199706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mSourceCrop = crop;
199806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mDisplay.markGeometryChanged();
1999c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
2000c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2001c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
200206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Layer::setTransform(Transform transform) {
200306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mTransform = transform;
200406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mDisplay.markGeometryChanged();
2005c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
2006c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2007c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
200806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Layer::setVisibleRegion(hwc_region_t visible) {
200906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mVisibleRegion.resize(visible.numRects);
201006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    std::copy_n(visible.rects, visible.numRects, mVisibleRegion.begin());
201106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mDisplay.markGeometryChanged();
2012c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
2013c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2014c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
201506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::Layer::setZ(uint32_t z) {
2016c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mZ = z;
2017c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
2018c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2019c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
202006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardvoid HWC2On1Adapter::Layer::addReleaseFence(int fenceFd) {
2021c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("addReleaseFence %d to layer %" PRIu64, fenceFd, mId);
2022c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mReleaseFence.add(fenceFd);
2023c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2024c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2025c859147db5e9d5aa8a5043c0111e2799e1db042bFabien Sanglardconst sp<MiniFence>& HWC2On1Adapter::Layer::getReleaseFence() const {
2026c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return mReleaseFence.get();
2027c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2028c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
202906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardvoid HWC2On1Adapter::Layer::applyState(hwc_layer_1_t& hwc1Layer) {
203006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    applyCommonState(hwc1Layer);
203106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    applyCompositionType(hwc1Layer);
203206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    switch (mCompositionType) {
203306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        case Composition::SolidColor : applySolidColorState(hwc1Layer); break;
203406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        case Composition::Sideband : applySidebandState(hwc1Layer); break;
203506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        default: applyBufferState(hwc1Layer); break;
2036c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2037c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2038c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2039c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastatic std::string regionStrings(const std::vector<hwc_rect_t>& visibleRegion,
204006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        const std::vector<hwc_rect_t>& surfaceDamage) {
2041c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::string regions;
2042c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    regions += "        Visible Region";
2043c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    regions.resize(40, ' ');
2044c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    regions += "Surface Damage\n";
2045c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2046c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    size_t numPrinted = 0;
2047c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    size_t maxSize = std::max(visibleRegion.size(), surfaceDamage.size());
2048c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    while (numPrinted < maxSize) {
2049c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        std::string line("        ");
2050c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (visibleRegion.empty() && numPrinted == 0) {
2051c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            line += "None";
2052c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        } else if (numPrinted < visibleRegion.size()) {
2053c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            line += rectString(visibleRegion[numPrinted]);
2054c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2055c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        line.resize(40, ' ');
2056c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (surfaceDamage.empty() && numPrinted == 0) {
2057c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            line += "None";
2058c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        } else if (numPrinted < surfaceDamage.size()) {
2059c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            line += rectString(surfaceDamage[numPrinted]);
2060c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2061c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        line += '\n';
2062c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        regions += line;
2063c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ++numPrinted;
2064c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2065c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return regions;
2066c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2067c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
206806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardstd::string HWC2On1Adapter::Layer::dump() const {
2069c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::stringstream output;
2070c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const char* fill = "      ";
2071c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
207206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    output << fill << to_string(mCompositionType);
2073c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << " Layer  HWC2/1: " << mId << "/" << mHwc1Id << "  ";
2074c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    output << "Z: " << mZ;
207506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    if (mCompositionType == HWC2::Composition::SolidColor) {
207606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        output << "  " << colorString(mColor);
207706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    } else if (mCompositionType == HWC2::Composition::Sideband) {
207806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        output << "  Handle: " << mSidebandStream << '\n';
2079c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
2080c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << "  Buffer: " << mBuffer.getBuffer() << "/" <<
2081c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mBuffer.getFence() << '\n';
2082c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << fill << "  Display frame [LTRB]: " <<
208306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard                rectString(mDisplayFrame) << '\n';
2084c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        output << fill << "  Source crop: " <<
208506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard                frectString(mSourceCrop) << '\n';
208606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        output << fill << "  Transform: " << to_string(mTransform);
208706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        output << "  Blend mode: " << to_string(mBlendMode);
208806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        if (mPlaneAlpha != 1.0f) {
2089c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            output << "  Alpha: " <<
209006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard                alphaString(mPlaneAlpha) << '\n';
2091c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        } else {
2092c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            output << '\n';
2093c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
209406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        output << regionStrings(mVisibleRegion, mSurfaceDamage);
2095c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2096c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return output.str();
2097c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2098c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
209906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardstatic int getHwc1Blending(HWC2::BlendMode blendMode) {
2100c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    switch (blendMode) {
2101c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case BlendMode::Coverage: return HWC_BLENDING_COVERAGE;
2102c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        case BlendMode::Premultiplied: return HWC_BLENDING_PREMULT;
2103c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        default: return HWC_BLENDING_NONE;
2104c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2105c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2106c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
210706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardvoid HWC2On1Adapter::Layer::applyCommonState(hwc_layer_1_t& hwc1Layer) {
2108c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto minorVersion = mDisplay.getDevice().getHwc1MinorVersion();
210906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    hwc1Layer.blending = getHwc1Blending(mBlendMode);
211006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    hwc1Layer.displayFrame = mDisplayFrame;
211106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard
211206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    auto pendingAlpha = mPlaneAlpha;
211306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    if (minorVersion < 2) {
211406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        mHasUnsupportedPlaneAlpha = pendingAlpha < 1.0f;
211506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    } else {
211606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        hwc1Layer.planeAlpha =
211706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard                static_cast<uint8_t>(255.0f * pendingAlpha + 0.5f);
211806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    }
211906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard
212006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    if (minorVersion < 3) {
212106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        auto pending = mSourceCrop;
212206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        hwc1Layer.sourceCropi.left =
212306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard                static_cast<int32_t>(std::ceil(pending.left));
212406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        hwc1Layer.sourceCropi.top =
212506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard                static_cast<int32_t>(std::ceil(pending.top));
212606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        hwc1Layer.sourceCropi.right =
212706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard                static_cast<int32_t>(std::floor(pending.right));
212806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        hwc1Layer.sourceCropi.bottom =
212906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard                static_cast<int32_t>(std::floor(pending.bottom));
213006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    } else {
213106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        hwc1Layer.sourceCropf = mSourceCrop;
2132c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2133c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
213406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    hwc1Layer.transform = static_cast<uint32_t>(mTransform);
2135c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
213606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    auto& hwc1VisibleRegion = hwc1Layer.visibleRegionScreen;
213706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    hwc1VisibleRegion.numRects = mVisibleRegion.size();
213806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    hwc_rect_t* rects = mDisplay.GetRects(hwc1VisibleRegion.numRects);
213906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    hwc1VisibleRegion.rects = rects;
214006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    for (size_t i = 0; i < mVisibleRegion.size(); i++) {
214106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        rects[i] = mVisibleRegion[i];
2142c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2143c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2144c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
214506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardvoid HWC2On1Adapter::Layer::applySolidColorState(hwc_layer_1_t& hwc1Layer) {
214606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    // If the device does not support background color it is likely to make
214706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    // assumption regarding backgroundColor and handle (both fields occupy
214806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    // the same location in hwc_layer_1_t union).
214906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    // To not confuse these devices we don't set background color and we
215006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    // make sure handle is a null pointer.
215106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    if (hasUnsupportedBackgroundColor()) {
215206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        hwc1Layer.handle = nullptr;
215306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    } else {
215406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        hwc1Layer.backgroundColor = mColor;
2155c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2156c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2157c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
215806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardvoid HWC2On1Adapter::Layer::applySidebandState(hwc_layer_1_t& hwc1Layer) {
215906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    hwc1Layer.sidebandStream = mSidebandStream;
2160c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2161c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
216206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardvoid HWC2On1Adapter::Layer::applyBufferState(hwc_layer_1_t& hwc1Layer) {
2163c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Layer.handle = mBuffer.getBuffer();
2164c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc1Layer.acquireFenceFd = mBuffer.getFence();
2165c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2166c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
216706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardvoid HWC2On1Adapter::Layer::applyCompositionType(hwc_layer_1_t& hwc1Layer) {
21685df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    // HWC1 never supports color transforms or dataspaces and only sometimes
21695df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    // supports plane alpha (depending on the version). These require us to drop
21705df2a86063c6a83813fc1aa3d8938a82f7ff8f14Dan Stoza    // some or all layers to client composition.
2171999a7fdad2a48d0517f515cc6ea6c7324aa28228Fabien Sanglard    if (mHasUnsupportedPlaneAlpha || mDisplay.hasColorTransform() ||
217206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            hasUnsupportedBackgroundColor()) {
2173c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2174c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        hwc1Layer.flags = HWC_SKIP_LAYER;
2175c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
2176c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2177c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
217806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    hwc1Layer.flags = 0;
217906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    switch (mCompositionType) {
218006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        case Composition::Client:
218106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            hwc1Layer.compositionType = HWC_FRAMEBUFFER;
218206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            hwc1Layer.flags |= HWC_SKIP_LAYER;
218306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            break;
218406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        case Composition::Device:
218506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            hwc1Layer.compositionType = HWC_FRAMEBUFFER;
218606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            break;
218706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        case Composition::SolidColor:
218806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            // In theory the following line should work, but since the HWC1
218906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            // version of SurfaceFlinger never used HWC_BACKGROUND, HWC1
219006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            // devices may not work correctly. To be on the safe side, we
219106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            // fall back to client composition.
219206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            //
219306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            // hwc1Layer.compositionType = HWC_BACKGROUND;
219406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            hwc1Layer.compositionType = HWC_FRAMEBUFFER;
219506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            hwc1Layer.flags |= HWC_SKIP_LAYER;
219606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            break;
219706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        case Composition::Cursor:
219806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            hwc1Layer.compositionType = HWC_FRAMEBUFFER;
219906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            if (mDisplay.getDevice().getHwc1MinorVersion() >= 4) {
220006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard                hwc1Layer.hints |= HWC_IS_CURSOR_LAYER;
220106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            }
220206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            break;
220306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        case Composition::Sideband:
220406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            if (mDisplay.getDevice().getHwc1MinorVersion() < 4) {
220506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard                hwc1Layer.compositionType = HWC_SIDEBAND;
220606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            } else {
2207c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwc1Layer.compositionType = HWC_FRAMEBUFFER;
2208c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                hwc1Layer.flags |= HWC_SKIP_LAYER;
220906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            }
221006e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            break;
221106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        default:
221206e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            hwc1Layer.compositionType = HWC_FRAMEBUFFER;
221306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            hwc1Layer.flags |= HWC_SKIP_LAYER;
221406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            break;
2215c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
221606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    ALOGV("Layer %" PRIu64 " %s set to %d", mId,
221706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            to_string(mCompositionType).c_str(),
221806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            hwc1Layer.compositionType);
221906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    ALOGV_IF(hwc1Layer.flags & HWC_SKIP_LAYER, "    and skipping");
2220c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2221c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2222c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza// Adapter helpers
2223c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
222406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardvoid HWC2On1Adapter::populateCapabilities() {
2225c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1MinorVersion >= 3U) {
2226c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        int supportedTypes = 0;
2227c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto result = mHwc1Device->query(mHwc1Device,
2228c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                HWC_DISPLAY_TYPES_SUPPORTED, &supportedTypes);
2229c50c01e0b8a1ef3bac59477cb9ecf946a363c9f8Fred Fettinger        if ((result == 0) && ((supportedTypes & HWC_DISPLAY_VIRTUAL_BIT) != 0)) {
2230c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGI("Found support for HWC virtual displays");
2231c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            mHwc1SupportsVirtualDisplays = true;
2232c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2233c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2234c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1MinorVersion >= 4U) {
2235c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mCapabilities.insert(Capability::SidebandStream);
2236c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2237eb3db61f914a2469fe632c48b46a0ce60c84c9d9Fabien Sanglard
2238eb3db61f914a2469fe632c48b46a0ce60c84c9d9Fabien Sanglard    // Check for HWC background color layer support.
2239eb3db61f914a2469fe632c48b46a0ce60c84c9d9Fabien Sanglard    if (mHwc1MinorVersion >= 1U) {
2240eb3db61f914a2469fe632c48b46a0ce60c84c9d9Fabien Sanglard        int backgroundColorSupported = 0;
2241eb3db61f914a2469fe632c48b46a0ce60c84c9d9Fabien Sanglard        auto result = mHwc1Device->query(mHwc1Device,
2242eb3db61f914a2469fe632c48b46a0ce60c84c9d9Fabien Sanglard                                         HWC_BACKGROUND_LAYER_SUPPORTED,
2243eb3db61f914a2469fe632c48b46a0ce60c84c9d9Fabien Sanglard                                         &backgroundColorSupported);
2244eb3db61f914a2469fe632c48b46a0ce60c84c9d9Fabien Sanglard        if ((result == 0) && (backgroundColorSupported == 1)) {
2245eb3db61f914a2469fe632c48b46a0ce60c84c9d9Fabien Sanglard            ALOGV("Found support for HWC background color");
2246eb3db61f914a2469fe632c48b46a0ce60c84c9d9Fabien Sanglard            mHwc1SupportsBackgroundColor = true;
2247eb3db61f914a2469fe632c48b46a0ce60c84c9d9Fabien Sanglard        }
2248eb3db61f914a2469fe632c48b46a0ce60c84c9d9Fabien Sanglard    }
22496b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson
22506b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    // Some devices might have HWC1 retire fences that accurately emulate
22516b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    // HWC2 present fences when they are deferred, but it's not very reliable.
22526b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    // To be safe, we indicate PresentFenceIsNotReliable for all HWC1 devices.
22536b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    mCapabilities.insert(Capability::PresentFenceIsNotReliable);
2254c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2255c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
225606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardHWC2On1Adapter::Display* HWC2On1Adapter::getDisplay(hwc2_display_t id) {
2257fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2258c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2259c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto display = mDisplays.find(id);
2260c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (display == mDisplays.end()) {
2261c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return nullptr;
2262c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2263c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2264c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return display->second.get();
2265c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2266c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2267c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stozastd::tuple<HWC2On1Adapter::Layer*, Error> HWC2On1Adapter::getLayer(
226806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        hwc2_display_t displayId, hwc2_layer_t layerId) {
2269c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto display = getDisplay(displayId);
2270c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (!display) {
2271c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadDisplay);
2272c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2273c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2274c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto layerEntry = mLayers.find(layerId);
2275c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (layerEntry == mLayers.end()) {
2276c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadLayer);
2277c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2278c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2279c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto layer = layerEntry->second;
2280c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (layer->getDisplay().getId() != displayId) {
2281c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return std::make_tuple(static_cast<Layer*>(nullptr), Error::BadLayer);
2282c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2283c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return std::make_tuple(layer.get(), Error::None);
2284c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2285c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
228606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardvoid HWC2On1Adapter::populatePrimary() {
2287fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2288c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
228906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    auto display = std::make_shared<Display>(*this, HWC2::DisplayType::Physical);
2290c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mHwc1DisplayMap[HWC_DISPLAY_PRIMARY] = display->getId();
2291c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    display->setHwc1Id(HWC_DISPLAY_PRIMARY);
2292c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    display->populateConfigs();
2293c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    mDisplays.emplace(display->getId(), std::move(display));
2294c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2295c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
229606e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardbool HWC2On1Adapter::prepareAllDisplays() {
2297c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ATRACE_CALL();
2298c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2299fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2300c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2301c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (const auto& displayPair : mDisplays) {
2302c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& display = displayPair.second;
2303c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (!display->prepare()) {
2304c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return false;
2305c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2306c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2307c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
23087382ed7f54a253b958a9d24f6d7eff2a94f47660Fabien Sanglard    if (mHwc1DisplayMap.count(HWC_DISPLAY_PRIMARY) == 0) {
2309c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("prepareAllDisplays: Unable to find primary HWC1 display");
2310c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return false;
2311c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2312c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
231306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    // Build an array of hwc_display_contents_1 to call prepare() on HWC1.
231406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mHwc1Contents.clear();
231506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard
2316c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Always push the primary display
2317c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto primaryDisplayId = mHwc1DisplayMap[HWC_DISPLAY_PRIMARY];
2318c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto& primaryDisplay = mDisplays[primaryDisplayId];
231906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    mHwc1Contents.push_back(primaryDisplay->getDisplayContents());
2320c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2321c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Push the external display, if present
2322c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1DisplayMap.count(HWC_DISPLAY_EXTERNAL) != 0) {
2323c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto externalDisplayId = mHwc1DisplayMap[HWC_DISPLAY_EXTERNAL];
2324c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& externalDisplay = mDisplays[externalDisplayId];
232506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        mHwc1Contents.push_back(externalDisplay->getDisplayContents());
2326c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
2327c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Even if an external display isn't present, we still need to send
2328c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // at least two displays down to HWC1
232906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        mHwc1Contents.push_back(nullptr);
2330c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2331c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2332c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Push the hardware virtual display, if supported and present
2333c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1MinorVersion >= 3) {
2334c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (mHwc1DisplayMap.count(HWC_DISPLAY_VIRTUAL) != 0) {
2335c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto virtualDisplayId = mHwc1DisplayMap[HWC_DISPLAY_VIRTUAL];
2336c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto& virtualDisplay = mDisplays[virtualDisplayId];
233706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            mHwc1Contents.push_back(virtualDisplay->getDisplayContents());
2338c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        } else {
233906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard            mHwc1Contents.push_back(nullptr);
2340c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2341c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2342c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
234306e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    for (auto& displayContents : mHwc1Contents) {
2344c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (!displayContents) {
2345c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            continue;
2346c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2347c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2348c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("Display %zd layers:", mHwc1Contents.size() - 1);
2349c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (size_t l = 0; l < displayContents->numHwLayers; ++l) {
2350c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            auto& layer = displayContents->hwLayers[l];
2351c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGV("  %zd: %d", l, layer.compositionType);
2352c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2353c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2354c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2355c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("Calling HWC1 prepare");
2356c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    {
2357c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ATRACE_NAME("HWC1 prepare");
2358c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHwc1Device->prepare(mHwc1Device, mHwc1Contents.size(),
2359c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mHwc1Contents.data());
2360c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2361c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2362c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t c = 0; c < mHwc1Contents.size(); ++c) {
2363c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& contents = mHwc1Contents[c];
2364c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (!contents) {
2365c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            continue;
2366c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2367c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("Display %zd layers:", c);
2368c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        for (size_t l = 0; l < contents->numHwLayers; ++l) {
2369c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGV("  %zd: %d", l, contents->hwLayers[l].compositionType);
2370c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2371c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2372c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2373c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Return the received contents to their respective displays
2374c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t hwc1Id = 0; hwc1Id < mHwc1Contents.size(); ++hwc1Id) {
2375c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (mHwc1Contents[hwc1Id] == nullptr) {
2376c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            continue;
2377c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2378c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2379c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto displayId = mHwc1DisplayMap[hwc1Id];
2380c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& display = mDisplays[displayId];
238106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard        display->generateChanges();
2382c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2383c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2384c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return true;
2385c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2386c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2387af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglardvoid dumpHWC1Message(hwc_composer_device_1* device, size_t numDisplays,
2388af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                     hwc_display_contents_1_t** displays) {
2389af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard    ALOGV("*****************************");
2390af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard    size_t displayId = 0;
2391af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard    while (displayId < numDisplays) {
2392af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard        hwc_display_contents_1_t* display = displays[displayId];
2393af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard
2394af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard        ALOGV("hwc_display_contents_1_t[%zu] @0x%p", displayId, display);
2395af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard        if (display == nullptr) {
2396af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard            displayId++;
2397af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard            continue;
2398af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard        }
2399af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard        ALOGV("  retirefd:0x%08x", display->retireFenceFd);
2400af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard        ALOGV("  outbuf  :0x%p", display->outbuf);
2401af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard        ALOGV("  outbuffd:0x%08x", display->outbufAcquireFenceFd);
2402af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard        ALOGV("  flags   :0x%08x", display->flags);
2403af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard        for(size_t layerId=0 ; layerId < display->numHwLayers ; layerId++) {
2404af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard            hwc_layer_1_t& layer = display->hwLayers[layerId];
2405af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard            ALOGV("    Layer[%zu]:", layerId);
2406af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard            ALOGV("      composition        : 0x%08x", layer.compositionType);
2407af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard            ALOGV("      hints              : 0x%08x", layer.hints);
2408af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard            ALOGV("      flags              : 0x%08x", layer.flags);
2409af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard            ALOGV("      handle             : 0x%p", layer.handle);
2410af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard            ALOGV("      transform          : 0x%08x", layer.transform);
2411af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard            ALOGV("      blending           : 0x%08x", layer.blending);
2412af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard            ALOGV("      sourceCropf        : %f, %f, %f, %f",
2413af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                  layer.sourceCropf.left,
2414af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                  layer.sourceCropf.top,
2415af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                  layer.sourceCropf.right,
2416af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                  layer.sourceCropf.bottom);
2417af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard            ALOGV("      displayFrame       : %d, %d, %d, %d",
2418af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                  layer.displayFrame.left,
2419af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                  layer.displayFrame.left,
2420af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                  layer.displayFrame.left,
2421af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                  layer.displayFrame.left);
2422af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard            hwc_region_t& visReg = layer.visibleRegionScreen;
2423af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard            ALOGV("      visibleRegionScreen: #0x%08zx[@0x%p]",
2424af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                  visReg.numRects,
2425af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                  visReg.rects);
2426af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard            for (size_t visRegId=0; visRegId < visReg.numRects ; visRegId++) {
2427af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                if (layer.visibleRegionScreen.rects == nullptr) {
2428af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                    ALOGV("        null");
2429af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                } else {
2430af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                    ALOGV("        visibleRegionScreen[%zu] %d, %d, %d, %d",
2431af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                          visRegId,
2432af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                          visReg.rects[visRegId].left,
2433af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                          visReg.rects[visRegId].top,
2434af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                          visReg.rects[visRegId].right,
2435af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                          visReg.rects[visRegId].bottom);
2436af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                }
2437af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard            }
2438af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard            ALOGV("      acquireFenceFd     : 0x%08x", layer.acquireFenceFd);
2439af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard            ALOGV("      releaseFenceFd     : 0x%08x", layer.releaseFenceFd);
2440af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard            ALOGV("      planeAlpha         : 0x%08x", layer.planeAlpha);
2441af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard            if (getMinorVersion(device) < 5)
2442af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard               continue;
2443af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard            ALOGV("      surfaceDamage      : #0x%08zx[@0x%p]",
2444af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                  layer.surfaceDamage.numRects,
2445af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                  layer.surfaceDamage.rects);
2446af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard            for (size_t sdId=0; sdId < layer.surfaceDamage.numRects ; sdId++) {
2447af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                if (layer.surfaceDamage.rects == nullptr) {
2448af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                    ALOGV("      null");
2449af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                } else {
2450af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                    ALOGV("      surfaceDamage[%zu] %d, %d, %d, %d",
2451af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                          sdId,
2452af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                          layer.surfaceDamage.rects[sdId].left,
2453af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                          layer.surfaceDamage.rects[sdId].top,
2454af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                          layer.surfaceDamage.rects[sdId].right,
2455af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                          layer.surfaceDamage.rects[sdId].bottom);
2456af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard                }
2457af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard            }
2458af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard        }
2459af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard        displayId++;
2460af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard    }
2461af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard    ALOGV("-----------------------------");
2462af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard}
2463af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard
246406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien SanglardError HWC2On1Adapter::setAllDisplays() {
2465c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ATRACE_CALL();
2466c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2467fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2468c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2469c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Make sure we're ready to validate
2470c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t hwc1Id = 0; hwc1Id < mHwc1Contents.size(); ++hwc1Id) {
2471c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (mHwc1Contents[hwc1Id] == nullptr) {
2472c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            continue;
2473c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2474c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2475c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto displayId = mHwc1DisplayMap[hwc1Id];
2476c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& display = mDisplays[displayId];
2477c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        Error error = display->set(*mHwc1Contents[hwc1Id]);
2478c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (error != Error::None) {
2479c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGE("setAllDisplays: Failed to set display %zd: %s", hwc1Id,
2480c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    to_string(error).c_str());
2481c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return error;
2482c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2483c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2484c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2485c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("Calling HWC1 set");
2486c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    {
2487c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ATRACE_NAME("HWC1 set");
2488af5b6b814119151985d27d6edde7917cfb1e8d45Fabien Sanglard        //dumpHWC1Message(mHwc1Device, mHwc1Contents.size(), mHwc1Contents.data());
2489c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHwc1Device->set(mHwc1Device, mHwc1Contents.size(),
2490c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                mHwc1Contents.data());
2491c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2492c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2493c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Add retire and release fences
2494c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (size_t hwc1Id = 0; hwc1Id < mHwc1Contents.size(); ++hwc1Id) {
2495c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (mHwc1Contents[hwc1Id] == nullptr) {
2496c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            continue;
2497c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2498c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2499c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto displayId = mHwc1DisplayMap[hwc1Id];
2500c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto& display = mDisplays[displayId];
2501c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto retireFenceFd = mHwc1Contents[hwc1Id]->retireFenceFd;
2502c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGV("setAllDisplays: Adding retire fence %d to display %zd",
2503c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                retireFenceFd, hwc1Id);
2504c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        display->addRetireFence(mHwc1Contents[hwc1Id]->retireFenceFd);
2505c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        display->addReleaseFences(*mHwc1Contents[hwc1Id]);
2506c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2507c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2508c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    return Error::None;
2509c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2510c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
251106e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardvoid HWC2On1Adapter::hwc1Invalidate() {
2512c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("Received hwc1Invalidate");
2513c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2514fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2515c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2516c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // If the HWC2-side callback hasn't been registered yet, buffer this until
251706e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    // it is registered.
2518c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mCallbacks.count(Callback::Refresh) == 0) {
2519c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHasPendingInvalidate = true;
2520c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
2521c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2522c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2523c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto& callbackInfo = mCallbacks[Callback::Refresh];
2524c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    std::vector<hwc2_display_t> displays;
2525c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (const auto& displayPair : mDisplays) {
2526c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        displays.emplace_back(displayPair.first);
2527c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2528c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
252906e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    // Call back without the state lock held.
2530c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    lock.unlock();
2531c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2532c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto refresh = reinterpret_cast<HWC2_PFN_REFRESH>(callbackInfo.pointer);
2533c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    for (auto display : displays) {
2534c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        refresh(callbackInfo.data, display);
2535c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2536c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2537c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
253806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardvoid HWC2On1Adapter::hwc1Vsync(int hwc1DisplayId, int64_t timestamp) {
2539c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("Received hwc1Vsync(%d, %" PRId64 ")", hwc1DisplayId, timestamp);
2540c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2541fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2542c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2543c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // If the HWC2-side callback hasn't been registered yet, buffer this until
254406e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    // it is registered.
2545c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mCallbacks.count(Callback::Vsync) == 0) {
2546c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mPendingVsyncs.emplace_back(hwc1DisplayId, timestamp);
2547c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
2548c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2549c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2550c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
2551c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("hwc1Vsync: Couldn't find display for HWC1 id %d", hwc1DisplayId);
2552c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
2553c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2554c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2555c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto& callbackInfo = mCallbacks[Callback::Vsync];
2556c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto displayId = mHwc1DisplayMap[hwc1DisplayId];
2557c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
255806e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglard    // Call back without the state lock held.
2559c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    lock.unlock();
2560c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2561c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto vsync = reinterpret_cast<HWC2_PFN_VSYNC>(callbackInfo.pointer);
2562c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    vsync(callbackInfo.data, displayId, timestamp);
2563c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2564c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
256506e908a69177e5b2cfe2625f58cae9da9f29e78fFabien Sanglardvoid HWC2On1Adapter::hwc1Hotplug(int hwc1DisplayId, int connected) {
2566c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    ALOGV("Received hwc1Hotplug(%d, %d)", hwc1DisplayId, connected);
2567c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2568c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (hwc1DisplayId != HWC_DISPLAY_EXTERNAL) {
2569c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        ALOGE("hwc1Hotplug: Received hotplug for non-external display");
2570c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
2571c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2572c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2573fc4e202b33d33b5e11181f09a2229d3ef7ae925aDan Stoza    std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);
2574c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2575c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // If the HWC2-side callback hasn't been registered yet, buffer this until
2576c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // it is registered
2577c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mCallbacks.count(Callback::Hotplug) == 0) {
2578c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mPendingHotplugs.emplace_back(hwc1DisplayId, connected);
2579c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        return;
2580c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2581c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2582c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hwc2_display_t displayId = UINT64_MAX;
2583c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {
2584c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (connected == 0) {
2585c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGW("hwc1Hotplug: Received disconnect for unconnected display");
2586c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return;
2587c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2588c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2589c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Create a new display on connect
2590c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        auto display = std::make_shared<HWC2On1Adapter::Display>(*this,
2591c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                HWC2::DisplayType::Physical);
2592c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        display->setHwc1Id(HWC_DISPLAY_EXTERNAL);
2593c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        display->populateConfigs();
2594c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        displayId = display->getId();
2595c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHwc1DisplayMap[HWC_DISPLAY_EXTERNAL] = displayId;
2596c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mDisplays.emplace(displayId, std::move(display));
2597c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    } else {
2598c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        if (connected != 0) {
2599c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            ALOGW("hwc1Hotplug: Received connect for previously connected "
2600c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza                    "display");
2601c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            return;
2602c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        }
2603c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2604c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        // Disconnect an existing display
2605c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        displayId = mHwc1DisplayMap[hwc1DisplayId];
2606c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mHwc1DisplayMap.erase(HWC_DISPLAY_EXTERNAL);
2607c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza        mDisplays.erase(displayId);
2608c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    }
2609c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2610c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    const auto& callbackInfo = mCallbacks[Callback::Hotplug];
2611c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2612c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    // Call back without the state lock held
2613c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    lock.unlock();
2614c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza
2615c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(callbackInfo.pointer);
2616c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    auto hwc2Connected = (connected == 0) ?
2617c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza            HWC2::Connection::Disconnected : HWC2::Connection::Connected;
2618c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza    hotplug(callbackInfo.data, displayId, static_cast<int32_t>(hwc2Connected));
2619c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza}
2620c6998d2391e6e54cf0664bb664e0fba2f2fce1daDan Stoza} // namespace android
2621