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