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