• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <unordered_map>
23 #include <unordered_set>
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:
~ComposerClientReader()44     ~ComposerClientReader() { resetData(); }
45 
46     // Parse and execute commands from the command queue.  The commands are
47     // actually return values from the server and will be saved in ReturnData.
parse(std::vector<CommandResultPayload> && results)48     void parse(std::vector<CommandResultPayload>&& results) {
49         resetData();
50 
51         for (auto& result : results) {
52             switch (result.getTag()) {
53                 case CommandResultPayload::Tag::error:
54                     parseSetError(std::move(result.get<CommandResultPayload::Tag::error>()));
55                     break;
56                 case CommandResultPayload::Tag::changedCompositionTypes:
57                     parseSetChangedCompositionTypes(std::move(
58                             result.get<CommandResultPayload::Tag::changedCompositionTypes>()));
59                     break;
60                 case CommandResultPayload::Tag::displayRequest:
61                     parseSetDisplayRequests(
62                             std::move(result.get<CommandResultPayload::Tag::displayRequest>()));
63                     break;
64                 case CommandResultPayload::Tag::presentFence:
65                     parseSetPresentFence(
66                             std::move(result.get<CommandResultPayload::Tag::presentFence>()));
67                     break;
68                 case CommandResultPayload::Tag::releaseFences:
69                     parseSetReleaseFences(
70                             std::move(result.get<CommandResultPayload::Tag::releaseFences>()));
71                     break;
72                 case CommandResultPayload::Tag::presentOrValidateResult:
73                     parseSetPresentOrValidateDisplayResult(std::move(
74                             result.get<CommandResultPayload::Tag::presentOrValidateResult>()));
75                     break;
76                 case CommandResultPayload::Tag::clientTargetProperty:
77                     parseSetClientTargetProperty(std::move(
78                             result.get<CommandResultPayload::Tag::clientTargetProperty>()));
79                     break;
80             }
81         }
82     }
83 
takeErrors()84     std::vector<CommandError> takeErrors() { return std::move(mErrors); }
85 
hasChanges(int64_t display,uint32_t * outNumChangedCompositionTypes,uint32_t * outNumLayerRequestMasks)86     void hasChanges(int64_t display, uint32_t* outNumChangedCompositionTypes,
87                     uint32_t* outNumLayerRequestMasks) const {
88         auto found = mReturnData.find(display);
89         if (found == mReturnData.end()) {
90             *outNumChangedCompositionTypes = 0;
91             *outNumLayerRequestMasks = 0;
92             return;
93         }
94 
95         const ReturnData& data = found->second;
96 
97         *outNumChangedCompositionTypes = static_cast<uint32_t>(data.changedLayers.size());
98         *outNumLayerRequestMasks = static_cast<uint32_t>(data.displayRequests.layerRequests.size());
99     }
100 
101     // Get and clear saved changed composition types.
takeChangedCompositionTypes(int64_t display)102     std::vector<ChangedCompositionLayer> takeChangedCompositionTypes(int64_t display) {
103         auto found = mReturnData.find(display);
104         if (found == mReturnData.end()) {
105             return {};
106         }
107 
108         ReturnData& data = found->second;
109         return std::move(data.changedLayers);
110     }
111 
112     // Get and clear saved display requests.
takeDisplayRequests(int64_t display)113     DisplayRequest takeDisplayRequests(int64_t display) {
114         auto found = mReturnData.find(display);
115         if (found == mReturnData.end()) {
116             return {};
117         }
118 
119         ReturnData& data = found->second;
120         return std::move(data.displayRequests);
121     }
122 
123     // Get and clear saved release fences.
takeReleaseFences(int64_t display)124     std::vector<ReleaseFences::Layer> takeReleaseFences(int64_t display) {
125         auto found = mReturnData.find(display);
126         if (found == mReturnData.end()) {
127             return {};
128         }
129 
130         ReturnData& data = found->second;
131         return std::move(data.releasedLayers);
132     }
133 
134     // Get and clear saved present fence.
takePresentFence(int64_t display)135     ndk::ScopedFileDescriptor takePresentFence(int64_t display) {
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.presentFence);
143     }
144 
145     // Get what stage succeeded during PresentOrValidate: Present or Validate
takePresentOrValidateStage(int64_t display)146     std::optional<PresentOrValidate::Result> takePresentOrValidateStage(int64_t display) {
147         auto found = mReturnData.find(display);
148         if (found == mReturnData.end()) {
149             return std::nullopt;
150         }
151         ReturnData& data = found->second;
152         return data.presentOrValidateState;
153     }
154 
155     // Get the client target properties requested by hardware composer.
takeClientTargetProperty(int64_t display)156     ClientTargetPropertyWithBrightness takeClientTargetProperty(int64_t display) {
157         auto found = mReturnData.find(display);
158 
159         // If not found, return the default values.
160         if (found == mReturnData.end()) {
161             return ClientTargetPropertyWithBrightness{
162                     .clientTargetProperty = {common::PixelFormat::RGBA_8888, Dataspace::UNKNOWN},
163                     .brightness = 1.f,
164             };
165         }
166 
167         ReturnData& data = found->second;
168         return std::move(data.clientTargetProperty);
169     }
170 
171   private:
resetData()172     void resetData() {
173         mErrors.clear();
174         mReturnData.clear();
175     }
176 
parseSetError(CommandError && error)177     void parseSetError(CommandError&& error) { mErrors.emplace_back(error); }
178 
parseSetChangedCompositionTypes(ChangedCompositionTypes && changedCompositionTypes)179     void parseSetChangedCompositionTypes(ChangedCompositionTypes&& changedCompositionTypes) {
180         auto& data = mReturnData[changedCompositionTypes.display];
181         data.changedLayers = std::move(changedCompositionTypes.layers);
182     }
183 
parseSetDisplayRequests(DisplayRequest && displayRequest)184     void parseSetDisplayRequests(DisplayRequest&& displayRequest) {
185         auto& data = mReturnData[displayRequest.display];
186         data.displayRequests = std::move(displayRequest);
187     }
188 
parseSetPresentFence(PresentFence && presentFence)189     void parseSetPresentFence(PresentFence&& presentFence) {
190         auto& data = mReturnData[presentFence.display];
191         data.presentFence = std::move(presentFence.fence);
192     }
193 
parseSetReleaseFences(ReleaseFences && releaseFences)194     void parseSetReleaseFences(ReleaseFences&& releaseFences) {
195         auto& data = mReturnData[releaseFences.display];
196         data.releasedLayers = std::move(releaseFences.layers);
197     }
198 
parseSetPresentOrValidateDisplayResult(const PresentOrValidate && presentOrValidate)199     void parseSetPresentOrValidateDisplayResult(const PresentOrValidate&& presentOrValidate) {
200         auto& data = mReturnData[presentOrValidate.display];
201         data.presentOrValidateState = std::move(presentOrValidate.result);
202     }
203 
parseSetClientTargetProperty(const ClientTargetPropertyWithBrightness && clientTargetProperty)204     void parseSetClientTargetProperty(
205             const ClientTargetPropertyWithBrightness&& clientTargetProperty) {
206         auto& data = mReturnData[clientTargetProperty.display];
207         data.clientTargetProperty = std::move(clientTargetProperty);
208     }
209 
210     struct ReturnData {
211         DisplayRequest displayRequests;
212         std::vector<ChangedCompositionLayer> changedLayers;
213         ndk::ScopedFileDescriptor presentFence;
214         std::vector<ReleaseFences::Layer> releasedLayers;
215         PresentOrValidate::Result presentOrValidateState;
216 
217         ClientTargetPropertyWithBrightness clientTargetProperty = {
218                 .clientTargetProperty = {common::PixelFormat::RGBA_8888, Dataspace::UNKNOWN},
219                 .brightness = 1.f,
220         };
221     };
222 
223     std::vector<CommandError> mErrors;
224     std::unordered_map<int64_t, ReturnData> mReturnData;
225 };
226 
227 }  // namespace aidl::android::hardware::graphics::composer3
228