summaryrefslogtreecommitdiff
path: root/hwc3/ComposerCommandEngine.cpp
diff options
context:
space:
mode:
authorLong Ling <longling@google.com>2021-10-01 14:25:49 -0700
committerLong Ling <longling@google.com>2021-11-10 09:56:46 -0800
commit7b05ff5a12b053069bd9f1c07e3ad0ca9b463ec1 (patch)
tree49329c7e8dca4c05ab5b025db08528d9900bd07a /hwc3/ComposerCommandEngine.cpp
parent4af8d97f8d51a73eb5dad71ba4fad4e0ad412cee (diff)
hwc: migrate to composer3
Bug: 201321174 Change-Id: I31834ad240c89f25427958f887a3c5015e9cb535
Diffstat (limited to 'hwc3/ComposerCommandEngine.cpp')
-rw-r--r--hwc3/ComposerCommandEngine.cpp713
1 files changed, 713 insertions, 0 deletions
diff --git a/hwc3/ComposerCommandEngine.cpp b/hwc3/ComposerCommandEngine.cpp
new file mode 100644
index 0000000..13f3c35
--- /dev/null
+++ b/hwc3/ComposerCommandEngine.cpp
@@ -0,0 +1,713 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <aidl/android/hardware/graphics/composer3/Command.h>
+
+#include "ComposerCommandEngine.h"
+#include "Util.h"
+
+/// The command engine interface is not 'pure' aidl. Conversion to aidl
+// structure is done within this class. Don't mix it with impl/translate.
+// Expect to have an AIDL command interface in the future.
+//
+// The initial implementation is a combination of asop ComposerCommandEngine 2.1 to 2.4
+// and adapt to aidl structures.
+namespace aidl::android::hardware::graphics::composer3::impl {
+
+bool ComposerCommandEngine::init() {
+ mWriter = std::make_unique<CommandWriterBase>(kWriterInitialSize);
+ return (mWriter != nullptr);
+}
+
+int32_t ComposerCommandEngine::execute(int32_t inLength,
+ const std::vector<AidlNativeHandle>& inHandles,
+ ExecuteCommandsStatus* status) {
+ DEBUG_FUNC();
+ // inHandles is not declared as const in AIDL sub code and is not used after this call.
+ // drop the const to avoid dup the handles
+ auto& handles = const_cast<std::vector<AidlNativeHandle>&>(inHandles);
+ if (!readQueue(inLength, std::move(handles))) {
+ return IComposerClient::EX_BAD_PARAMETER;
+ }
+
+ Command command;
+ uint16_t length = 0;
+ while (!isEmpty()) {
+ if (!beginCommand(&command, &length)) {
+ break;
+ }
+
+ bool parsed = executeCommand(command, length);
+ endCommand();
+
+ if (!parsed) {
+ LOG(ERROR) << "failed to parse command: 0x" << std::hex
+ << static_cast<uint32_t>(command)
+ << ", len: " << std::dec << length;
+ break;
+ }
+ }
+
+ if (!isEmpty()) {
+ return IComposerClient::EX_BAD_PARAMETER;
+ }
+
+ return mWriter->writeQueue(&status->queueChanged, &status->length, &status->handles)
+ ? 0
+ : IComposerClient::EX_NO_RESOURCES;
+}
+
+bool ComposerCommandEngine::executeCommand(Command command, uint16_t length) {
+ DEBUG_FUNC();
+ switch (command) {
+ case Command::SELECT_DISPLAY:
+ return executeSelectDisplay(length);
+ case Command::SELECT_LAYER:
+ return executeSelectLayer(length);
+ case Command::SET_COLOR_TRANSFORM:
+ return executeSetColorTransform(length);
+ case Command::SET_CLIENT_TARGET:
+ return executeSetClientTarget(length);
+ case Command::SET_OUTPUT_BUFFER:
+ return executeSetOutputBuffer(length);
+ case Command::VALIDATE_DISPLAY:
+ return executeValidateDisplay(length);
+ case Command::PRESENT_OR_VALIDATE_DISPLAY:
+ return executePresentOrValidateDisplay(length);
+ case Command::ACCEPT_DISPLAY_CHANGES:
+ return executeAcceptDisplayChanges(length);
+ case Command::PRESENT_DISPLAY:
+ return executePresentDisplay(length);
+ case Command::SET_LAYER_CURSOR_POSITION:
+ return executeSetLayerCursorPosition(length);
+ case Command::SET_LAYER_BUFFER:
+ return executeSetLayerBuffer(length);
+ case Command::SET_LAYER_SURFACE_DAMAGE:
+ return executeSetLayerSurfaceDamage(length);
+ case Command::SET_LAYER_BLEND_MODE:
+ return executeSetLayerBlendMode(length);
+ case Command::SET_LAYER_COLOR:
+ return executeSetLayerColor(length);
+ case Command::SET_LAYER_COMPOSITION_TYPE:
+ return executeSetLayerCompositionType(length);
+ case Command::SET_LAYER_DATASPACE:
+ return executeSetLayerDataspace(length);
+ case Command::SET_LAYER_DISPLAY_FRAME:
+ return executeSetLayerDisplayFrame(length);
+ case Command::SET_LAYER_PLANE_ALPHA:
+ return executeSetLayerPlaneAlpha(length);
+ case Command::SET_LAYER_SIDEBAND_STREAM:
+ return executeSetLayerSidebandStream(length);
+ case Command::SET_LAYER_SOURCE_CROP:
+ return executeSetLayerSourceCrop(length);
+ case Command::SET_LAYER_TRANSFORM:
+ return executeSetLayerTransform(length);
+ case Command::SET_LAYER_VISIBLE_REGION:
+ return executeSetLayerVisibleRegion(length);
+ case Command::SET_LAYER_Z_ORDER:
+ return executeSetLayerZOrder(length);
+ case Command::SET_LAYER_PER_FRAME_METADATA:
+ return executeSetLayerPerFrameMetadata(length);
+ case Command::SET_LAYER_FLOAT_COLOR:
+ return executeSetLayerFloatColor(length);
+ case Command::SET_LAYER_COLOR_TRANSFORM:
+ return executeSetLayerColorTransform(length);
+ case Command::SET_LAYER_PER_FRAME_METADATA_BLOBS:
+ return executeSetLayerPerFrameMetadataBlobs(length);
+ case Command::SET_LAYER_GENERIC_METADATA:
+ return executeSetLayerGenericMetadata(length);
+ default:
+ return false;
+ }
+}
+
+int32_t ComposerCommandEngine::executeValidateDisplayInternal() {
+ std::vector<int64_t> changedLayers;
+ std::vector<Composition> compositionTypes;
+ uint32_t displayRequestMask = 0x0;
+ std::vector<int64_t> requestedLayers;
+ std::vector<uint32_t> requestMasks;
+ ClientTargetProperty clientTargetProperty{common::PixelFormat::RGBA_8888,
+ common::Dataspace::UNKNOWN};
+ auto err = mHal->validateDisplay(mCurrentDisplay, &changedLayers, &compositionTypes,
+ &displayRequestMask, &requestedLayers, &requestMasks,
+ &clientTargetProperty);
+ mResources->setDisplayMustValidateState(mCurrentDisplay, false);
+ if (!err) {
+ mWriter->setChangedCompositionTypes(changedLayers, compositionTypes);
+ mWriter->setDisplayRequests(displayRequestMask, requestedLayers, requestMasks);
+ mWriter->setClientTargetProperty(clientTargetProperty);
+ } else {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+ return err;
+}
+
+bool ComposerCommandEngine::executeSelectDisplay(uint16_t length) {
+ if (length != CommandWriterBase::kSelectDisplayLength) {
+ return false;
+ }
+
+ mCurrentDisplay = read64();
+ mWriter->selectDisplay(mCurrentDisplay);
+
+ return true;
+}
+
+bool ComposerCommandEngine::executeSelectLayer(uint16_t length) {
+ if (length != CommandWriterBase::kSelectLayerLength) {
+ return false;
+ }
+
+ mCurrentLayer = read64();
+
+ return true;
+}
+
+bool ComposerCommandEngine::executeSetColorTransform(uint16_t length) {
+ if (length != CommandWriterBase::kSetColorTransformLength) {
+ return false;
+ }
+
+ std::vector<float> matrix(16);
+ for (int i = 0; i < 16; i++) {
+ matrix[i] = readFloat();
+ }
+ auto transform = readSigned();
+
+ auto err = mHal->setColorTransform(mCurrentDisplay, matrix, transform);
+ if (err) {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool ComposerCommandEngine::executeSetClientTarget(uint16_t length) {
+ // 4 parameters followed by N rectangles
+ if ((length - 4) % 4 != 0) {
+ return false;
+ }
+
+ bool useCache = false;
+ auto slot = read();
+ auto handle = readHandle(&useCache);
+ auto fence = readAidlFence();
+ common::Dataspace dataspace = static_cast<common::Dataspace>(readSigned());
+ auto damage = readRegion((length - 4) / 4);
+ buffer_handle_t clientTarget;
+
+ auto bufferReleaser = mResources->createReleaser(true);
+ auto err = mResources->getDisplayClientTarget(mCurrentDisplay, slot, useCache, handle,
+ clientTarget, bufferReleaser.get());
+ if (!err) {
+ err = mHal->setClientTarget(mCurrentDisplay, clientTarget, fence, dataspace,
+ damage);
+ } else {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool ComposerCommandEngine::executeSetOutputBuffer(uint16_t length) {
+ if (length != CommandWriterBase::kSetOutputBufferLength) {
+ return false;
+ }
+
+ bool useCache = false;
+ auto slot = read();
+ auto handle = readHandle(&useCache);
+ auto fence = readAidlFence();
+ buffer_handle_t outputBuffer;
+
+ auto bufferReleaser = mResources->createReleaser(true);
+ auto err = mResources->getDisplayOutputBuffer(mCurrentDisplay, slot, useCache, handle,
+ outputBuffer, bufferReleaser.get());
+ if (!err) {
+ err = mHal->setOutputBuffer(mCurrentDisplay, outputBuffer, fence);
+ } else {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool ComposerCommandEngine::executeValidateDisplay(uint16_t length) {
+ if (length != CommandWriterBase::kValidateDisplayLength) {
+ return false;
+ }
+ executeValidateDisplayInternal();
+ return true;
+}
+
+bool ComposerCommandEngine::executePresentOrValidateDisplay(uint16_t length) {
+ if (length != CommandWriterBase::kPresentOrValidateDisplayLength) {
+ return false;
+ }
+
+ // First try to Present as is.
+ if (mHal->hasCapability(Capability::SKIP_VALIDATE)) {
+ ndk::ScopedFileDescriptor presentFence;
+ std::vector<int64_t> layers;
+ std::vector<ndk::ScopedFileDescriptor> fences;
+ auto err = mResources->mustValidateDisplay(mCurrentDisplay)
+ ? IComposerClient::EX_NOT_VALIDATED
+ : mHal->presentDisplay(mCurrentDisplay, presentFence, &layers, &fences);
+ if (!err) {
+ mWriter->setPresentOrValidateResult(1);
+ // ownership is transferred to Writer
+ mWriter->setPresentFence(takeFence(presentFence));
+ mWriter->setReleaseFences(layers, takeFence(fences));
+ return true;
+ }
+ }
+
+ // Present has failed. We need to fallback to validate
+ auto err = executeValidateDisplayInternal();
+ if (!err) {
+ mWriter->setPresentOrValidateResult(0);
+ }
+
+ return true;
+}
+
+bool ComposerCommandEngine::executeAcceptDisplayChanges(uint16_t length) {
+ if (length != CommandWriterBase::kAcceptDisplayChangesLength) {
+ return false;
+ }
+
+ auto err = mHal->acceptDisplayChanges(mCurrentDisplay);
+ if (err) {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool ComposerCommandEngine::executePresentDisplay(uint16_t length) {
+ if (length != CommandWriterBase::kPresentDisplayLength) {
+ return false;
+ }
+
+ ndk::ScopedFileDescriptor presentFence;
+ std::vector<int64_t> layers;
+ std::vector<ndk::ScopedFileDescriptor> fences;
+ auto err = mHal->presentDisplay(mCurrentDisplay, presentFence, &layers, &fences);
+ if (!err) {
+ // ownership is transferred to Writer
+ mWriter->setPresentFence(takeFence(presentFence));
+ mWriter->setReleaseFences(layers, takeFence(fences));
+ } else {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool ComposerCommandEngine::executeSetLayerCursorPosition(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerCursorPositionLength) {
+ return false;
+ }
+
+ auto err = mHal->setLayerCursorPosition(mCurrentDisplay, mCurrentLayer, readSigned(),
+ readSigned());
+ if (err) {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool ComposerCommandEngine::executeSetLayerBuffer(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerBufferLength) {
+ return false;
+ }
+
+ bool useCache = false;
+ auto slot = read();
+ auto handle = readHandle(&useCache);
+ auto fence = readAidlFence();
+
+ buffer_handle_t buffer;
+ auto bufferReleaser = mResources->createReleaser(true);
+ auto err = mResources->getLayerBuffer(mCurrentDisplay, mCurrentLayer, slot, useCache,
+ handle, buffer, bufferReleaser.get());
+ if (!err) {
+ err = mHal->setLayerBuffer(mCurrentDisplay, mCurrentLayer, buffer, fence);
+ } else {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool ComposerCommandEngine::executeSetLayerSurfaceDamage(uint16_t length) {
+ // N rectangles
+ if (length % 4 != 0) {
+ return false;
+ }
+
+ auto damage = readRegion(length / 4);
+ auto err = mHal->setLayerSurfaceDamage(mCurrentDisplay, mCurrentLayer, damage);
+ if (err) {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool ComposerCommandEngine::executeSetLayerBlendMode(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerBlendModeLength) {
+ return false;
+ }
+
+ BlendMode mode = static_cast<BlendMode>(readSigned());
+ auto err = mHal->setLayerBlendMode(mCurrentDisplay, mCurrentLayer, mode);
+ if (err) {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool ComposerCommandEngine::executeSetLayerColor(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerColorLength) {
+ return false;
+ }
+
+ auto err = mHal->setLayerColor(mCurrentDisplay, mCurrentLayer, readColor());
+ if (err) {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool ComposerCommandEngine::executeSetLayerCompositionType(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerCompositionTypeLength) {
+ return false;
+ }
+
+ Composition type = static_cast<Composition>(readSigned());
+ auto err = mHal->setLayerCompositionType(mCurrentDisplay, mCurrentLayer, type);
+ if (err) {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool ComposerCommandEngine::executeSetLayerDataspace(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerDataspaceLength) {
+ return false;
+ }
+
+ common::Dataspace dataspace = static_cast<common::Dataspace>(readSigned());
+ auto err = mHal->setLayerDataspace(mCurrentDisplay, mCurrentLayer, dataspace);
+ if (err) {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool ComposerCommandEngine::executeSetLayerDisplayFrame(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerDisplayFrameLength) {
+ return false;
+ }
+
+ auto err = mHal->setLayerDisplayFrame(mCurrentDisplay, mCurrentLayer, readRect());
+ if (err) {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool ComposerCommandEngine::executeSetLayerPlaneAlpha(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerPlaneAlphaLength) {
+ return false;
+ }
+
+ auto err = mHal->setLayerPlaneAlpha(mCurrentDisplay, mCurrentLayer, readFloat());
+ if (err) {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool ComposerCommandEngine::executeSetLayerSidebandStream(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerSidebandStreamLength) {
+ return false;
+ }
+
+ bool useCache;
+ auto handle = readHandle(&useCache);
+ buffer_handle_t stream;
+
+ auto bufferReleaser = mResources->createReleaser(false);
+ auto err = mResources->getLayerSidebandStream(mCurrentDisplay, mCurrentLayer, handle,
+ stream, bufferReleaser.get());
+ if (err) {
+ err = mHal->setLayerSidebandStream(mCurrentDisplay, mCurrentLayer, stream);
+ }
+ if (err) {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool ComposerCommandEngine::executeSetLayerSourceCrop(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerSourceCropLength) {
+ return false;
+ }
+
+ auto err = mHal->setLayerSourceCrop(mCurrentDisplay, mCurrentLayer, readFRect());
+ if (err) {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool ComposerCommandEngine::executeSetLayerTransform(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerTransformLength) {
+ return false;
+ }
+
+ common::Transform transform = static_cast<common::Transform>(readSigned());
+ auto err = mHal->setLayerTransform(mCurrentDisplay, mCurrentLayer, transform);
+ if (err) {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool ComposerCommandEngine::executeSetLayerVisibleRegion(uint16_t length) {
+ // N rectangles
+ if (length % 4 != 0) {
+ return false;
+ }
+
+ auto region = readRegion(length / 4);
+ auto err = mHal->setLayerVisibleRegion(mCurrentDisplay, mCurrentLayer, region);
+ if (err) {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool ComposerCommandEngine::executeSetLayerZOrder(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerZOrderLength) {
+ return false;
+ }
+
+ auto err = mHal->setLayerZOrder(mCurrentDisplay, mCurrentLayer, read());
+ if (err) {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool ComposerCommandEngine::executeSetLayerPerFrameMetadata(uint16_t length) {
+ // (key, value) pairs
+ if (length % 2 != 0) {
+ return false;
+ }
+
+ std::vector<PerFrameMetadata> metadata;
+ metadata.reserve(length / 2);
+ while (length > 0) {
+ metadata.emplace_back(
+ PerFrameMetadata{static_cast<PerFrameMetadataKey>(readSigned()), readFloat()});
+ length -= 2;
+ }
+
+ auto err = mHal->setLayerPerFrameMetadata(mCurrentDisplay, mCurrentLayer, metadata);
+ if (err) {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool ComposerCommandEngine::executeSetLayerFloatColor(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerFloatColorLength) {
+ return false;
+ }
+
+ auto err = mHal->setLayerFloatColor(mCurrentDisplay, mCurrentLayer, readFloatColor());
+ if (err) {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool ComposerCommandEngine::executeSetLayerColorTransform(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerColorTransformLength) {
+ return false;
+ }
+
+ std::vector<float> matrix(16);
+ for (int i = 0; i < 16; i++) {
+ matrix[i] = readFloat();
+ }
+ auto err = mHal->setLayerColorTransform(mCurrentDisplay, mCurrentLayer, matrix);
+ if (err) {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+bool ComposerCommandEngine::executeSetLayerPerFrameMetadataBlobs(uint16_t length) {
+ // must have at least one metadata blob
+ // of at least size 1 in queue (i.e {/*numBlobs=*/1, key, size, blob})
+ if (length < 4) {
+ return false;
+ }
+
+ uint32_t numBlobs = read();
+ length--;
+
+ std::vector<PerFrameMetadataBlob> metadata;
+
+ for (size_t i = 0; i < numBlobs; i++) {
+ PerFrameMetadataKey key = static_cast<PerFrameMetadataKey>(readSigned());
+ uint32_t blobSize = read();
+
+ length -= 2;
+
+ if (length * sizeof(uint32_t) < blobSize) {
+ return false;
+ }
+
+ metadata.push_back({key, std::vector<uint8_t>()});
+ PerFrameMetadataBlob& metadataBlob = metadata.back();
+ metadataBlob.blob.resize(blobSize);
+ readBlob(blobSize, metadataBlob.blob.data());
+ }
+ auto err = mHal->setLayerPerFrameMetadataBlobs(mCurrentDisplay, mCurrentLayer, metadata);
+ if (err) {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+ return true;
+}
+
+bool ComposerCommandEngine::executeSetLayerGenericMetadata(uint16_t length) {
+ // We expect at least two buffer lengths and a mandatory flag
+ if (length < 3) {
+ return false;
+ }
+
+ const uint32_t keySize = read();
+ std::string key;
+ key.resize(keySize);
+ readBlob(keySize, key.data());
+
+ const bool mandatory = read();
+
+ const uint32_t valueSize = read();
+ std::vector<uint8_t> value(valueSize);
+ readBlob(valueSize, value.data());
+
+ auto err =
+ mHal->setLayerGenericMetadata(mCurrentDisplay, mCurrentLayer, key, mandatory, value);
+ if (err) {
+ LOG(WARNING) << __func__ << ": err " << err;
+ mWriter->setError(getCommandLoc(), err);
+ }
+
+ return true;
+}
+
+common::Rect ComposerCommandEngine::readRect() {
+ return common::Rect{
+ readSigned(),
+ readSigned(),
+ readSigned(),
+ readSigned(),
+ };
+}
+
+std::vector<common::Rect> ComposerCommandEngine::readRegion(size_t count) {
+ std::vector<common::Rect> region;
+ region.reserve(count);
+ while (count > 0) {
+ region.emplace_back(readRect());
+ count--;
+ }
+
+ return region;
+}
+
+common::FRect ComposerCommandEngine::readFRect() {
+ return common::FRect {
+ readFloat(),
+ readFloat(),
+ readFloat(),
+ readFloat(),
+ };
+}
+
+FloatColor ComposerCommandEngine::readFloatColor() {
+ return FloatColor {
+ readFloat(),
+ readFloat(),
+ readFloat(),
+ readFloat(),
+ };
+}
+
+void ComposerCommandEngine::readBlob(uint32_t size, void* blob) {
+ memcpy(blob, &mData[mDataRead], size);
+ uint32_t numElements = size / sizeof(uint32_t);
+ mDataRead += numElements;
+ mDataRead += (size - numElements * sizeof(uint32_t) != 0) ? 1 : 0;
+}
+
+} // namespace aidl::android::hardware::graphics::composer3::impl