OSDN Git Service

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