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