• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
CommandWriterBase(uint32_t initialMaxSize)57     CommandWriterBase(uint32_t initialMaxSize)
58         : mDataMaxSize(initialMaxSize)
59     {
60         mData = std::make_unique<uint32_t[]>(mDataMaxSize);
61         reset();
62     }
63 
~CommandWriterBase()64     virtual ~CommandWriterBase()
65     {
66         reset();
67     }
68 
reset()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 
getCommand(uint32_t offset)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 
writeQueue(bool * outQueueChanged,uint32_t * outCommandLength,hidl_vec<hidl_handle> * outCommandHandles)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 
getMQDescriptor()140     const MQDescriptorSync<uint32_t>* getMQDescriptor() const
141     {
142         return (mQueue) ? mQueue->getDesc() : nullptr;
143     }
144 
145     static constexpr uint16_t kSelectDisplayLength = 2;
selectDisplay(Display display)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;
selectLayer(Layer layer)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;
setError(uint32_t location,Error error)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;
setPresentOrValidateResult(uint32_t state)173     void setPresentOrValidateResult(uint32_t  state) {
174        beginCommand(IComposerClient::Command::SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT, kPresentOrValidateDisplayResultLength);
175        write(state);
176        endCommand();
177     }
178 
setChangedCompositionTypes(const std::vector<Layer> & layers,const std::vector<IComposerClient::Composition> & types)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 
setDisplayRequests(uint32_t displayRequestMask,const std::vector<Layer> & layers,const std::vector<uint32_t> & layerRequestMasks)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;
setPresentFence(int presentFence)228     void setPresentFence(int presentFence)
229     {
230         beginCommand(IComposerClient::Command::SET_PRESENT_FENCE,
231                 kSetPresentFenceLength);
232         writeFence(presentFence);
233         endCommand();
234     }
235 
setReleaseFences(const std::vector<Layer> & layers,const std::vector<int> & releaseFences)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;
setColorTransform(const float * matrix,ColorTransform hint)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 
setClientTarget(uint32_t slot,const native_handle_t * target,int acquireFence,Dataspace dataspace,const std::vector<IComposerClient::Rect> & damage)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;
setOutputBuffer(uint32_t slot,const native_handle_t * buffer,int releaseFence)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;
validateDisplay()304     void validateDisplay()
305     {
306         beginCommand(IComposerClient::Command::VALIDATE_DISPLAY,
307                 kValidateDisplayLength);
308         endCommand();
309     }
310 
311     static constexpr uint16_t kPresentOrValidateDisplayLength = 0;
presentOrvalidateDisplay()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;
acceptDisplayChanges()320     void acceptDisplayChanges()
321     {
322         beginCommand(IComposerClient::Command::ACCEPT_DISPLAY_CHANGES,
323                 kAcceptDisplayChangesLength);
324         endCommand();
325     }
326 
327     static constexpr uint16_t kPresentDisplayLength = 0;
presentDisplay()328     void presentDisplay()
329     {
330         beginCommand(IComposerClient::Command::PRESENT_DISPLAY,
331                 kPresentDisplayLength);
332         endCommand();
333     }
334 
335     static constexpr uint16_t kSetLayerCursorPositionLength = 2;
setLayerCursorPosition(int32_t x,int32_t y)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;
setLayerBuffer(uint32_t slot,const native_handle_t * buffer,int acquireFence)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 
setLayerSurfaceDamage(const std::vector<IComposerClient::Rect> & damage)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;
setLayerBlendMode(IComposerClient::BlendMode mode)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;
setLayerColor(IComposerClient::Color color)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;
setLayerCompositionType(IComposerClient::Composition type)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;
setLayerDataspace(Dataspace dataspace)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;
setLayerDisplayFrame(const IComposerClient::Rect & frame)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;
setLayerPlaneAlpha(float alpha)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;
setLayerSidebandStream(const native_handle_t * stream)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;
setLayerSourceCrop(const IComposerClient::FRect & crop)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;
setLayerTransform(Transform transform)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 
setLayerVisibleRegion(const std::vector<IComposerClient::Rect> & visible)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;
setLayerZOrder(uint32_t z)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:
beginCommand(IComposerClient::Command command,uint16_t length)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 
endCommand()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 
write(uint32_t val)512     void write(uint32_t val)
513     {
514         mData[mDataWritten++] = val;
515     }
516 
writeSigned(int32_t val)517     void writeSigned(int32_t val)
518     {
519         memcpy(&mData[mDataWritten++], &val, sizeof(val));
520     }
521 
writeFloat(float val)522     void writeFloat(float val)
523     {
524         memcpy(&mData[mDataWritten++], &val, sizeof(val));
525     }
526 
write64(uint64_t val)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 
writeRect(const IComposerClient::Rect & rect)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 
writeRegion(const std::vector<IComposerClient::Rect> & region)543     void writeRegion(const std::vector<IComposerClient::Rect>& region)
544     {
545         for (const auto& rect : region) {
546             writeRect(rect);
547         }
548     }
549 
writeFRect(const IComposerClient::FRect & rect)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 
writeColor(const IComposerClient::Color & color)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
writeHandle(const native_handle_t * handle,bool useCache)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 
writeHandle(const native_handle_t * handle)580     void writeHandle(const native_handle_t* handle)
581     {
582         writeHandle(handle, false);
583     }
584 
585     // ownership of fence is transferred
writeFence(int fence)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 
getTemporaryHandle(int numFds,int numInts)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:
growData(uint32_t grow)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:
CommandReaderBase()656     CommandReaderBase() : mDataMaxSize(0)
657     {
658         reset();
659     }
660 
setMQDescriptor(const MQDescriptorSync<uint32_t> & descriptor)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 
readQueue(uint32_t commandLength,const hidl_vec<hidl_handle> & commandHandles)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 
reset()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:
isEmpty()712     bool isEmpty() const
713     {
714         return (mDataRead >= mDataSize);
715     }
716 
beginCommand(IComposerClient::Command * outCommand,uint16_t * outLength)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 
endCommand()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 
getCommandLoc()763     uint32_t getCommandLoc() const
764     {
765         return mCommandBegin;
766     }
767 
read()768     uint32_t read()
769     {
770         return mData[mDataRead++];
771     }
772 
readSigned()773     int32_t readSigned()
774     {
775         int32_t val;
776         memcpy(&val, &mData[mDataRead++], sizeof(val));
777         return val;
778     }
779 
readFloat()780     float readFloat()
781     {
782         float val;
783         memcpy(&val, &mData[mDataRead++], sizeof(val));
784         return val;
785     }
786 
read64()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 
readColor()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
readHandle(bool * outUseCache)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 
readHandle()831     const native_handle_t* readHandle()
832     {
833         bool useCache;
834         return readHandle(&useCache);
835     }
836 
837     // ownership of fence is transferred
readFence()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
882