blob: 9ee5f4f88dd3e993e729161d12b27924bb85287f [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>
Hridya Valsaraju89b5e6b2016-12-20 07:25:43 -080038#include <fmq/MessageQueue.h>
Chia-I Wubb61a722016-10-24 15:40:20 +080039
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.
Daniel Nicoarabd82b812017-01-17 11:15:26 -050055class CommandWriterBase {
Chia-I Wubb61a722016-10-24 15:40:20 +080056public:
Daniel Nicoarabd82b812017-01-17 11:15:26 -050057 CommandWriterBase(uint32_t initialMaxSize)
Chia-I Wubb61a722016-10-24 15:40:20 +080058 : mDataMaxSize(initialMaxSize)
59 {
60 mData = std::make_unique<uint32_t[]>(mDataMaxSize);
61 reset();
62 }
63
Daniel Nicoarabd82b812017-01-17 11:15:26 -050064 virtual ~CommandWriterBase()
Chia-I Wubb61a722016-10-24 15:40:20 +080065 {
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
Chia-I Wue1768352016-12-19 12:56:54 +080092 bool writeQueue(bool* outQueueChanged, uint32_t* outCommandLength,
93 hidl_vec<hidl_handle>* outCommandHandles)
Chia-I Wubb61a722016-10-24 15:40:20 +080094 {
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
Chia-I Wue1768352016-12-19 12:56:54 +0800102 *outQueueChanged = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800103 } 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);
Chia-I Wue1768352016-12-19 12:56:54 +0800112 *outQueueChanged = true;
Chia-I Wubb61a722016-10-24 15:40:20 +0800113 }
114
Chia-I Wue1768352016-12-19 12:56:54 +0800115 *outCommandLength = mDataWritten;
116 outCommandHandles->setToExternal(
Chia-I Wubb61a722016-10-24 15:40:20 +0800117 const_cast<hidl_handle*>(mDataHandles.data()),
118 mDataHandles.size());
119
120 return true;
121 }
122
Hridya Valsaraju33351da2016-12-27 12:40:01 -0800123 const MQDescriptorSync<uint32_t>* getMQDescriptor() const
Chia-I Wubb61a722016-10-24 15:40:20 +0800124 {
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
Fabien Sanglard11ec3932017-06-19 19:25:31 -0700155 static constexpr uint32_t kPresentOrValidateDisplayResultLength = 1;
156 void setPresentOrValidateResult(uint32_t state) {
157 beginCommand(IComposerClient::Command::SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT, kPresentOrValidateDisplayResultLength);
158 write(state);
159 endCommand();
160 }
161
Chia-I Wubb61a722016-10-24 15:40:20 +0800162 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
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;
211 void setPresentFence(int presentFence)
212 {
213 beginCommand(IComposerClient::Command::SET_PRESENT_FENCE,
214 kSetPresentFenceLength);
215 writeFence(presentFence);
216 endCommand();
217 }
218
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;
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
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;
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;
287 void validateDisplay()
288 {
289 beginCommand(IComposerClient::Command::VALIDATE_DISPLAY,
290 kValidateDisplayLength);
291 endCommand();
292 }
293
Fabien Sanglard11ec3932017-06-19 19:25:31 -0700294 static constexpr uint16_t kPresentOrValidateDisplayLength = 0;
295 void presentOrvalidateDisplay()
296 {
297 beginCommand(IComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY,
298 kPresentOrValidateDisplayLength);
299 endCommand();
300 }
301
Chia-I Wubb61a722016-10-24 15:40:20 +0800302 static constexpr uint16_t kAcceptDisplayChangesLength = 0;
303 void acceptDisplayChanges()
304 {
305 beginCommand(IComposerClient::Command::ACCEPT_DISPLAY_CHANGES,
306 kAcceptDisplayChangesLength);
307 endCommand();
308 }
309
310 static constexpr uint16_t kPresentDisplayLength = 0;
311 void presentDisplay()
312 {
313 beginCommand(IComposerClient::Command::PRESENT_DISPLAY,
314 kPresentDisplayLength);
315 endCommand();
316 }
317
318 static constexpr uint16_t kSetLayerCursorPositionLength = 2;
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;
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
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;
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;
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;
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;
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;
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;
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;
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;
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;
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
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;
456 void setLayerZOrder(uint32_t z)
457 {
458 beginCommand(IComposerClient::Command::SET_LAYER_Z_ORDER,
459 kSetLayerZOrderLength);
460 write(z);
461 endCommand();
462 }
463
464protected:
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
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
495 void write(uint32_t val)
496 {
497 mData[mDataWritten++] = val;
498 }
499
500 void writeSigned(int32_t val)
501 {
502 memcpy(&mData[mDataWritten++], &val, sizeof(val));
503 }
504
505 void writeFloat(float val)
506 {
507 memcpy(&mData[mDataWritten++], &val, sizeof(val));
508 }
509
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
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
526 void writeRegion(const std::vector<IComposerClient::Rect>& region)
527 {
528 for (const auto& rect : region) {
529 writeRect(rect);
530 }
531 }
532
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
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
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
563 void writeHandle(const native_handle_t* handle)
564 {
565 writeHandle(handle, false);
566 }
567
568 // ownership of fence is transferred
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
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
598private:
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.
637class CommandReaderBase {
638public:
639 CommandReaderBase() : mDataMaxSize(0)
640 {
641 reset();
642 }
643
Hridya Valsaraju33351da2016-12-27 12:40:01 -0800644 bool setMQDescriptor(const MQDescriptorSync<uint32_t>& descriptor)
Chia-I Wubb61a722016-10-24 15:40:20 +0800645 {
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
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
685 void reset()
686 {
687 mDataSize = 0;
688 mDataRead = 0;
689 mCommandBegin = 0;
690 mCommandEnd = 0;
691 mDataHandles.setToExternal(nullptr, 0);
692 }
693
694protected:
695 bool isEmpty() const
696 {
697 return (mDataRead >= mDataSize);
698 }
699
Chia-I Wue1768352016-12-19 12:56:54 +0800700 bool beginCommand(IComposerClient::Command* outCommand,
701 uint16_t* outLength)
Chia-I Wubb61a722016-10-24 15:40:20 +0800702 {
703 if (mCommandEnd) {
Daniel Nicoara3d2b8d62017-01-10 11:01:29 -0500704 LOG_FATAL("endCommand was not called for last command");
Chia-I Wubb61a722016-10-24 15:40:20 +0800705 }
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();
Chia-I Wue1768352016-12-19 12:56:54 +0800713 *outCommand = static_cast<IComposerClient::Command>(
714 val & opcode_mask);
715 *outLength = static_cast<uint16_t>(val & length_mask);
Chia-I Wubb61a722016-10-24 15:40:20 +0800716
Chia-I Wue1768352016-12-19 12:56:54 +0800717 if (mDataRead + *outLength > mDataSize) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800718 ALOGE("command 0x%x has invalid command length %" PRIu16,
Chia-I Wue1768352016-12-19 12:56:54 +0800719 *outCommand, *outLength);
Chia-I Wubb61a722016-10-24 15:40:20 +0800720 // undo the read() above
721 mDataRead--;
722 return false;
723 }
724
Chia-I Wue1768352016-12-19 12:56:54 +0800725 mCommandEnd = mDataRead + *outLength;
Chia-I Wubb61a722016-10-24 15:40:20 +0800726
727 return true;
728 }
729
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
746 uint32_t getCommandLoc() const
747 {
748 return mCommandBegin;
749 }
750
751 uint32_t read()
752 {
753 return mData[mDataRead++];
754 }
755
756 int32_t readSigned()
757 {
758 int32_t val;
759 memcpy(&val, &mData[mDataRead++], sizeof(val));
760 return val;
761 }
762
763 float readFloat()
764 {
765 float val;
766 memcpy(&val, &mData[mDataRead++], sizeof(val));
767 return val;
768 }
769
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
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
Chia-I Wue1768352016-12-19 12:56:54 +0800789 const native_handle_t* readHandle(bool* outUseCache)
Chia-I Wubb61a722016-10-24 15:40:20 +0800790 {
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):
Chia-I Wue1768352016-12-19 12:56:54 +0800796 *outUseCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800797 break;
798 case static_cast<int32_t>(IComposerClient::HandleIndex::CACHED):
Chia-I Wue1768352016-12-19 12:56:54 +0800799 *outUseCache = true;
Chia-I Wubb61a722016-10-24 15:40:20 +0800800 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 }
Chia-I Wue1768352016-12-19 12:56:54 +0800807 *outUseCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800808 break;
809 }
810
811 return handle;
812 }
813
814 const native_handle_t* readHandle()
815 {
816 bool useCache;
Chia-I Wue1768352016-12-19 12:56:54 +0800817 return readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800818 }
819
820 // ownership of fence is transferred
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
843private:
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