1 /*
2  * Copyright 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <algorithm>
20 #include <limits>
21 #include <memory>
22 #include <optional>
23 #include <unordered_map>
24 #include <vector>
25 
26 #include <inttypes.h>
27 #include <string.h>
28 
29 #include <aidl/android/hardware/graphics/composer3/ClientTargetProperty.h>
30 #include <aidl/android/hardware/graphics/composer3/Composition.h>
31 #include <aidl/android/hardware/graphics/composer3/CommandResultPayload.h>
32 
33 
34 #include <log/log.h>
35 #include <sync/sync.h>
36 
37 
38 using aidl::android::hardware::graphics::common::Dataspace;
39 
40 namespace aidl::android::hardware::graphics::composer3 {
41 
42 class ComposerClientReader {
43   public:
mDisplay(display)44     explicit ComposerClientReader(std::optional<int64_t> display = {}) : mDisplay(display) {}
45 
~ComposerClientReader()46     ~ComposerClientReader() { resetData(); }
47 
48     ComposerClientReader(ComposerClientReader&&) = default;
49 
50     ComposerClientReader(const ComposerClientReader&) = delete;
51     ComposerClientReader& operator=(const ComposerClientReader&) = delete;
52 
53     // Parse and execute commands from the command queue.  The commands are
54     // actually return values from the server and will be saved in ReturnData.
parse(std::vector<CommandResultPayload> && results)55     void parse(std::vector<CommandResultPayload>&& results) {
56         resetData();
57 
58         for (auto& result : results) {
59             switch (result.getTag()) {
60                 case CommandResultPayload::Tag::error:
61                     parseSetError(std::move(result.get<CommandResultPayload::Tag::error>()));
62                     break;
63                 case CommandResultPayload::Tag::changedCompositionTypes:
64                     parseSetChangedCompositionTypes(std::move(
65                             result.get<CommandResultPayload::Tag::changedCompositionTypes>()));
66                     break;
67                 case CommandResultPayload::Tag::displayRequest:
68                     parseSetDisplayRequests(
69                             std::move(result.get<CommandResultPayload::Tag::displayRequest>()));
70                     break;
71                 case CommandResultPayload::Tag::presentFence:
72                     parseSetPresentFence(
73                             std::move(result.get<CommandResultPayload::Tag::presentFence>()));
74                     break;
75                 case CommandResultPayload::Tag::releaseFences:
76                     parseSetReleaseFences(
77                             std::move(result.get<CommandResultPayload::Tag::releaseFences>()));
78                     break;
79                 case CommandResultPayload::Tag::presentOrValidateResult:
80                     parseSetPresentOrValidateDisplayResult(std::move(
81                             result.get<CommandResultPayload::Tag::presentOrValidateResult>()));
82                     break;
83                 case CommandResultPayload::Tag::clientTargetProperty:
84                     parseSetClientTargetProperty(std::move(
85                             result.get<CommandResultPayload::Tag::clientTargetProperty>()));
86                     break;
87             }
88         }
89     }
90 
takeErrors()91     std::vector<CommandError> takeErrors() { return std::move(mErrors); }
92 
hasChanges(int64_t display,uint32_t * outNumChangedCompositionTypes,uint32_t * outNumLayerRequestMasks)93     void hasChanges(int64_t display, uint32_t* outNumChangedCompositionTypes,
94                     uint32_t* outNumLayerRequestMasks) const {
95         LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
96         auto found = mReturnData.find(display);
97         if (found == mReturnData.end()) {
98             *outNumChangedCompositionTypes = 0;
99             *outNumLayerRequestMasks = 0;
100             return;
101         }
102 
103         const ReturnData& data = found->second;
104 
105         *outNumChangedCompositionTypes = static_cast<uint32_t>(data.changedLayers.size());
106         *outNumLayerRequestMasks = static_cast<uint32_t>(data.displayRequests.layerRequests.size());
107     }
108 
109     // Get and clear saved changed composition types.
takeChangedCompositionTypes(int64_t display)110     std::vector<ChangedCompositionLayer> takeChangedCompositionTypes(int64_t display) {
111         LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
112         auto found = mReturnData.find(display);
113         if (found == mReturnData.end()) {
114             return {};
115         }
116 
117         ReturnData& data = found->second;
118         return std::move(data.changedLayers);
119     }
120 
121     // Get and clear saved display requests.
takeDisplayRequests(int64_t display)122     DisplayRequest takeDisplayRequests(int64_t display) {
123         LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
124         auto found = mReturnData.find(display);
125         if (found == mReturnData.end()) {
126             return {};
127         }
128 
129         ReturnData& data = found->second;
130         return std::move(data.displayRequests);
131     }
132 
133     // Get and clear saved release fences.
takeReleaseFences(int64_t display)134     std::vector<ReleaseFences::Layer> takeReleaseFences(int64_t display) {
135         LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
136         auto found = mReturnData.find(display);
137         if (found == mReturnData.end()) {
138             return {};
139         }
140 
141         ReturnData& data = found->second;
142         return std::move(data.releasedLayers);
143     }
144 
145     // Get and clear saved present fence.
takePresentFence(int64_t display)146     ndk::ScopedFileDescriptor takePresentFence(int64_t display) {
147         LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
148         auto found = mReturnData.find(display);
149         if (found == mReturnData.end()) {
150             return {};
151         }
152 
153         ReturnData& data = found->second;
154         return std::move(data.presentFence);
155     }
156 
157     // Get what stage succeeded during PresentOrValidate: Present or Validate
takePresentOrValidateStage(int64_t display)158     std::optional<PresentOrValidate::Result> takePresentOrValidateStage(int64_t display) {
159         LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
160         auto found = mReturnData.find(display);
161         if (found == mReturnData.end()) {
162             return std::nullopt;
163         }
164         ReturnData& data = found->second;
165         return data.presentOrValidateState;
166     }
167 
168     // Get the client target properties requested by hardware composer.
takeClientTargetProperty(int64_t display)169     ClientTargetPropertyWithBrightness takeClientTargetProperty(int64_t display) {
170         LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
171         auto found = mReturnData.find(display);
172 
173         // If not found, return the default values.
174         if (found == mReturnData.end()) {
175             return ClientTargetPropertyWithBrightness{
176                     .clientTargetProperty = {common::PixelFormat::RGBA_8888, Dataspace::UNKNOWN},
177                     .brightness = 1.f,
178             };
179         }
180 
181         ReturnData& data = found->second;
182         return std::move(data.clientTargetProperty);
183     }
184 
185   private:
resetData()186     void resetData() {
187         mErrors.clear();
188         mReturnData.clear();
189     }
190 
parseSetError(CommandError && error)191     void parseSetError(CommandError&& error) { mErrors.emplace_back(error); }
192 
parseSetChangedCompositionTypes(ChangedCompositionTypes && changedCompositionTypes)193     void parseSetChangedCompositionTypes(ChangedCompositionTypes&& changedCompositionTypes) {
194         LOG_ALWAYS_FATAL_IF(mDisplay && changedCompositionTypes.display != *mDisplay);
195         auto& data = mReturnData[changedCompositionTypes.display];
196         data.changedLayers = std::move(changedCompositionTypes.layers);
197     }
198 
parseSetDisplayRequests(DisplayRequest && displayRequest)199     void parseSetDisplayRequests(DisplayRequest&& displayRequest) {
200         LOG_ALWAYS_FATAL_IF(mDisplay && displayRequest.display != *mDisplay);
201         auto& data = mReturnData[displayRequest.display];
202         data.displayRequests = std::move(displayRequest);
203     }
204 
parseSetPresentFence(PresentFence && presentFence)205     void parseSetPresentFence(PresentFence&& presentFence) {
206         LOG_ALWAYS_FATAL_IF(mDisplay && presentFence.display != *mDisplay);
207         auto& data = mReturnData[presentFence.display];
208         data.presentFence = std::move(presentFence.fence);
209     }
210 
parseSetReleaseFences(ReleaseFences && releaseFences)211     void parseSetReleaseFences(ReleaseFences&& releaseFences) {
212         LOG_ALWAYS_FATAL_IF(mDisplay && releaseFences.display != *mDisplay);
213         auto& data = mReturnData[releaseFences.display];
214         data.releasedLayers = std::move(releaseFences.layers);
215     }
216 
parseSetPresentOrValidateDisplayResult(const PresentOrValidate && presentOrValidate)217     void parseSetPresentOrValidateDisplayResult(const PresentOrValidate&& presentOrValidate) {
218         LOG_ALWAYS_FATAL_IF(mDisplay && presentOrValidate.display != *mDisplay);
219         auto& data = mReturnData[presentOrValidate.display];
220         data.presentOrValidateState = std::move(presentOrValidate.result);
221     }
222 
parseSetClientTargetProperty(const ClientTargetPropertyWithBrightness && clientTargetProperty)223     void parseSetClientTargetProperty(
224             const ClientTargetPropertyWithBrightness&& clientTargetProperty) {
225         LOG_ALWAYS_FATAL_IF(mDisplay && clientTargetProperty.display != *mDisplay);
226         auto& data = mReturnData[clientTargetProperty.display];
227         data.clientTargetProperty = std::move(clientTargetProperty);
228     }
229 
230     struct ReturnData {
231         DisplayRequest displayRequests;
232         std::vector<ChangedCompositionLayer> changedLayers;
233         ndk::ScopedFileDescriptor presentFence;
234         std::vector<ReleaseFences::Layer> releasedLayers;
235         PresentOrValidate::Result presentOrValidateState;
236 
237         ClientTargetPropertyWithBrightness clientTargetProperty = {
238                 .clientTargetProperty = {common::PixelFormat::RGBA_8888, Dataspace::UNKNOWN},
239                 .brightness = 1.f,
240         };
241     };
242 
243     std::vector<CommandError> mErrors;
244     std::unordered_map<int64_t, ReturnData> mReturnData;
245     const std::optional<int64_t> mDisplay;
246 };
247 
248 }  // namespace aidl::android::hardware::graphics::composer3
249