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