blob: 058709c5ed30a589a898c935c7a09a85c6e9bbd1 [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 {
Chia-I Wu48ffe282017-09-08 11:24:32 -070095 // 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
Chia-I Wubb61a722016-10-24 15:40:20 +0800112 // 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
Chia-I Wue1768352016-12-19 12:56:54 +0800119 *outQueueChanged = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800120 } 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);
Chia-I Wue1768352016-12-19 12:56:54 +0800129 *outQueueChanged = true;
Chia-I Wubb61a722016-10-24 15:40:20 +0800130 }
131
Chia-I Wue1768352016-12-19 12:56:54 +0800132 *outCommandLength = mDataWritten;
133 outCommandHandles->setToExternal(
Chia-I Wubb61a722016-10-24 15:40:20 +0800134 const_cast<hidl_handle*>(mDataHandles.data()),
135 mDataHandles.size());
136
137 return true;
138 }
139
Hridya Valsaraju33351da2016-12-27 12:40:01 -0800140 const MQDescriptorSync<uint32_t>* getMQDescriptor() const
Chia-I Wubb61a722016-10-24 15:40:20 +0800141 {
142 return (mQueue) ? mQueue->getDesc() : nullptr;
143 }
144
145 static constexpr uint16_t kSelectDisplayLength = 2;
146 void selectDisplay(Display display)
147 {
148 beginCommand(IComposerClient::Command::SELECT_DISPLAY,
149 kSelectDisplayLength);
150 write64(display);
151 endCommand();
152 }
153
154 static constexpr uint16_t kSelectLayerLength = 2;
155 void selectLayer(Layer layer)
156 {
157 beginCommand(IComposerClient::Command::SELECT_LAYER,
158 kSelectLayerLength);
159 write64(layer);
160 endCommand();
161 }
162
163 static constexpr uint16_t kSetErrorLength = 2;
164 void setError(uint32_t location, Error error)
165 {
166 beginCommand(IComposerClient::Command::SET_ERROR, kSetErrorLength);
167 write(location);
168 writeSigned(static_cast<int32_t>(error));
169 endCommand();
170 }
171
Fabien Sanglard11ec3932017-06-19 19:25:31 -0700172 static constexpr uint32_t kPresentOrValidateDisplayResultLength = 1;
173 void setPresentOrValidateResult(uint32_t state) {
174 beginCommand(IComposerClient::Command::SET_PRESENT_OR_VALIDATE_DISPLAY_RESULT, kPresentOrValidateDisplayResultLength);
175 write(state);
176 endCommand();
177 }
178
Chia-I Wubb61a722016-10-24 15:40:20 +0800179 void setChangedCompositionTypes(const std::vector<Layer>& layers,
180 const std::vector<IComposerClient::Composition>& types)
181 {
182 size_t totalLayers = std::min(layers.size(), types.size());
183 size_t currentLayer = 0;
184
185 while (currentLayer < totalLayers) {
186 size_t count = std::min(totalLayers - currentLayer,
187 static_cast<size_t>(kMaxLength) / 3);
188
189 beginCommand(
190 IComposerClient::Command::SET_CHANGED_COMPOSITION_TYPES,
191 count * 3);
192 for (size_t i = 0; i < count; i++) {
193 write64(layers[currentLayer + i]);
194 writeSigned(static_cast<int32_t>(types[currentLayer + i]));
195 }
196 endCommand();
197
198 currentLayer += count;
199 }
200 }
201
202 void setDisplayRequests(uint32_t displayRequestMask,
203 const std::vector<Layer>& layers,
204 const std::vector<uint32_t>& layerRequestMasks)
205 {
206 size_t totalLayers = std::min(layers.size(),
207 layerRequestMasks.size());
208 size_t currentLayer = 0;
209
210 while (currentLayer < totalLayers) {
211 size_t count = std::min(totalLayers - currentLayer,
212 static_cast<size_t>(kMaxLength - 1) / 3);
213
214 beginCommand(IComposerClient::Command::SET_DISPLAY_REQUESTS,
215 1 + count * 3);
216 write(displayRequestMask);
217 for (size_t i = 0; i < count; i++) {
218 write64(layers[currentLayer + i]);
219 write(static_cast<int32_t>(layerRequestMasks[currentLayer + i]));
220 }
221 endCommand();
222
223 currentLayer += count;
224 }
225 }
226
227 static constexpr uint16_t kSetPresentFenceLength = 1;
228 void setPresentFence(int presentFence)
229 {
230 beginCommand(IComposerClient::Command::SET_PRESENT_FENCE,
231 kSetPresentFenceLength);
232 writeFence(presentFence);
233 endCommand();
234 }
235
236 void setReleaseFences(const std::vector<Layer>& layers,
237 const std::vector<int>& releaseFences)
238 {
239 size_t totalLayers = std::min(layers.size(), releaseFences.size());
240 size_t currentLayer = 0;
241
242 while (currentLayer < totalLayers) {
243 size_t count = std::min(totalLayers - currentLayer,
244 static_cast<size_t>(kMaxLength) / 3);
245
246 beginCommand(IComposerClient::Command::SET_RELEASE_FENCES,
247 count * 3);
248 for (size_t i = 0; i < count; i++) {
249 write64(layers[currentLayer + i]);
250 writeFence(releaseFences[currentLayer + i]);
251 }
252 endCommand();
253
254 currentLayer += count;
255 }
256 }
257
258 static constexpr uint16_t kSetColorTransformLength = 17;
259 void setColorTransform(const float* matrix, ColorTransform hint)
260 {
261 beginCommand(IComposerClient::Command::SET_COLOR_TRANSFORM,
262 kSetColorTransformLength);
263 for (int i = 0; i < 16; i++) {
264 writeFloat(matrix[i]);
265 }
266 writeSigned(static_cast<int32_t>(hint));
267 endCommand();
268 }
269
270 void setClientTarget(uint32_t slot, const native_handle_t* target,
271 int acquireFence, Dataspace dataspace,
272 const std::vector<IComposerClient::Rect>& damage)
273 {
274 bool doWrite = (damage.size() <= (kMaxLength - 4) / 4);
275 size_t length = 4 + ((doWrite) ? damage.size() * 4 : 0);
276
277 beginCommand(IComposerClient::Command::SET_CLIENT_TARGET, length);
278 write(slot);
279 writeHandle(target, true);
280 writeFence(acquireFence);
281 writeSigned(static_cast<int32_t>(dataspace));
282 // When there are too many rectangles in the damage region and doWrite
283 // is false, we write no rectangle at all which means the entire
284 // client target is damaged.
285 if (doWrite) {
286 writeRegion(damage);
287 }
288 endCommand();
289 }
290
291 static constexpr uint16_t kSetOutputBufferLength = 3;
292 void setOutputBuffer(uint32_t slot, const native_handle_t* buffer,
293 int releaseFence)
294 {
295 beginCommand(IComposerClient::Command::SET_OUTPUT_BUFFER,
296 kSetOutputBufferLength);
297 write(slot);
298 writeHandle(buffer, true);
299 writeFence(releaseFence);
300 endCommand();
301 }
302
303 static constexpr uint16_t kValidateDisplayLength = 0;
304 void validateDisplay()
305 {
306 beginCommand(IComposerClient::Command::VALIDATE_DISPLAY,
307 kValidateDisplayLength);
308 endCommand();
309 }
310
Fabien Sanglard11ec3932017-06-19 19:25:31 -0700311 static constexpr uint16_t kPresentOrValidateDisplayLength = 0;
312 void presentOrvalidateDisplay()
313 {
314 beginCommand(IComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY,
315 kPresentOrValidateDisplayLength);
316 endCommand();
317 }
318
Chia-I Wubb61a722016-10-24 15:40:20 +0800319 static constexpr uint16_t kAcceptDisplayChangesLength = 0;
320 void acceptDisplayChanges()
321 {
322 beginCommand(IComposerClient::Command::ACCEPT_DISPLAY_CHANGES,
323 kAcceptDisplayChangesLength);
324 endCommand();
325 }
326
327 static constexpr uint16_t kPresentDisplayLength = 0;
328 void presentDisplay()
329 {
330 beginCommand(IComposerClient::Command::PRESENT_DISPLAY,
331 kPresentDisplayLength);
332 endCommand();
333 }
334
335 static constexpr uint16_t kSetLayerCursorPositionLength = 2;
336 void setLayerCursorPosition(int32_t x, int32_t y)
337 {
338 beginCommand(IComposerClient::Command::SET_LAYER_CURSOR_POSITION,
339 kSetLayerCursorPositionLength);
340 writeSigned(x);
341 writeSigned(y);
342 endCommand();
343 }
344
345 static constexpr uint16_t kSetLayerBufferLength = 3;
346 void setLayerBuffer(uint32_t slot, const native_handle_t* buffer,
347 int acquireFence)
348 {
349 beginCommand(IComposerClient::Command::SET_LAYER_BUFFER,
350 kSetLayerBufferLength);
351 write(slot);
352 writeHandle(buffer, true);
353 writeFence(acquireFence);
354 endCommand();
355 }
356
357 void setLayerSurfaceDamage(
358 const std::vector<IComposerClient::Rect>& damage)
359 {
360 bool doWrite = (damage.size() <= kMaxLength / 4);
361 size_t length = (doWrite) ? damage.size() * 4 : 0;
362
363 beginCommand(IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE,
364 length);
365 // When there are too many rectangles in the damage region and doWrite
366 // is false, we write no rectangle at all which means the entire
367 // layer is damaged.
368 if (doWrite) {
369 writeRegion(damage);
370 }
371 endCommand();
372 }
373
374 static constexpr uint16_t kSetLayerBlendModeLength = 1;
375 void setLayerBlendMode(IComposerClient::BlendMode mode)
376 {
377 beginCommand(IComposerClient::Command::SET_LAYER_BLEND_MODE,
378 kSetLayerBlendModeLength);
379 writeSigned(static_cast<int32_t>(mode));
380 endCommand();
381 }
382
383 static constexpr uint16_t kSetLayerColorLength = 1;
384 void setLayerColor(IComposerClient::Color color)
385 {
386 beginCommand(IComposerClient::Command::SET_LAYER_COLOR,
387 kSetLayerColorLength);
388 writeColor(color);
389 endCommand();
390 }
391
392 static constexpr uint16_t kSetLayerCompositionTypeLength = 1;
393 void setLayerCompositionType(IComposerClient::Composition type)
394 {
395 beginCommand(IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE,
396 kSetLayerCompositionTypeLength);
397 writeSigned(static_cast<int32_t>(type));
398 endCommand();
399 }
400
401 static constexpr uint16_t kSetLayerDataspaceLength = 1;
402 void setLayerDataspace(Dataspace dataspace)
403 {
404 beginCommand(IComposerClient::Command::SET_LAYER_DATASPACE,
405 kSetLayerDataspaceLength);
406 writeSigned(static_cast<int32_t>(dataspace));
407 endCommand();
408 }
409
410 static constexpr uint16_t kSetLayerDisplayFrameLength = 4;
411 void setLayerDisplayFrame(const IComposerClient::Rect& frame)
412 {
413 beginCommand(IComposerClient::Command::SET_LAYER_DISPLAY_FRAME,
414 kSetLayerDisplayFrameLength);
415 writeRect(frame);
416 endCommand();
417 }
418
419 static constexpr uint16_t kSetLayerPlaneAlphaLength = 1;
420 void setLayerPlaneAlpha(float alpha)
421 {
422 beginCommand(IComposerClient::Command::SET_LAYER_PLANE_ALPHA,
423 kSetLayerPlaneAlphaLength);
424 writeFloat(alpha);
425 endCommand();
426 }
427
428 static constexpr uint16_t kSetLayerSidebandStreamLength = 1;
429 void setLayerSidebandStream(const native_handle_t* stream)
430 {
431 beginCommand(IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM,
432 kSetLayerSidebandStreamLength);
433 writeHandle(stream);
434 endCommand();
435 }
436
437 static constexpr uint16_t kSetLayerSourceCropLength = 4;
438 void setLayerSourceCrop(const IComposerClient::FRect& crop)
439 {
440 beginCommand(IComposerClient::Command::SET_LAYER_SOURCE_CROP,
441 kSetLayerSourceCropLength);
442 writeFRect(crop);
443 endCommand();
444 }
445
446 static constexpr uint16_t kSetLayerTransformLength = 1;
447 void setLayerTransform(Transform transform)
448 {
449 beginCommand(IComposerClient::Command::SET_LAYER_TRANSFORM,
450 kSetLayerTransformLength);
451 writeSigned(static_cast<int32_t>(transform));
452 endCommand();
453 }
454
455 void setLayerVisibleRegion(
456 const std::vector<IComposerClient::Rect>& visible)
457 {
458 bool doWrite = (visible.size() <= kMaxLength / 4);
459 size_t length = (doWrite) ? visible.size() * 4 : 0;
460
461 beginCommand(IComposerClient::Command::SET_LAYER_VISIBLE_REGION,
462 length);
463 // When there are too many rectangles in the visible region and
464 // doWrite is false, we write no rectangle at all which means the
465 // entire layer is visible.
466 if (doWrite) {
467 writeRegion(visible);
468 }
469 endCommand();
470 }
471
472 static constexpr uint16_t kSetLayerZOrderLength = 1;
473 void setLayerZOrder(uint32_t z)
474 {
475 beginCommand(IComposerClient::Command::SET_LAYER_Z_ORDER,
476 kSetLayerZOrderLength);
477 write(z);
478 endCommand();
479 }
480
481protected:
482 void beginCommand(IComposerClient::Command command, uint16_t length)
483 {
484 if (mCommandEnd) {
485 LOG_FATAL("endCommand was not called before command 0x%x",
486 command);
487 }
488
489 growData(1 + length);
490 write(static_cast<uint32_t>(command) | length);
491
492 mCommandEnd = mDataWritten + length;
493 }
494
495 void endCommand()
496 {
497 if (!mCommandEnd) {
498 LOG_FATAL("beginCommand was not called");
499 } else if (mDataWritten > mCommandEnd) {
500 LOG_FATAL("too much data written");
501 mDataWritten = mCommandEnd;
502 } else if (mDataWritten < mCommandEnd) {
503 LOG_FATAL("too little data written");
504 while (mDataWritten < mCommandEnd) {
505 write(0);
506 }
507 }
508
509 mCommandEnd = 0;
510 }
511
512 void write(uint32_t val)
513 {
514 mData[mDataWritten++] = val;
515 }
516
517 void writeSigned(int32_t val)
518 {
519 memcpy(&mData[mDataWritten++], &val, sizeof(val));
520 }
521
522 void writeFloat(float val)
523 {
524 memcpy(&mData[mDataWritten++], &val, sizeof(val));
525 }
526
527 void write64(uint64_t val)
528 {
529 uint32_t lo = static_cast<uint32_t>(val & 0xffffffff);
530 uint32_t hi = static_cast<uint32_t>(val >> 32);
531 write(lo);
532 write(hi);
533 }
534
535 void writeRect(const IComposerClient::Rect& rect)
536 {
537 writeSigned(rect.left);
538 writeSigned(rect.top);
539 writeSigned(rect.right);
540 writeSigned(rect.bottom);
541 }
542
543 void writeRegion(const std::vector<IComposerClient::Rect>& region)
544 {
545 for (const auto& rect : region) {
546 writeRect(rect);
547 }
548 }
549
550 void writeFRect(const IComposerClient::FRect& rect)
551 {
552 writeFloat(rect.left);
553 writeFloat(rect.top);
554 writeFloat(rect.right);
555 writeFloat(rect.bottom);
556 }
557
558 void writeColor(const IComposerClient::Color& color)
559 {
560 write((color.r << 0) |
561 (color.g << 8) |
562 (color.b << 16) |
563 (color.a << 24));
564 }
565
566 // ownership of handle is not transferred
567 void writeHandle(const native_handle_t* handle, bool useCache)
568 {
569 if (!handle) {
570 writeSigned(static_cast<int32_t>((useCache) ?
571 IComposerClient::HandleIndex::CACHED :
572 IComposerClient::HandleIndex::EMPTY));
573 return;
574 }
575
576 mDataHandles.push_back(handle);
577 writeSigned(mDataHandles.size() - 1);
578 }
579
580 void writeHandle(const native_handle_t* handle)
581 {
582 writeHandle(handle, false);
583 }
584
585 // ownership of fence is transferred
586 void writeFence(int fence)
587 {
588 native_handle_t* handle = nullptr;
589 if (fence >= 0) {
590 handle = getTemporaryHandle(1, 0);
591 if (handle) {
592 handle->data[0] = fence;
593 } else {
594 ALOGW("failed to get temporary handle for fence %d", fence);
595 sync_wait(fence, -1);
596 close(fence);
597 }
598 }
599
600 writeHandle(handle);
601 }
602
603 native_handle_t* getTemporaryHandle(int numFds, int numInts)
604 {
605 native_handle_t* handle = native_handle_create(numFds, numInts);
606 if (handle) {
607 mTemporaryHandles.push_back(handle);
608 }
609 return handle;
610 }
611
612 static constexpr uint16_t kMaxLength =
613 std::numeric_limits<uint16_t>::max();
614
615private:
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.
654class CommandReaderBase {
655public:
656 CommandReaderBase() : mDataMaxSize(0)
657 {
658 reset();
659 }
660
Hridya Valsaraju33351da2016-12-27 12:40:01 -0800661 bool setMQDescriptor(const MQDescriptorSync<uint32_t>& descriptor)
Chia-I Wubb61a722016-10-24 15:40:20 +0800662 {
663 mQueue = std::make_unique<CommandQueueType>(descriptor, false);
664 if (mQueue->isValid()) {
665 return true;
666 } else {
667 mQueue = nullptr;
668 return false;
669 }
670 }
671
672 bool readQueue(uint32_t commandLength,
673 const hidl_vec<hidl_handle>& commandHandles)
674 {
675 if (!mQueue) {
676 return false;
677 }
678
679 auto quantumCount = mQueue->getQuantumCount();
680 if (mDataMaxSize < quantumCount) {
681 mDataMaxSize = quantumCount;
682 mData = std::make_unique<uint32_t[]>(mDataMaxSize);
683 }
684
685 if (commandLength > mDataMaxSize ||
686 !mQueue->read(mData.get(), commandLength)) {
687 ALOGE("failed to read commands from message queue");
688 return false;
689 }
690
691 mDataSize = commandLength;
692 mDataRead = 0;
693 mCommandBegin = 0;
694 mCommandEnd = 0;
695 mDataHandles.setToExternal(
696 const_cast<hidl_handle*>(commandHandles.data()),
697 commandHandles.size());
698
699 return true;
700 }
701
702 void reset()
703 {
704 mDataSize = 0;
705 mDataRead = 0;
706 mCommandBegin = 0;
707 mCommandEnd = 0;
708 mDataHandles.setToExternal(nullptr, 0);
709 }
710
711protected:
712 bool isEmpty() const
713 {
714 return (mDataRead >= mDataSize);
715 }
716
Chia-I Wue1768352016-12-19 12:56:54 +0800717 bool beginCommand(IComposerClient::Command* outCommand,
718 uint16_t* outLength)
Chia-I Wubb61a722016-10-24 15:40:20 +0800719 {
720 if (mCommandEnd) {
Daniel Nicoara3d2b8d62017-01-10 11:01:29 -0500721 LOG_FATAL("endCommand was not called for last command");
Chia-I Wubb61a722016-10-24 15:40:20 +0800722 }
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();
Chia-I Wue1768352016-12-19 12:56:54 +0800730 *outCommand = static_cast<IComposerClient::Command>(
731 val & opcode_mask);
732 *outLength = static_cast<uint16_t>(val & length_mask);
Chia-I Wubb61a722016-10-24 15:40:20 +0800733
Chia-I Wue1768352016-12-19 12:56:54 +0800734 if (mDataRead + *outLength > mDataSize) {
Chia-I Wubb61a722016-10-24 15:40:20 +0800735 ALOGE("command 0x%x has invalid command length %" PRIu16,
Chia-I Wue1768352016-12-19 12:56:54 +0800736 *outCommand, *outLength);
Chia-I Wubb61a722016-10-24 15:40:20 +0800737 // undo the read() above
738 mDataRead--;
739 return false;
740 }
741
Chia-I Wue1768352016-12-19 12:56:54 +0800742 mCommandEnd = mDataRead + *outLength;
Chia-I Wubb61a722016-10-24 15:40:20 +0800743
744 return true;
745 }
746
747 void endCommand()
748 {
749 if (!mCommandEnd) {
750 LOG_FATAL("beginCommand was not called");
751 } else if (mDataRead > mCommandEnd) {
752 LOG_FATAL("too much data read");
753 mDataRead = mCommandEnd;
754 } else if (mDataRead < mCommandEnd) {
755 LOG_FATAL("too little data read");
756 mDataRead = mCommandEnd;
757 }
758
759 mCommandBegin = mCommandEnd;
760 mCommandEnd = 0;
761 }
762
763 uint32_t getCommandLoc() const
764 {
765 return mCommandBegin;
766 }
767
768 uint32_t read()
769 {
770 return mData[mDataRead++];
771 }
772
773 int32_t readSigned()
774 {
775 int32_t val;
776 memcpy(&val, &mData[mDataRead++], sizeof(val));
777 return val;
778 }
779
780 float readFloat()
781 {
782 float val;
783 memcpy(&val, &mData[mDataRead++], sizeof(val));
784 return val;
785 }
786
787 uint64_t read64()
788 {
789 uint32_t lo = read();
790 uint32_t hi = read();
791 return (static_cast<uint64_t>(hi) << 32) | lo;
792 }
793
794 IComposerClient::Color readColor()
795 {
796 uint32_t val = read();
797 return IComposerClient::Color{
798 static_cast<uint8_t>((val >> 0) & 0xff),
799 static_cast<uint8_t>((val >> 8) & 0xff),
800 static_cast<uint8_t>((val >> 16) & 0xff),
801 static_cast<uint8_t>((val >> 24) & 0xff),
802 };
803 }
804
805 // ownership of handle is not transferred
Chia-I Wue1768352016-12-19 12:56:54 +0800806 const native_handle_t* readHandle(bool* outUseCache)
Chia-I Wubb61a722016-10-24 15:40:20 +0800807 {
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):
Chia-I Wue1768352016-12-19 12:56:54 +0800813 *outUseCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800814 break;
815 case static_cast<int32_t>(IComposerClient::HandleIndex::CACHED):
Chia-I Wue1768352016-12-19 12:56:54 +0800816 *outUseCache = true;
Chia-I Wubb61a722016-10-24 15:40:20 +0800817 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 }
Chia-I Wue1768352016-12-19 12:56:54 +0800824 *outUseCache = false;
Chia-I Wubb61a722016-10-24 15:40:20 +0800825 break;
826 }
827
828 return handle;
829 }
830
831 const native_handle_t* readHandle()
832 {
833 bool useCache;
Chia-I Wue1768352016-12-19 12:56:54 +0800834 return readHandle(&useCache);
Chia-I Wubb61a722016-10-24 15:40:20 +0800835 }
836
837 // ownership of fence is transferred
838 int readFence()
839 {
840 auto handle = readHandle();
841 if (!handle || handle->numFds == 0) {
842 return -1;
843 }
844
845 if (handle->numFds != 1) {
846 ALOGE("invalid fence handle with %d fds", handle->numFds);
847 return -1;
848 }
849
850 int fd = dup(handle->data[0]);
851 if (fd < 0) {
852 ALOGW("failed to dup fence %d", handle->data[0]);
853 sync_wait(handle->data[0], -1);
854 fd = -1;
855 }
856
857 return fd;
858 }
859
860private:
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