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/common/BlendMode.h> 30 #include <aidl/android/hardware/graphics/composer3/Color.h> 31 #include <aidl/android/hardware/graphics/composer3/Composition.h> 32 #include <aidl/android/hardware/graphics/composer3/DisplayBrightness.h> 33 #include <aidl/android/hardware/graphics/composer3/LayerBrightness.h> 34 #include <aidl/android/hardware/graphics/composer3/PerFrameMetadata.h> 35 #include <aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h> 36 37 #include <aidl/android/hardware/graphics/composer3/DisplayCommand.h> 38 39 #include <aidl/android/hardware/graphics/common/ColorTransform.h> 40 #include <aidl/android/hardware/graphics/common/FRect.h> 41 #include <aidl/android/hardware/graphics/common/Rect.h> 42 #include <aidl/android/hardware/graphics/common/Transform.h> 43 44 #include <log/log.h> 45 #include <sync/sync.h> 46 47 #include <aidlcommonsupport/NativeHandle.h> 48 49 using aidl::android::hardware::graphics::common::BlendMode; 50 using aidl::android::hardware::graphics::common::ColorTransform; 51 using aidl::android::hardware::graphics::common::Dataspace; 52 using aidl::android::hardware::graphics::common::FRect; 53 using aidl::android::hardware::graphics::common::Rect; 54 using aidl::android::hardware::graphics::common::Transform; 55 56 using namespace aidl::android::hardware::graphics::composer3; 57 58 using aidl::android::hardware::common::NativeHandle; 59 60 namespace aidl::android::hardware::graphics::composer3 { 61 62 class ComposerClientWriter { 63 public: 64 static constexpr std::optional<ClockMonotonicTimestamp> kNoTimestamp = std::nullopt; 65 ComposerClientWriter()66 ComposerClientWriter() { reset(); } 67 ~ComposerClientWriter()68 virtual ~ComposerClientWriter() { reset(); } 69 reset()70 void reset() { 71 mDisplayCommand.reset(); 72 mLayerCommand.reset(); 73 mCommands.clear(); 74 } 75 setColorTransform(int64_t display,const float * matrix)76 void setColorTransform(int64_t display, const float* matrix) { 77 std::vector<float> matVec; 78 matVec.reserve(16); 79 matVec.assign(matrix, matrix + 16); 80 getDisplayCommand(display).colorTransformMatrix.emplace(std::move(matVec)); 81 } 82 setDisplayBrightness(int64_t display,float brightness,float brightnessNits)83 void setDisplayBrightness(int64_t display, float brightness, float brightnessNits) { 84 getDisplayCommand(display).brightness.emplace( 85 DisplayBrightness{.brightness = brightness, .brightnessNits = brightnessNits}); 86 } 87 setClientTarget(int64_t display,uint32_t slot,const native_handle_t * target,int acquireFence,Dataspace dataspace,const std::vector<Rect> & damage)88 void setClientTarget(int64_t display, uint32_t slot, const native_handle_t* target, 89 int acquireFence, Dataspace dataspace, const std::vector<Rect>& damage) { 90 ClientTarget clientTargetCommand; 91 clientTargetCommand.buffer = getBuffer(slot, target, acquireFence); 92 clientTargetCommand.dataspace = dataspace; 93 clientTargetCommand.damage.assign(damage.begin(), damage.end()); 94 getDisplayCommand(display).clientTarget.emplace(std::move(clientTargetCommand)); 95 } 96 setOutputBuffer(int64_t display,uint32_t slot,const native_handle_t * buffer,int releaseFence)97 void setOutputBuffer(int64_t display, uint32_t slot, const native_handle_t* buffer, 98 int releaseFence) { 99 getDisplayCommand(display).virtualDisplayOutputBuffer.emplace( 100 getBuffer(slot, buffer, releaseFence)); 101 } 102 validateDisplay(int64_t display,std::optional<ClockMonotonicTimestamp> expectedPresentTime)103 void validateDisplay(int64_t display, 104 std::optional<ClockMonotonicTimestamp> expectedPresentTime) { 105 auto& command = getDisplayCommand(display); 106 command.expectedPresentTime = expectedPresentTime; 107 command.validateDisplay = true; 108 } 109 presentOrvalidateDisplay(int64_t display,std::optional<ClockMonotonicTimestamp> expectedPresentTime)110 void presentOrvalidateDisplay(int64_t display, 111 std::optional<ClockMonotonicTimestamp> expectedPresentTime) { 112 auto& command = getDisplayCommand(display); 113 command.expectedPresentTime = expectedPresentTime; 114 command.presentOrValidateDisplay = true; 115 } 116 acceptDisplayChanges(int64_t display)117 void acceptDisplayChanges(int64_t display) { 118 getDisplayCommand(display).acceptDisplayChanges = true; 119 } 120 presentDisplay(int64_t display)121 void presentDisplay(int64_t display) { getDisplayCommand(display).presentDisplay = true; } 122 setLayerCursorPosition(int64_t display,int64_t layer,int32_t x,int32_t y)123 void setLayerCursorPosition(int64_t display, int64_t layer, int32_t x, int32_t y) { 124 common::Point cursorPosition; 125 cursorPosition.x = x; 126 cursorPosition.y = y; 127 getLayerCommand(display, layer).cursorPosition.emplace(std::move(cursorPosition)); 128 } 129 setLayerBuffer(int64_t display,int64_t layer,uint32_t slot,const native_handle_t * buffer,int acquireFence)130 void setLayerBuffer(int64_t display, int64_t layer, uint32_t slot, 131 const native_handle_t* buffer, int acquireFence) { 132 getLayerCommand(display, layer).buffer = getBuffer(slot, buffer, acquireFence); 133 } 134 setLayerSurfaceDamage(int64_t display,int64_t layer,const std::vector<Rect> & damage)135 void setLayerSurfaceDamage(int64_t display, int64_t layer, const std::vector<Rect>& damage) { 136 getLayerCommand(display, layer).damage.emplace(damage.begin(), damage.end()); 137 } 138 setLayerBlendMode(int64_t display,int64_t layer,BlendMode mode)139 void setLayerBlendMode(int64_t display, int64_t layer, BlendMode mode) { 140 ParcelableBlendMode parcelableBlendMode; 141 parcelableBlendMode.blendMode = mode; 142 getLayerCommand(display, layer).blendMode.emplace(std::move(parcelableBlendMode)); 143 } 144 setLayerColor(int64_t display,int64_t layer,Color color)145 void setLayerColor(int64_t display, int64_t layer, Color color) { 146 getLayerCommand(display, layer).color.emplace(std::move(color)); 147 } 148 setLayerCompositionType(int64_t display,int64_t layer,Composition type)149 void setLayerCompositionType(int64_t display, int64_t layer, Composition type) { 150 ParcelableComposition compositionPayload; 151 compositionPayload.composition = type; 152 getLayerCommand(display, layer).composition.emplace(std::move(compositionPayload)); 153 } 154 setLayerDataspace(int64_t display,int64_t layer,Dataspace dataspace)155 void setLayerDataspace(int64_t display, int64_t layer, Dataspace dataspace) { 156 ParcelableDataspace dataspacePayload; 157 dataspacePayload.dataspace = dataspace; 158 getLayerCommand(display, layer).dataspace.emplace(std::move(dataspacePayload)); 159 } 160 setLayerDisplayFrame(int64_t display,int64_t layer,const Rect & frame)161 void setLayerDisplayFrame(int64_t display, int64_t layer, const Rect& frame) { 162 getLayerCommand(display, layer).displayFrame.emplace(frame); 163 } 164 setLayerPlaneAlpha(int64_t display,int64_t layer,float alpha)165 void setLayerPlaneAlpha(int64_t display, int64_t layer, float alpha) { 166 PlaneAlpha planeAlpha; 167 planeAlpha.alpha = alpha; 168 getLayerCommand(display, layer).planeAlpha.emplace(std::move(planeAlpha)); 169 } 170 setLayerSidebandStream(int64_t display,int64_t layer,const native_handle_t * stream)171 void setLayerSidebandStream(int64_t display, int64_t layer, const native_handle_t* stream) { 172 NativeHandle handle; 173 if (stream) handle = ::android::dupToAidl(stream); 174 getLayerCommand(display, layer).sidebandStream.emplace(std::move(handle)); 175 } 176 setLayerSourceCrop(int64_t display,int64_t layer,const FRect & crop)177 void setLayerSourceCrop(int64_t display, int64_t layer, const FRect& crop) { 178 getLayerCommand(display, layer).sourceCrop.emplace(crop); 179 } 180 setLayerTransform(int64_t display,int64_t layer,Transform transform)181 void setLayerTransform(int64_t display, int64_t layer, Transform transform) { 182 ParcelableTransform transformPayload; 183 transformPayload.transform = transform; 184 getLayerCommand(display, layer).transform.emplace(std::move(transformPayload)); 185 } 186 setLayerVisibleRegion(int64_t display,int64_t layer,const std::vector<Rect> & visible)187 void setLayerVisibleRegion(int64_t display, int64_t layer, const std::vector<Rect>& visible) { 188 getLayerCommand(display, layer).visibleRegion.emplace(visible.begin(), visible.end()); 189 } 190 setLayerZOrder(int64_t display,int64_t layer,uint32_t z)191 void setLayerZOrder(int64_t display, int64_t layer, uint32_t z) { 192 ZOrder zorder; 193 zorder.z = static_cast<int32_t>(z); 194 getLayerCommand(display, layer).z.emplace(std::move(zorder)); 195 } 196 setLayerPerFrameMetadata(int64_t display,int64_t layer,const std::vector<PerFrameMetadata> & metadataVec)197 void setLayerPerFrameMetadata(int64_t display, int64_t layer, 198 const std::vector<PerFrameMetadata>& metadataVec) { 199 getLayerCommand(display, layer) 200 .perFrameMetadata.emplace(metadataVec.begin(), metadataVec.end()); 201 } 202 setLayerColorTransform(int64_t display,int64_t layer,const float * matrix)203 void setLayerColorTransform(int64_t display, int64_t layer, const float* matrix) { 204 getLayerCommand(display, layer).colorTransform.emplace(matrix, matrix + 16); 205 } 206 setLayerPerFrameMetadataBlobs(int64_t display,int64_t layer,const std::vector<PerFrameMetadataBlob> & metadata)207 void setLayerPerFrameMetadataBlobs(int64_t display, int64_t layer, 208 const std::vector<PerFrameMetadataBlob>& metadata) { 209 getLayerCommand(display, layer) 210 .perFrameMetadataBlob.emplace(metadata.begin(), metadata.end()); 211 } 212 setLayerBrightness(int64_t display,int64_t layer,float brightness)213 void setLayerBrightness(int64_t display, int64_t layer, float brightness) { 214 getLayerCommand(display, layer) 215 .brightness.emplace(LayerBrightness{.brightness = brightness}); 216 } 217 setLayerBlockingRegion(int64_t display,int64_t layer,const std::vector<Rect> & blocking)218 void setLayerBlockingRegion(int64_t display, int64_t layer, const std::vector<Rect>& blocking) { 219 getLayerCommand(display, layer).blockingRegion.emplace(blocking.begin(), blocking.end()); 220 } 221 getPendingCommands()222 const std::vector<DisplayCommand>& getPendingCommands() { 223 flushLayerCommand(); 224 flushDisplayCommand(); 225 return mCommands; 226 } 227 228 private: 229 std::optional<DisplayCommand> mDisplayCommand; 230 std::optional<LayerCommand> mLayerCommand; 231 std::vector<DisplayCommand> mCommands; 232 getBuffer(uint32_t slot,const native_handle_t * bufferHandle,int fence)233 Buffer getBuffer(uint32_t slot, const native_handle_t* bufferHandle, int fence) { 234 Buffer bufferCommand; 235 bufferCommand.slot = static_cast<int32_t>(slot); 236 if (bufferHandle) bufferCommand.handle.emplace(::android::dupToAidl(bufferHandle)); 237 if (fence > 0) bufferCommand.fence = ::ndk::ScopedFileDescriptor(fence); 238 return bufferCommand; 239 } 240 flushLayerCommand()241 void flushLayerCommand() { 242 if (mLayerCommand.has_value()) { 243 mDisplayCommand->layers.emplace_back(std::move(*mLayerCommand)); 244 mLayerCommand.reset(); 245 } 246 } 247 flushDisplayCommand()248 void flushDisplayCommand() { 249 if (mDisplayCommand.has_value()) { 250 mCommands.emplace_back(std::move(*mDisplayCommand)); 251 mDisplayCommand.reset(); 252 } 253 } 254 getDisplayCommand(int64_t display)255 DisplayCommand& getDisplayCommand(int64_t display) { 256 if (!mDisplayCommand.has_value() || mDisplayCommand->display != display) { 257 flushLayerCommand(); 258 flushDisplayCommand(); 259 mDisplayCommand.emplace(); 260 mDisplayCommand->display = display; 261 } 262 return *mDisplayCommand; 263 } 264 getLayerCommand(int64_t display,int64_t layer)265 LayerCommand& getLayerCommand(int64_t display, int64_t layer) { 266 getDisplayCommand(display); 267 if (!mLayerCommand.has_value() || mLayerCommand->layer != layer) { 268 flushLayerCommand(); 269 mLayerCommand.emplace(); 270 mLayerCommand->layer = layer; 271 } 272 return *mLayerCommand; 273 } 274 }; 275 276 } // namespace aidl::android::hardware::graphics::composer3 277