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