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