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