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