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