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