1 /*
2  * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
3  * Not a Contribution.
4  *
5  * Copyright (C) 2017 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifndef __QTICOMPOSERCOMMANDBUFFER_H__
21 #define __QTICOMPOSERCOMMANDBUFFER_H__
22 
23 #include <log/log.h>
24 #include <sync/sync.h>
25 #include <fmq/MessageQueue.h>
26 #include <hidl/MQDescriptor.h>
27 #include <utils/fence.h>
28 
29 #include <limits>
30 #include <algorithm>
31 #include <vector>
32 #include <string>
33 
34 namespace vendor {
35 namespace qti {
36 namespace hardware {
37 namespace display {
38 namespace composer {
39 namespace V3_0 {
40 
41 using ::android::hardware::graphics::common::V1_0::ColorTransform;
42 using ::android::hardware::graphics::common::V1_0::Dataspace;
43 using ::android::hardware::graphics::common::V1_0::Transform;
44 using ::android::hardware::graphics::composer::V2_1::Error;
45 using ::android::hardware::graphics::composer::V2_1::Display;
46 using ::android::hardware::graphics::composer::V2_1::Layer;
47 using ::android::hardware::MessageQueue;
48 using ::android::hardware::MQDescriptorSync;
49 using ::android::hardware::hidl_vec;
50 using ::android::hardware::hidl_handle;
51 
52 using CommandQueueType = MessageQueue<uint32_t, ::android::hardware::kSynchronizedReadWrite>;
53 
54 using std::shared_ptr;
55 using std::string;
56 using sdm::Fence;
57 
58 // This class helps build a command queue.  Note that all sizes/lengths are in units of uint32_t's.
59 class CommandWriter {
60  public:
CommandWriter(uint32_t initialMaxSize)61   explicit CommandWriter(uint32_t initialMaxSize) : mDataMaxSize(initialMaxSize) {
62     mData = std::make_unique<uint32_t[]>(mDataMaxSize);
63     reset();
64   }
65 
~CommandWriter()66   ~CommandWriter() { reset(); }
67 
reset()68   void reset() {
69     mDataWritten = 0;
70     mCommandEnd = 0;
71 
72     // handles in mDataHandles are owned by the caller
73     mDataHandles.clear();
74 
75     // handles in mTemporaryHandles are owned by the writer
76     for (auto handle : mTemporaryHandles) {
77       native_handle_close(handle);
78       native_handle_delete(handle);
79     }
80     mTemporaryHandles.clear();
81   }
82 
getCommand(uint32_t offset)83   IQtiComposerClient::Command getCommand(uint32_t offset) {
84     uint32_t val = (offset < mDataWritten) ? mData[offset] : 0;
85     return static_cast<IQtiComposerClient::Command>(val &
86       static_cast<uint32_t>(IQtiComposerClient::Command::OPCODE_MASK));
87   }
88 
writeQueue(bool & queueChanged,uint32_t & commandLength,hidl_vec<hidl_handle> & commandHandles)89   bool writeQueue(bool& queueChanged, uint32_t& commandLength,
90                   hidl_vec<hidl_handle>& commandHandles) {
91     if (mDataWritten == 0) {
92       queueChanged = false;
93       commandLength = 0;
94       commandHandles.setToExternal(nullptr, 0);
95       return true;
96     }
97 
98     // After data are written to the queue, it may not be read by the
99     // remote reader when
100     //
101     //  - the writer does not send them (because of other errors)
102     //  - the hwbinder transaction fails
103     //  - the reader does not read them (because of other errors)
104     //
105     // Discard the stale data here.
106     size_t staleDataSize = mQueue ? mQueue->availableToRead() : 0;
107     if (staleDataSize > 0) {
108       ALOGW("discarding stale data from message queue");
109       CommandQueueType::MemTransaction tx;
110       if (mQueue->beginRead(staleDataSize, &tx)) {
111         mQueue->commitRead(staleDataSize);
112       }
113     }
114     // write data to queue, optionally resizing it
115     if (mQueue && (mDataMaxSize <= mQueue->getQuantumCount())) {
116       if (!mQueue->write(mData.get(), mDataWritten)) {
117         ALOGE("failed to write commands to message queue");
118         return false;
119       }
120 
121       queueChanged = false;
122     } else {
123       auto newQueue = std::make_unique<CommandQueueType>(mDataMaxSize);
124       if (!newQueue->isValid() || !newQueue->write(mData.get(), mDataWritten)) {
125         ALOGE("failed to prepare a new message queue ");
126         return false;
127       }
128 
129       mQueue = std::move(newQueue);
130       queueChanged = true;
131     }
132 
133     commandLength = mDataWritten;
134     commandHandles.setToExternal(const_cast<hidl_handle*>(mDataHandles.data()),
135                                  mDataHandles.size());
136 
137     return true;
138   }
139 
getMQDescriptor()140   const MQDescriptorSync<uint32_t>* getMQDescriptor() const {
141     return (mQueue) ? mQueue->getDesc() : nullptr;
142   }
143 
144   // Commands from ::android::hardware::graphics::composer::V2_1::IComposerClient follow.
145   static constexpr uint16_t kSelectDisplayLength = 2;
selectDisplay(Display display)146   void selectDisplay(Display display) {
147     beginCommand(IQtiComposerClient::Command::SELECT_DISPLAY, kSelectDisplayLength);
148     write64(display);
149     endCommand();
150   }
151 
152   static constexpr uint16_t kSelectLayerLength = 2;
selectLayer(Layer layer)153   void selectLayer(Layer layer) {
154     beginCommand(IQtiComposerClient::Command::SELECT_LAYER, kSelectLayerLength);
155     write64(layer);
156     endCommand();
157   }
158 
159   static constexpr uint16_t kSetErrorLength = 2;
setError(uint32_t location,Error error)160   void setError(uint32_t location, Error error) {
161     beginCommand(IQtiComposerClient::Command::SET_ERROR, kSetErrorLength);
162     write(location);
163     writeSigned(static_cast<int32_t>(error));
164     endCommand();
165   }
166 
167   static constexpr uint32_t kPresentOrValidateDisplayResultLength = 1;
setPresentOrValidateResult(uint32_t state)168   void setPresentOrValidateResult(uint32_t state) {
169     beginCommand(IQtiComposerClient::Command::SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT,
170                  kPresentOrValidateDisplayResultLength);
171     write(state);
172     endCommand();
173   }
174 
setChangedCompositionTypes(const std::vector<Layer> & layers,const std::vector<IQtiComposerClient::Composition> & types)175   void setChangedCompositionTypes(const std::vector<Layer>& layers,
176                                   const std::vector<IQtiComposerClient::Composition>& types) {
177     size_t totalLayers = std::min(layers.size(), types.size());
178     size_t currentLayer = 0;
179 
180     while (currentLayer < totalLayers) {
181       size_t count = std::min(totalLayers - currentLayer, static_cast<size_t>(kMaxLength) / 3);
182 
183       beginCommand(IQtiComposerClient::Command::SET_CHANGED_COMPOSITION_TYPES, count * 3);
184       for (size_t i = 0; i < count; i++) {
185         write64(layers[currentLayer + i]);
186         writeSigned(static_cast<int32_t>(types[currentLayer + i]));
187       }
188       endCommand();
189 
190       currentLayer += count;
191     }
192   }
193 
setDisplayRequests(uint32_t displayRequestMask,const std::vector<Layer> & layers,const std::vector<uint32_t> & layerRequestMasks)194   void setDisplayRequests(uint32_t displayRequestMask, const std::vector<Layer>& layers,
195                           const std::vector<uint32_t>& layerRequestMasks) {
196     size_t totalLayers = std::min(layers.size(), layerRequestMasks.size());
197     size_t currentLayer = 0;
198 
199     while (currentLayer < totalLayers) {
200       size_t count = std::min(totalLayers - currentLayer, static_cast<size_t>(kMaxLength - 1) / 3);
201 
202       beginCommand(IQtiComposerClient::Command::SET_DISPLAY_REQUESTS, 1 + count * 3);
203       write(displayRequestMask);
204       for (size_t i = 0; i < count; i++) {
205         write64(layers[currentLayer + i]);
206         write(static_cast<int32_t>(layerRequestMasks[currentLayer + i]));
207       }
208       endCommand();
209 
210       currentLayer += count;
211     }
212   }
213 
214   static constexpr uint16_t kSetPresentFenceLength = 1;
setPresentFence(const shared_ptr<Fence> & presentFence)215   void setPresentFence(const shared_ptr<Fence> &presentFence) {
216     beginCommand(IQtiComposerClient::Command::SET_PRESENT_FENCE, kSetPresentFenceLength);
217     writeFence(presentFence);
218     endCommand();
219   }
220 
setReleaseFences(const std::vector<Layer> & layers,const std::vector<shared_ptr<Fence>> & releaseFences)221   void setReleaseFences(const std::vector<Layer>& layers,
222                         const std::vector<shared_ptr<Fence>>& releaseFences) {
223     size_t totalLayers = std::min(layers.size(), releaseFences.size());
224     size_t currentLayer = 0;
225 
226     while (currentLayer < totalLayers) {
227       size_t count = std::min(totalLayers - currentLayer, static_cast<size_t>(kMaxLength) / 3);
228 
229       beginCommand(IQtiComposerClient::Command::SET_RELEASE_FENCES, count * 3);
230       for (size_t i = 0; i < count; i++) {
231         write64(layers[currentLayer + i]);
232         writeFence(releaseFences[currentLayer + i]);
233       }
234       endCommand();
235 
236       currentLayer += count;
237     }
238   }
239 
240   static constexpr uint16_t kSetColorTransformLength = 17;
setColorTransform(const float * matrix,ColorTransform hint)241   void setColorTransform(const float* matrix, ColorTransform hint) {
242     beginCommand(IQtiComposerClient::Command::SET_COLOR_TRANSFORM, kSetColorTransformLength);
243     for (int i = 0; i < 16; i++) {
244       writeFloat(matrix[i]);
245     }
246     writeSigned(static_cast<int32_t>(hint));
247     endCommand();
248   }
249 
setClientTarget(uint32_t slot,const native_handle_t * target,const shared_ptr<Fence> & acquireFence,Dataspace dataspace,const std::vector<IQtiComposerClient::Rect> & damage)250   void setClientTarget(uint32_t slot, const native_handle_t* target,
251                        const shared_ptr<Fence>& acquireFence, Dataspace dataspace,
252                        const std::vector<IQtiComposerClient::Rect>& damage) {
253     bool doWrite = (damage.size() <= (kMaxLength - 4) / 4);
254     size_t length = 4 + ((doWrite) ? damage.size() * 4 : 0);
255 
256     beginCommand(IQtiComposerClient::Command::SET_CLIENT_TARGET, length);
257     write(slot);
258     writeHandle(target, true);
259     writeFence(acquireFence);
260     writeSigned(static_cast<int32_t>(dataspace));
261     // When there are too many rectangles in the damage region and doWrite
262     // is false, we write no rectangle at all which means the entire
263     // client target is damaged.
264     if (doWrite) {
265       writeRegion(damage);
266     }
267     endCommand();
268   }
269 
270   static constexpr uint16_t kSetOutputBufferLength = 3;
setOutputBuffer(uint32_t slot,const native_handle_t * buffer,const shared_ptr<Fence> & releaseFence)271   void setOutputBuffer(uint32_t slot, const native_handle_t* buffer,
272                        const shared_ptr<Fence>& releaseFence) {
273     beginCommand(IQtiComposerClient::Command::SET_OUTPUT_BUFFER, kSetOutputBufferLength);
274     write(slot);
275     writeHandle(buffer, true);
276     writeFence(releaseFence);
277     endCommand();
278   }
279 
280   static constexpr uint16_t kValidateDisplayLength = 0;
validateDisplay()281   void validateDisplay() {
282     beginCommand(IQtiComposerClient::Command::VALIDATE_DISPLAY, kValidateDisplayLength);
283     endCommand();
284   }
285 
286   static constexpr uint16_t kPresentOrValidateDisplayLength = 0;
presentOrvalidateDisplay()287   void presentOrvalidateDisplay() {
288     beginCommand(IQtiComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY,
289                  kPresentOrValidateDisplayLength);
290     endCommand();
291   }
292 
293   static constexpr uint16_t kAcceptDisplayChangesLength = 0;
acceptDisplayChanges()294   void acceptDisplayChanges() {
295     beginCommand(IQtiComposerClient::Command::ACCEPT_DISPLAY_CHANGES, kAcceptDisplayChangesLength);
296     endCommand();
297   }
298 
299   static constexpr uint16_t kPresentDisplayLength = 0;
presentDisplay()300   void presentDisplay() {
301     beginCommand(IQtiComposerClient::Command::PRESENT_DISPLAY, kPresentDisplayLength);
302     endCommand();
303   }
304 
305   static constexpr uint16_t kSetLayerCursorPositionLength = 2;
setLayerCursorPosition(int32_t x,int32_t y)306   void setLayerCursorPosition(int32_t x, int32_t y) {
307     beginCommand(IQtiComposerClient::Command::SET_LAYER_CURSOR_POSITION,
308                  kSetLayerCursorPositionLength);
309     writeSigned(x);
310     writeSigned(y);
311     endCommand();
312   }
313 
314   static constexpr uint16_t kSetLayerBufferLength = 3;
setLayerBuffer(uint32_t slot,const native_handle_t * buffer,const shared_ptr<Fence> & acquireFence)315   void setLayerBuffer(uint32_t slot, const native_handle_t* buffer,
316                       const shared_ptr<Fence>& acquireFence) {
317     beginCommand(IQtiComposerClient::Command::SET_LAYER_BUFFER, kSetLayerBufferLength);
318     write(slot);
319     writeHandle(buffer, true);
320     writeFence(acquireFence);
321     endCommand();
322   }
323 
setLayerSurfaceDamage(const std::vector<IQtiComposerClient::Rect> & damage)324   void setLayerSurfaceDamage(const std::vector<IQtiComposerClient::Rect>& damage) {
325     bool doWrite = (damage.size() <= kMaxLength / 4);
326     size_t length = (doWrite) ? damage.size() * 4 : 0;
327 
328     beginCommand(IQtiComposerClient::Command::SET_LAYER_SURFACE_DAMAGE, length);
329     // When there are too many rectangles in the damage region and doWrite
330     // is false, we write no rectangle at all which means the entire
331     // layer is damaged.
332     if (doWrite) {
333       writeRegion(damage);
334     }
335     endCommand();
336   }
337 
338   static constexpr uint16_t kSetLayerBlendModeLength = 1;
setLayerBlendMode(IQtiComposerClient::BlendMode mode)339   void setLayerBlendMode(IQtiComposerClient::BlendMode mode) {
340     beginCommand(IQtiComposerClient::Command::SET_LAYER_BLEND_MODE, kSetLayerBlendModeLength);
341     writeSigned(static_cast<int32_t>(mode));
342     endCommand();
343   }
344 
345   static constexpr uint16_t kSetLayerColorLength = 1;
setLayerColor(IQtiComposerClient::Color color)346   void setLayerColor(IQtiComposerClient::Color color) {
347     beginCommand(IQtiComposerClient::Command::SET_LAYER_COLOR, kSetLayerColorLength);
348     writeColor(color);
349     endCommand();
350   }
351 
352   static constexpr uint16_t kSetLayerCompositionTypeLength = 1;
setLayerCompositionType(IQtiComposerClient::Composition type)353   void setLayerCompositionType(IQtiComposerClient::Composition type) {
354     beginCommand(IQtiComposerClient::Command::SET_LAYER_COMPOSITION_TYPE,
355                  kSetLayerCompositionTypeLength);
356     writeSigned(static_cast<int32_t>(type));
357     endCommand();
358   }
359 
360   static constexpr uint16_t kSetLayerDataspaceLength = 1;
setLayerDataspace(Dataspace dataspace)361   void setLayerDataspace(Dataspace dataspace) {
362     beginCommand(IQtiComposerClient::Command::SET_LAYER_DATASPACE, kSetLayerDataspaceLength);
363     writeSigned(static_cast<int32_t>(dataspace));
364     endCommand();
365   }
366 
367   static constexpr uint16_t kSetLayerDisplayFrameLength = 4;
setLayerDisplayFrame(const IQtiComposerClient::Rect & frame)368   void setLayerDisplayFrame(const IQtiComposerClient::Rect& frame) {
369     beginCommand(IQtiComposerClient::Command::SET_LAYER_DISPLAY_FRAME, kSetLayerDisplayFrameLength);
370     writeRect(frame);
371     endCommand();
372   }
373 
374   static constexpr uint16_t kSetLayerPlaneAlphaLength = 1;
setLayerPlaneAlpha(float alpha)375   void setLayerPlaneAlpha(float alpha) {
376     beginCommand(IQtiComposerClient::Command::SET_LAYER_PLANE_ALPHA, kSetLayerPlaneAlphaLength);
377     writeFloat(alpha);
378     endCommand();
379   }
380 
381   static constexpr uint16_t kSetLayerSidebandStreamLength = 1;
setLayerSidebandStream(const native_handle_t * stream)382   void setLayerSidebandStream(const native_handle_t* stream) {
383     beginCommand(IQtiComposerClient::Command::SET_LAYER_SIDEBAND_STREAM,
384                  kSetLayerSidebandStreamLength);
385     writeHandle(stream);
386     endCommand();
387   }
388 
389   static constexpr uint16_t kSetLayerSourceCropLength = 4;
setLayerSourceCrop(const IQtiComposerClient::FRect & crop)390   void setLayerSourceCrop(const IQtiComposerClient::FRect& crop) {
391     beginCommand(IQtiComposerClient::Command::SET_LAYER_SOURCE_CROP, kSetLayerSourceCropLength);
392     writeFRect(crop);
393     endCommand();
394   }
395 
396   static constexpr uint16_t kSetLayerTransformLength = 1;
setLayerTransform(Transform transform)397   void setLayerTransform(Transform transform) {
398     beginCommand(IQtiComposerClient::Command::SET_LAYER_TRANSFORM, kSetLayerTransformLength);
399     writeSigned(static_cast<int32_t>(transform));
400     endCommand();
401   }
402 
setLayerVisibleRegion(const std::vector<IQtiComposerClient::Rect> & visible)403   void setLayerVisibleRegion(const std::vector<IQtiComposerClient::Rect>& visible) {
404     bool doWrite = (visible.size() <= kMaxLength / 4);
405     size_t length = (doWrite) ? visible.size() * 4 : 0;
406 
407     beginCommand(IQtiComposerClient::Command::SET_LAYER_VISIBLE_REGION, length);
408     // When there are too many rectangles in the visible region and
409     // doWrite is false, we write no rectangle at all which means the
410     // entire layer is visible.
411     if (doWrite) {
412       writeRegion(visible);
413     }
414     endCommand();
415   }
416 
417   static constexpr uint16_t kSetLayerZOrderLength = 1;
setLayerZOrder(uint32_t z)418   void setLayerZOrder(uint32_t z) {
419     beginCommand(IQtiComposerClient::Command::SET_LAYER_Z_ORDER, kSetLayerZOrderLength);
420     write(z);
421     endCommand();
422   }
423 
424   static constexpr uint16_t kSetLayerTypeLength = 1;
setLayerType(uint32_t z)425   void setLayerType(uint32_t z) {
426     beginCommand(IQtiComposerClient::Command::SET_LAYER_TYPE, kSetLayerTypeLength);
427     write(z);
428     endCommand();
429   }
430 
431   // Commands from ::android::hardware::graphics::composer::V2_2::IComposerClient follow.
432   static constexpr uint16_t kSetLayerFloatColorLength = 4;
setLayerFloatColor(IQtiComposerClient::FloatColor color)433   void setLayerFloatColor(IQtiComposerClient::FloatColor color) {
434     beginCommand(IQtiComposerClient::Command::SET_LAYER_FLOAT_COLOR, kSetLayerFloatColorLength);
435     writeFloatColor(color);
436     endCommand();
437   }
438 
setLayerPerFrameMetadata(const hidl_vec<IQtiComposerClient::PerFrameMetadata> & metadataVec)439   void setLayerPerFrameMetadata(const hidl_vec<IQtiComposerClient::PerFrameMetadata>& metadataVec) {
440     beginCommand(IQtiComposerClient::Command::SET_LAYER_PER_FRAME_METADATA,
441                  metadataVec.size() * 2);
442     for (const auto& metadata : metadataVec) {
443       writeSigned(static_cast<int32_t>(metadata.key));
444       writeFloat(metadata.value);
445     }
446     endCommand();
447   }
448 
449   // Commands from ::android::hardware::graphics::composer::V2_3::IComposerClient follow.
450   static constexpr uint16_t kSetLayerColorTransformLength = 16;
setLayerColorTransform(const float * matrix)451   void setLayerColorTransform(const float* matrix) {
452     beginCommand(IQtiComposerClient::Command::SET_LAYER_COLOR_TRANSFORM,
453                  kSetLayerColorTransformLength);
454     for (int i = 0; i < 16; i++) {
455       writeFloat(matrix[i]);
456     }
457     endCommand();
458   }
459 
setLayerPerFrameMetadataBlobs(const hidl_vec<IQtiComposerClient::PerFrameMetadataBlob> & metadata)460   void setLayerPerFrameMetadataBlobs(
461     const hidl_vec<IQtiComposerClient::PerFrameMetadataBlob>& metadata) {
462     size_t commandLength = 0;
463 
464     if (metadata.size() > std::numeric_limits<uint32_t>::max()) {
465       LOG_FATAL("too many metadata blobs - dynamic metadata size is too large");
466       return;
467     }
468 
469     // number of blobs
470     commandLength += metadata.size();
471 
472     for (auto metadataBlob : metadata) {
473       commandLength += sizeof(int32_t);  // key of metadata blob
474       commandLength += 1;                // size information of metadata blob
475 
476       // metadata content size
477       size_t metadataSize = metadataBlob.blob.size() / sizeof(uint32_t);
478       commandLength += metadataSize;
479       commandLength += (metadataBlob.blob.size() - (metadataSize * sizeof(uint32_t)) > 0) ? 1 : 0;
480     }
481 
482     if (commandLength > std::numeric_limits<uint16_t>::max()) {
483       LOG_FATAL("dynamic metadata size is too large");
484       return;
485     }
486 
487     // Blobs are written as:
488     // {numElements, key1, size1, blob1, key2, size2, blob2, key3, size3...}
489     uint16_t length = static_cast<uint16_t>(commandLength);
490     beginCommand(IQtiComposerClient::Command::SET_LAYER_PER_FRAME_METADATA_BLOBS, length);
491     write(static_cast<uint32_t>(metadata.size()));
492     for (auto metadataBlob : metadata) {
493       writeSigned(static_cast<int32_t>(metadataBlob.key));
494       write(static_cast<uint32_t>(metadataBlob.blob.size()));
495       writeBlob(static_cast<uint32_t>(metadataBlob.blob.size()), metadataBlob.blob.data());
496     }
497     endCommand();
498   }
499 
500   static constexpr uint16_t kSetDisplayElapseTime = 2;
setDisplayElapseTime(uint64_t time)501   void setDisplayElapseTime(uint64_t time) {
502     beginCommand(IQtiComposerClient::Command::SET_DISPLAY_ELAPSE_TIME, kSetDisplayElapseTime);
503     write64(time);
504     endCommand();
505   }
506 
507   // Commands from ::android::hardware::graphics::composer::V2_4::IComposerClient follow.
508   static constexpr uint16_t kSetClientTargetPropertyLength = 2;
setClientTargetProperty(const IQtiComposerClient::ClientTargetProperty & clientTargetProperty)509   void setClientTargetProperty(
510         const IQtiComposerClient::ClientTargetProperty& clientTargetProperty) {
511     beginCommand(IQtiComposerClient::Command::SET_CLIENT_TARGET_PROPERTY,
512                  kSetClientTargetPropertyLength);
513     writeSigned(static_cast<int32_t>(clientTargetProperty.pixelFormat));
514     writeSigned(static_cast<int32_t>(clientTargetProperty.dataspace));
515     endCommand();
516   }
517 
518  protected:
519   // Commands from ::android::hardware::graphics::composer::V2_1::IComposerClient follow.
beginCommand(IQtiComposerClient::Command command,uint16_t length)520   void beginCommand(IQtiComposerClient::Command command, uint16_t length) {
521     if (mCommandEnd) {
522       LOG_FATAL("endCommand was not called before command 0x%x", command);
523     }
524 
525     growData(1 + length);
526     write(static_cast<uint32_t>(command) | length);
527 
528     mCommandEnd = mDataWritten + length;
529   }
530 
endCommand()531   void endCommand() {
532     if (!mCommandEnd) {
533       LOG_FATAL("beginCommand was not called");
534     } else if (mDataWritten > mCommandEnd) {
535       LOG_FATAL("too much data written");
536       mDataWritten = mCommandEnd;
537     } else if (mDataWritten < mCommandEnd) {
538       LOG_FATAL("too little data written");
539       while (mDataWritten < mCommandEnd) {
540         write(0);
541       }
542     }
543 
544     mCommandEnd = 0;
545   }
546 
write(uint32_t val)547   void write(uint32_t val) { mData[mDataWritten++] = val; }
548 
writeSigned(int32_t val)549   void writeSigned(int32_t val) { memcpy(&mData[mDataWritten++], &val, sizeof(val)); }
550 
writeFloat(float val)551   void writeFloat(float val) { memcpy(&mData[mDataWritten++], &val, sizeof(val)); }
552 
write64(uint64_t val)553   void write64(uint64_t val) {
554     uint32_t lo = static_cast<uint32_t>(val & 0xffffffff);
555     uint32_t hi = static_cast<uint32_t>(val >> 32);
556     write(lo);
557     write(hi);
558   }
559 
writeRect(const IQtiComposerClient::Rect & rect)560   void writeRect(const IQtiComposerClient::Rect& rect) {
561     writeSigned(rect.left);
562     writeSigned(rect.top);
563     writeSigned(rect.right);
564     writeSigned(rect.bottom);
565   }
566 
writeRegion(const std::vector<IQtiComposerClient::Rect> & region)567   void writeRegion(const std::vector<IQtiComposerClient::Rect>& region) {
568     for (const auto& rect : region) {
569       writeRect(rect);
570     }
571   }
572 
writeFRect(const IQtiComposerClient::FRect & rect)573   void writeFRect(const IQtiComposerClient::FRect& rect) {
574     writeFloat(rect.left);
575     writeFloat(rect.top);
576     writeFloat(rect.right);
577     writeFloat(rect.bottom);
578   }
579 
writeColor(const IQtiComposerClient::Color & color)580   void writeColor(const IQtiComposerClient::Color& color) {
581     write((color.r <<  0) | (color.g <<  8) | (color.b << 16) | (color.a << 24));
582   }
583 
584   // ownership of handle is not transferred
writeHandle(const native_handle_t * handle,bool useCache)585   void writeHandle(const native_handle_t* handle, bool useCache) {
586     if (!handle) {
587       writeSigned(static_cast<int32_t>((useCache) ?
588                 IQtiComposerClient::HandleIndex::CACHED : IQtiComposerClient::HandleIndex::EMPTY));
589       return;
590     }
591 
592     mDataHandles.push_back(handle);
593     writeSigned(mDataHandles.size() - 1);
594   }
595 
writeHandle(const native_handle_t * handle)596   void writeHandle(const native_handle_t* handle) {
597     writeHandle(handle, false);
598   }
599 
600   // Handle would own fence hereafter. Hence provide a dupped fd.
writeFence(const shared_ptr<Fence> & fence)601   void writeFence(const shared_ptr<Fence>& fence) {
602     native_handle_t* handle = nullptr;
603     if (fence) {
604       handle = getTemporaryHandle(1, 0);
605       if (handle) {
606         handle->data[0] = Fence::Dup(fence);
607       } else {
608         ALOGW("failed to get temporary handle for fence %s", Fence::GetStr(fence).c_str());
609         Fence::Wait(fence);
610       }
611     }
612 
613     writeHandle(handle);
614   }
615 
getTemporaryHandle(int numFds,int numInts)616   native_handle_t* getTemporaryHandle(int numFds, int numInts) {
617     native_handle_t* handle = native_handle_create(numFds, numInts);
618     if (handle) {
619       mTemporaryHandles.push_back(handle);
620     }
621     return handle;
622   }
623 
624   static constexpr uint16_t kMaxLength = std::numeric_limits<uint16_t>::max();
625 
626   // Commands from ::android::hardware::graphics::composer::V2_2::IComposerClient follow.
writeFloatColor(const IQtiComposerClient::FloatColor & color)627   void writeFloatColor(const IQtiComposerClient::FloatColor& color) {
628     writeFloat(color.r);
629     writeFloat(color.g);
630     writeFloat(color.b);
631     writeFloat(color.a);
632   }
633 
634   // Commands from ::android::hardware::graphics::composer::V2_3::IComposerClient follow.
writeBlob(uint32_t length,const unsigned char * blob)635   void writeBlob(uint32_t length, const unsigned char* blob) {
636     memcpy(&mData[mDataWritten], blob, length);
637     uint32_t numElements = length / 4;
638     mDataWritten += numElements;
639     mDataWritten += (length - (numElements * 4) > 0) ? 1 : 0;
640   }
641 
642  private:
growData(uint32_t grow)643   void growData(uint32_t grow) {
644     uint32_t newWritten = mDataWritten + grow;
645     if (newWritten < mDataWritten) {
646       LOG_ALWAYS_FATAL("buffer overflowed; data written %" PRIu32
647                        ", growing by %" PRIu32, mDataWritten, grow);
648     }
649 
650     if (newWritten <= mDataMaxSize) {
651       return;
652     }
653 
654     uint32_t newMaxSize = mDataMaxSize << 1;
655     if (newMaxSize < newWritten) {
656       newMaxSize = newWritten;
657     }
658 
659     auto newData = std::make_unique<uint32_t[]>(newMaxSize);
660     std::copy_n(mData.get(), mDataWritten, newData.get());
661     mDataMaxSize = newMaxSize;
662     mData = std::move(newData);
663   }
664 
665   uint32_t mDataMaxSize;
666   std::unique_ptr<uint32_t[]> mData;
667 
668   uint32_t mDataWritten;
669   // end offset of the current command
670   uint32_t mCommandEnd;
671 
672   std::vector<hidl_handle> mDataHandles;
673   std::vector<native_handle_t *> mTemporaryHandles;
674 
675   std::unique_ptr<CommandQueueType> mQueue;
676 };
677 
678 // This class helps parse a command queue.  Note that all sizes/lengths are in units of uint32_t's.
679 class CommandReaderBase {
680  public:
CommandReaderBase()681   CommandReaderBase() : mDataMaxSize(0) { reset(); }
682 
setMQDescriptor(const MQDescriptorSync<uint32_t> & descriptor)683   bool setMQDescriptor(const MQDescriptorSync<uint32_t>& descriptor) {
684     mQueue = std::make_unique<CommandQueueType>(descriptor, false);
685     if (mQueue->isValid()) {
686       return true;
687     } else {
688       mQueue = nullptr;
689       return false;
690     }
691   }
692 
readQueue(uint32_t commandLength,const hidl_vec<hidl_handle> & commandHandles)693   bool readQueue(uint32_t commandLength, const hidl_vec<hidl_handle>& commandHandles) {
694     if (!mQueue) {
695       return false;
696     }
697 
698     auto quantumCount = mQueue->getQuantumCount();
699     if (mDataMaxSize < quantumCount) {
700       mDataMaxSize = quantumCount;
701       mData = std::make_unique<uint32_t[]>(mDataMaxSize);
702     }
703 
704     if (commandLength > mDataMaxSize || !mQueue->read(mData.get(), commandLength)) {
705       ALOGE("failed to read commands from message queue");
706       return false;
707     }
708 
709     mDataSize = commandLength;
710     mDataRead = 0;
711     mCommandBegin = 0;
712     mCommandEnd = 0;
713     mDataHandles.setToExternal(const_cast<hidl_handle*>(commandHandles.data()),
714                                commandHandles.size());
715 
716     return true;
717   }
718 
reset()719   void reset() {
720     mDataSize = 0;
721     mDataRead = 0;
722     mCommandBegin = 0;
723     mCommandEnd = 0;
724     mDataHandles.setToExternal(nullptr, 0);
725   }
726 
727  protected:
isEmpty()728   bool isEmpty() const { return (mDataRead >= mDataSize); }
729 
beginCommand(IQtiComposerClient::Command & command,uint16_t & length)730   bool beginCommand(IQtiComposerClient::Command& command, uint16_t& length) {
731     if (mCommandEnd) {
732       LOG_FATAL("endCommand was not called before command 0x%x", command);
733     }
734 
735     constexpr uint32_t opcode_mask =
736       static_cast<uint32_t>(IQtiComposerClient::Command::OPCODE_MASK);
737     constexpr uint32_t length_mask =
738       static_cast<uint32_t>(IQtiComposerClient::Command::LENGTH_MASK);
739 
740     uint32_t val = read();
741     command = static_cast<IQtiComposerClient::Command>(val & opcode_mask);
742     length = static_cast<uint16_t>(val & length_mask);
743 
744     if (mDataRead + length > mDataSize) {
745       ALOGE("command 0x%x has invalid command length %" PRIu16, command, length);
746       // undo the read() above
747       mDataRead--;
748       return false;
749     }
750 
751     mCommandEnd = mDataRead + length;
752 
753     return true;
754   }
755 
endCommand()756   void endCommand() {
757     if (!mCommandEnd) {
758       LOG_FATAL("beginCommand was not called");
759     } else if (mDataRead > mCommandEnd) {
760       LOG_FATAL("too much data read");
761       mDataRead = mCommandEnd;
762     } else if (mDataRead < mCommandEnd) {
763       LOG_FATAL("too little data read");
764       mDataRead = mCommandEnd;
765     }
766 
767     mCommandBegin = mCommandEnd;
768     mCommandEnd = 0;
769   }
770 
getCommandLoc()771   uint32_t getCommandLoc() const { return mCommandBegin; }
772 
read()773   uint32_t read() { return mData[mDataRead++]; }
774 
readSigned()775   int32_t readSigned() {
776     int32_t val;
777     memcpy(&val, &mData[mDataRead++], sizeof(val));
778     return val;
779   }
780 
readFloat()781   float readFloat() {
782     float val;
783     memcpy(&val, &mData[mDataRead++], sizeof(val));
784     return val;
785   }
786 
read64()787   uint64_t read64() {
788     uint32_t lo = read();
789     uint32_t hi = read();
790     return (static_cast<uint64_t>(hi) << 32) | lo;
791   }
792 
readBlob(uint32_t size,void * blob)793   void readBlob(uint32_t size, void* blob) {
794     memcpy(blob, &mData[mDataRead], size);
795     uint32_t numElements = size / sizeof(uint32_t);
796     mDataRead += numElements;
797     mDataRead += (size - numElements * sizeof(uint32_t) != 0) ? 1 : 0;
798   }
799 
readColor()800   IQtiComposerClient::Color readColor() {
801     uint32_t val = read();
802     return IQtiComposerClient::Color{
803       static_cast<uint8_t>((val >>  0) & 0xff),
804       static_cast<uint8_t>((val >>  8) & 0xff),
805       static_cast<uint8_t>((val >> 16) & 0xff),
806       static_cast<uint8_t>((val >> 24) & 0xff),
807     };
808   }
809 
810   // ownership of handle is not transferred
readHandle(bool & useCache)811   const native_handle_t* readHandle(bool& useCache) {
812     const native_handle_t* handle = nullptr;
813 
814     int32_t index = readSigned();
815     switch (index) {
816     case static_cast<int32_t>(IQtiComposerClient::HandleIndex::EMPTY):
817       useCache = false;
818       break;
819     case static_cast<int32_t>(IQtiComposerClient::HandleIndex::CACHED):
820       useCache = true;
821       break;
822     default:
823       if (static_cast<size_t>(index) < mDataHandles.size()) {
824         handle = mDataHandles[index].getNativeHandle();
825       } else {
826         ALOGE("invalid handle index %zu", static_cast<size_t>(index));
827       }
828       useCache = false;
829       break;
830     }
831 
832     return handle;
833   }
834 
readHandle()835   const native_handle_t* readHandle() {
836     bool useCache;
837     return readHandle(useCache);
838   }
839 
840   // Handle would still own original fence. Hence create a Fence object on duped fd.
readFence(shared_ptr<Fence> * fence,const string & name)841   void readFence(shared_ptr<Fence>* fence, const string &name) {
842     auto handle = readHandle();
843     if (!handle || handle->numFds == 0) {
844       return;
845     }
846 
847     if (handle->numFds != 1) {
848       ALOGE("invalid fence handle with %d fds", handle->numFds);
849       return;
850     }
851 
852     *fence = Fence::Create(dup(handle->data[0]), name);
853     if (*fence == nullptr) {
854       ALOGW("failed to dup fence %d", handle->data[0]);
855       sync_wait(handle->data[0], -1);
856     }
857   }
858 
859  private:
860   std::unique_ptr<CommandQueueType> mQueue;
861   uint32_t mDataMaxSize;
862   std::unique_ptr<uint32_t[]> mData;
863 
864   uint32_t mDataSize;
865   uint32_t mDataRead;
866 
867   // begin/end offsets of the current command
868   uint32_t mCommandBegin;
869   uint32_t mCommandEnd;
870 
871   hidl_vec<hidl_handle> mDataHandles;
872 };
873 
874 }  // namespace V3_0
875 }  // namespace composer
876 }  // namespace display
877 }  // namespace hardware
878 }  // namespace qti
879 }  // namespace vendor
880 
881 #endif  // __QTICOMPOSERCOMMANDBUFFER_H__
882