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