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/CommandResultPayload.h>
31 #include <aidl/android/hardware/graphics/composer3/Composition.h>
32 
33 #include <log/log.h>
34 #include <sync/sync.h>
35 
36 
37 using aidl::android::hardware::graphics::common::Dataspace;
38 
39 namespace aidl::android::hardware::graphics::composer3 {
40 
41 class ComposerClientReader {
42   public:
mDisplay(display)43     explicit ComposerClientReader(std::optional<int64_t> display = {}) : mDisplay(display) {}
44 
~ComposerClientReader()45     ~ComposerClientReader() { resetData(); }
46 
47     ComposerClientReader(ComposerClientReader&&) = default;
48 
49     ComposerClientReader(const ComposerClientReader&) = delete;
50     ComposerClientReader& operator=(const ComposerClientReader&) = delete;
51 
52     // Parse and execute commands from the command queue.  The commands are
53     // actually return values from the server and will be saved in ReturnData.
parse(std::vector<CommandResultPayload> && results)54     void parse(std::vector<CommandResultPayload>&& results) {
55         resetData();
56 
57         for (auto& result : results) {
58             switch (result.getTag()) {
59                 case CommandResultPayload::Tag::error:
60                     parseSetError(std::move(result.get<CommandResultPayload::Tag::error>()));
61                     break;
62                 case CommandResultPayload::Tag::changedCompositionTypes:
63                     parseSetChangedCompositionTypes(std::move(
64                             result.get<CommandResultPayload::Tag::changedCompositionTypes>()));
65                     break;
66                 case CommandResultPayload::Tag::displayRequest:
67                     parseSetDisplayRequests(
68                             std::move(result.get<CommandResultPayload::Tag::displayRequest>()));
69                     break;
70                 case CommandResultPayload::Tag::presentFence:
71                     parseSetPresentFence(
72                             std::move(result.get<CommandResultPayload::Tag::presentFence>()));
73                     break;
74                 case CommandResultPayload::Tag::releaseFences:
75                     parseSetReleaseFences(
76                             std::move(result.get<CommandResultPayload::Tag::releaseFences>()));
77                     break;
78                 case CommandResultPayload::Tag::presentOrValidateResult:
79                     parseSetPresentOrValidateDisplayResult(std::move(
80                             result.get<CommandResultPayload::Tag::presentOrValidateResult>()));
81                     break;
82                 case CommandResultPayload::Tag::clientTargetProperty:
83                     parseSetClientTargetProperty(std::move(
84                             result.get<CommandResultPayload::Tag::clientTargetProperty>()));
85                     break;
86                 case CommandResultPayload::Tag::displayLuts:
87                     parseSetDisplayLuts(
88                             std::move(result.get<CommandResultPayload::Tag::displayLuts>()));
89                     break;
90             }
91         }
92     }
93 
takeErrors()94     std::vector<CommandError> takeErrors() { return std::move(mErrors); }
95 
hasChanges(int64_t display,uint32_t * outNumChangedCompositionTypes,uint32_t * outNumLayerRequestMasks)96     void hasChanges(int64_t display, uint32_t* outNumChangedCompositionTypes,
97                     uint32_t* outNumLayerRequestMasks) const {
98         LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
99         auto found = mReturnData.find(display);
100         if (found == mReturnData.end()) {
101             *outNumChangedCompositionTypes = 0;
102             *outNumLayerRequestMasks = 0;
103             return;
104         }
105 
106         const ReturnData& data = found->second;
107 
108         *outNumChangedCompositionTypes = static_cast<uint32_t>(data.changedLayers.size());
109         *outNumLayerRequestMasks = static_cast<uint32_t>(data.displayRequests.layerRequests.size());
110     }
111 
112     // Get and clear saved changed composition types.
takeChangedCompositionTypes(int64_t display)113     std::vector<ChangedCompositionLayer> takeChangedCompositionTypes(int64_t display) {
114         LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
115         auto found = mReturnData.find(display);
116         if (found == mReturnData.end()) {
117             return {};
118         }
119 
120         ReturnData& data = found->second;
121         return std::move(data.changedLayers);
122     }
123 
124     // Get and clear saved display requests.
takeDisplayRequests(int64_t display)125     DisplayRequest takeDisplayRequests(int64_t display) {
126         LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
127         auto found = mReturnData.find(display);
128         if (found == mReturnData.end()) {
129             return {};
130         }
131 
132         ReturnData& data = found->second;
133         return std::move(data.displayRequests);
134     }
135 
136     // Get and clear saved release fences.
takeReleaseFences(int64_t display)137     std::vector<ReleaseFences::Layer> takeReleaseFences(int64_t display) {
138         LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
139         auto found = mReturnData.find(display);
140         if (found == mReturnData.end()) {
141             return {};
142         }
143 
144         ReturnData& data = found->second;
145         return std::move(data.releasedLayers);
146     }
147 
148     // Get and clear saved layer present fences.
takeLayerPresentFences(int64_t display)149     std::vector<PresentFence::LayerPresentFence> takeLayerPresentFences(int64_t display) {
150         LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
151         auto found = mReturnData.find(display);
152         if (found == mReturnData.end()) {
153             return {};
154         }
155 
156         ReturnData& data = found->second;
157         return std::move(data.layerPresentFences);
158     }
159 
160     // Get and clear saved present fence.
takePresentFence(int64_t display)161     ndk::ScopedFileDescriptor takePresentFence(int64_t display) {
162         LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
163         auto found = mReturnData.find(display);
164         if (found == mReturnData.end()) {
165             return {};
166         }
167 
168         ReturnData& data = found->second;
169         return std::move(data.presentFence);
170     }
171 
172     // Get what stage succeeded during PresentOrValidate: Present or Validate
takePresentOrValidateStage(int64_t display)173     std::optional<PresentOrValidate::Result> takePresentOrValidateStage(int64_t display) {
174         LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
175         auto found = mReturnData.find(display);
176         if (found == mReturnData.end()) {
177             return std::nullopt;
178         }
179         ReturnData& data = found->second;
180         return data.presentOrValidateState;
181     }
182 
183     // Get the client target properties requested by hardware composer.
takeClientTargetProperty(int64_t display)184     ClientTargetPropertyWithBrightness takeClientTargetProperty(int64_t display) {
185         LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
186         auto found = mReturnData.find(display);
187 
188         // If not found, return the default values.
189         if (found == mReturnData.end()) {
190             return ClientTargetPropertyWithBrightness{
191                     .clientTargetProperty = {common::PixelFormat::RGBA_8888, Dataspace::UNKNOWN},
192                     .brightness = 1.f,
193             };
194         }
195 
196         ReturnData& data = found->second;
197         return std::move(data.clientTargetProperty);
198     }
199 
200     // Get the lut(s) requested by hardware composer.
takeDisplayLuts(int64_t display)201     std::vector<DisplayLuts::LayerLut> takeDisplayLuts(int64_t display) {
202         LOG_ALWAYS_FATAL_IF(mDisplay && display != *mDisplay);
203         auto found = mReturnData.find(display);
204 
205         // If not found, return the empty vector
206         if (found == mReturnData.end()) {
207             return {};
208         }
209 
210         ReturnData& data = found->second;
211         return std::move(data.layerLuts);
212     }
213 
214   private:
resetData()215     void resetData() {
216         mErrors.clear();
217         mReturnData.clear();
218     }
219 
parseSetError(CommandError && error)220     void parseSetError(CommandError&& error) { mErrors.emplace_back(error); }
221 
parseSetChangedCompositionTypes(ChangedCompositionTypes && changedCompositionTypes)222     void parseSetChangedCompositionTypes(ChangedCompositionTypes&& changedCompositionTypes) {
223         LOG_ALWAYS_FATAL_IF(mDisplay && changedCompositionTypes.display != *mDisplay);
224         auto& data = mReturnData[changedCompositionTypes.display];
225         data.changedLayers = std::move(changedCompositionTypes.layers);
226     }
227 
parseSetDisplayRequests(DisplayRequest && displayRequest)228     void parseSetDisplayRequests(DisplayRequest&& displayRequest) {
229         LOG_ALWAYS_FATAL_IF(mDisplay && displayRequest.display != *mDisplay);
230         auto& data = mReturnData[displayRequest.display];
231         data.displayRequests = std::move(displayRequest);
232     }
233 
parseSetPresentFence(PresentFence && presentFence)234     void parseSetPresentFence(PresentFence&& presentFence) {
235         LOG_ALWAYS_FATAL_IF(mDisplay && presentFence.display != *mDisplay);
236         auto& data = mReturnData[presentFence.display];
237         data.presentFence = std::move(presentFence.fence);
238 
239         if (presentFence.layerPresentFences.has_value()) {
240             for (auto& optionalFence : presentFence.layerPresentFences.value()) {
241                 if (optionalFence.has_value()) {
242                     data.layerPresentFences.push_back(std::move(optionalFence.value()));
243                 }
244             }
245         }
246     }
247 
parseSetReleaseFences(ReleaseFences && releaseFences)248     void parseSetReleaseFences(ReleaseFences&& releaseFences) {
249         LOG_ALWAYS_FATAL_IF(mDisplay && releaseFences.display != *mDisplay);
250         auto& data = mReturnData[releaseFences.display];
251         data.releasedLayers = std::move(releaseFences.layers);
252     }
253 
parseSetPresentOrValidateDisplayResult(const PresentOrValidate && presentOrValidate)254     void parseSetPresentOrValidateDisplayResult(const PresentOrValidate&& presentOrValidate) {
255         LOG_ALWAYS_FATAL_IF(mDisplay && presentOrValidate.display != *mDisplay);
256         auto& data = mReturnData[presentOrValidate.display];
257         data.presentOrValidateState = std::move(presentOrValidate.result);
258     }
259 
parseSetClientTargetProperty(const ClientTargetPropertyWithBrightness && clientTargetProperty)260     void parseSetClientTargetProperty(
261             const ClientTargetPropertyWithBrightness&& clientTargetProperty) {
262         LOG_ALWAYS_FATAL_IF(mDisplay && clientTargetProperty.display != *mDisplay);
263         auto& data = mReturnData[clientTargetProperty.display];
264         data.clientTargetProperty = std::move(clientTargetProperty);
265     }
266 
parseSetDisplayLuts(DisplayLuts && displayLuts)267     void parseSetDisplayLuts(DisplayLuts&& displayLuts) {
268         LOG_ALWAYS_FATAL_IF(mDisplay && displayLuts.display != *mDisplay);
269         auto& data = mReturnData[displayLuts.display];
270         for (auto& [layerId, luts] : displayLuts.layerLuts) {
271             if (luts.pfd.get() >= 0) {
272                 data.layerLuts.push_back(
273                         {layerId, Luts{ndk::ScopedFileDescriptor(luts.pfd.release()), luts.offsets,
274                                        luts.lutProperties}});
275             }
276         }
277     }
278 
279     struct ReturnData {
280         DisplayRequest displayRequests;
281         std::vector<ChangedCompositionLayer> changedLayers;
282         ndk::ScopedFileDescriptor presentFence;
283         std::vector<PresentFence::LayerPresentFence> layerPresentFences;
284         std::vector<ReleaseFences::Layer> releasedLayers;
285         PresentOrValidate::Result presentOrValidateState;
286 
287         ClientTargetPropertyWithBrightness clientTargetProperty = {
288                 .clientTargetProperty = {common::PixelFormat::RGBA_8888, Dataspace::UNKNOWN},
289                 .brightness = 1.f,
290         };
291         std::vector<DisplayLuts::LayerLut> layerLuts;
292     };
293 
294     std::vector<CommandError> mErrors;
295     std::unordered_map<int64_t, ReturnData> mReturnData;
296     const std::optional<int64_t> mDisplay;
297 };
298 
299 }  // namespace aidl::android::hardware::graphics::composer3
300