graphics: add ComposerCommandEngine
Add ComposerCommandEngine to the HAL support library to replace
ComposerClient::CommandReader and ComposerClient::mWriter.
Test: boots and VTS
Change-Id: I2d1281d37180497cbd5c623ef005cee44bce377e
diff --git a/graphics/composer/2.1/default/ComposerClient.cpp b/graphics/composer/2.1/default/ComposerClient.cpp
index 807ff81..4fda5ae 100644
--- a/graphics/composer/2.1/default/ComposerClient.cpp
+++ b/graphics/composer/2.1/default/ComposerClient.cpp
@@ -29,7 +29,7 @@
namespace implementation {
ComposerClient::ComposerClient(ComposerHal& hal)
- : mHal(hal), mWriter(kWriterInitialSize)
+ : mHal(hal)
{
}
@@ -106,7 +106,7 @@
LOG_ALWAYS_FATAL("failed to create resources");
}
- mReader = createCommandReader();
+ mCommandEngine = createCommandEngine();
}
void ComposerClient::onHotplug(Display display,
@@ -333,8 +333,8 @@
Return<Error> ComposerClient::setInputCommandQueue(
const MQDescriptorSync<uint32_t>& descriptor)
{
- std::lock_guard<std::mutex> lock(mCommandMutex);
- return mReader->setMQDescriptor(descriptor) ?
+ std::lock_guard<std::mutex> lock(mCommandEngineMutex);
+ return mCommandEngine->setInputMQDescriptor(descriptor) ?
Error::NONE : Error::NO_RESOURCES;
}
@@ -344,7 +344,7 @@
// no locking as we require this function to be called inside
// executeCommands_cb
- auto outDescriptor = mWriter.getMQDescriptor();
+ auto outDescriptor = mCommandEngine->getOutputMQDescriptor();
if (outDescriptor) {
hidl_cb(Error::NONE, *outDescriptor);
} else {
@@ -358,27 +358,17 @@
const hidl_vec<hidl_handle>& inHandles,
executeCommands_cb hidl_cb)
{
- std::lock_guard<std::mutex> lock(mCommandMutex);
+ std::lock_guard<std::mutex> lock(mCommandEngineMutex);
bool outChanged = false;
uint32_t outLength = 0;
hidl_vec<hidl_handle> outHandles;
+ Error error = mCommandEngine->execute(inLength, inHandles,
+ &outChanged, &outLength, &outHandles);
- if (!mReader->readQueue(inLength, inHandles)) {
- hidl_cb(Error::BAD_PARAMETER, outChanged, outLength, outHandles);
- return Void();
- }
+ hidl_cb(error, outChanged, outLength, outHandles);
- Error err = mReader->parse();
- if (err == Error::NONE &&
- !mWriter.writeQueue(&outChanged, &outLength, &outHandles)) {
- err = Error::NO_RESOURCES;
- }
-
- hidl_cb(err, outChanged, outLength, outHandles);
-
- mReader->reset();
- mWriter.reset();
+ mCommandEngine->reset();
return Void();
}
@@ -388,571 +378,10 @@
return ComposerResources::create();
}
-std::unique_ptr<ComposerClient::CommandReader>
-ComposerClient::createCommandReader()
+std::unique_ptr<ComposerCommandEngine>
+ComposerClient::createCommandEngine()
{
- return std::unique_ptr<ComposerClient::CommandReader>(
- new CommandReader(*this));
-}
-
-ComposerClient::CommandReader::CommandReader(ComposerClient& client)
- : mHal(client.mHal), mResources(client.mResources.get()), mWriter(client.mWriter)
-{
-}
-
-ComposerClient::CommandReader::~CommandReader()
-{
-}
-
-Error ComposerClient::CommandReader::parse()
-{
- IComposerClient::Command command;
- uint16_t length = 0;
-
- while (!isEmpty()) {
- if (!beginCommand(&command, &length)) {
- break;
- }
-
- bool parsed = parseCommand(command, length);
- endCommand();
-
- if (!parsed) {
- ALOGE("failed to parse command 0x%x, length %" PRIu16,
- command, length);
- break;
- }
- }
-
- return (isEmpty()) ? Error::NONE : Error::BAD_PARAMETER;
-}
-
-bool ComposerClient::CommandReader::parseCommand(
- IComposerClient::Command command, uint16_t length) {
- switch (command) {
- case IComposerClient::Command::SELECT_DISPLAY:
- return parseSelectDisplay(length);
- case IComposerClient::Command::SELECT_LAYER:
- return parseSelectLayer(length);
- case IComposerClient::Command::SET_COLOR_TRANSFORM:
- return parseSetColorTransform(length);
- case IComposerClient::Command::SET_CLIENT_TARGET:
- return parseSetClientTarget(length);
- case IComposerClient::Command::SET_OUTPUT_BUFFER:
- return parseSetOutputBuffer(length);
- case IComposerClient::Command::VALIDATE_DISPLAY:
- return parseValidateDisplay(length);
- case IComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY:
- return parsePresentOrValidateDisplay(length);
- case IComposerClient::Command::ACCEPT_DISPLAY_CHANGES:
- return parseAcceptDisplayChanges(length);
- case IComposerClient::Command::PRESENT_DISPLAY:
- return parsePresentDisplay(length);
- case IComposerClient::Command::SET_LAYER_CURSOR_POSITION:
- return parseSetLayerCursorPosition(length);
- case IComposerClient::Command::SET_LAYER_BUFFER:
- return parseSetLayerBuffer(length);
- case IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE:
- return parseSetLayerSurfaceDamage(length);
- case IComposerClient::Command::SET_LAYER_BLEND_MODE:
- return parseSetLayerBlendMode(length);
- case IComposerClient::Command::SET_LAYER_COLOR:
- return parseSetLayerColor(length);
- case IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE:
- return parseSetLayerCompositionType(length);
- case IComposerClient::Command::SET_LAYER_DATASPACE:
- return parseSetLayerDataspace(length);
- case IComposerClient::Command::SET_LAYER_DISPLAY_FRAME:
- return parseSetLayerDisplayFrame(length);
- case IComposerClient::Command::SET_LAYER_PLANE_ALPHA:
- return parseSetLayerPlaneAlpha(length);
- case IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM:
- return parseSetLayerSidebandStream(length);
- case IComposerClient::Command::SET_LAYER_SOURCE_CROP:
- return parseSetLayerSourceCrop(length);
- case IComposerClient::Command::SET_LAYER_TRANSFORM:
- return parseSetLayerTransform(length);
- case IComposerClient::Command::SET_LAYER_VISIBLE_REGION:
- return parseSetLayerVisibleRegion(length);
- case IComposerClient::Command::SET_LAYER_Z_ORDER:
- return parseSetLayerZOrder(length);
- default:
- return false;
- }
-}
-
-bool ComposerClient::CommandReader::parseSelectDisplay(uint16_t length)
-{
- if (length != CommandWriterBase::kSelectDisplayLength) {
- return false;
- }
-
- mDisplay = read64();
- mWriter.selectDisplay(mDisplay);
-
- return true;
-}
-
-bool ComposerClient::CommandReader::parseSelectLayer(uint16_t length)
-{
- if (length != CommandWriterBase::kSelectLayerLength) {
- return false;
- }
-
- mLayer = read64();
-
- return true;
-}
-
-bool ComposerClient::CommandReader::parseSetColorTransform(uint16_t length)
-{
- if (length != CommandWriterBase::kSetColorTransformLength) {
- return false;
- }
-
- float matrix[16];
- for (int i = 0; i < 16; i++) {
- matrix[i] = readFloat();
- }
- auto transform = readSigned();
-
- auto err = mHal.setColorTransform(mDisplay, matrix, transform);
- if (err != Error::NONE) {
- mWriter.setError(getCommandLoc(), err);
- }
-
- return true;
-}
-
-bool ComposerClient::CommandReader::parseSetClientTarget(uint16_t length)
-{
- // 4 parameters followed by N rectangles
- if ((length - 4) % 4 != 0) {
- return false;
- }
-
- bool useCache = false;
- auto slot = read();
- auto rawHandle = readHandle(&useCache);
- auto fence = readFence();
- auto dataspace = readSigned();
- auto damage = readRegion((length - 4) / 4);
- bool closeFence = true;
-
- const native_handle_t* clientTarget;
- ComposerResources::ReplacedBufferHandle replacedClientTarget;
- auto err = mResources->getDisplayClientTarget(mDisplay,
- slot, useCache, rawHandle, &clientTarget, &replacedClientTarget);
- if (err == Error::NONE) {
- err = mHal.setClientTarget(mDisplay, clientTarget, fence,
- dataspace, damage);
- if (err == Error::NONE) {
- closeFence = false;
- }
- }
- if (closeFence) {
- close(fence);
- }
- if (err != Error::NONE) {
- mWriter.setError(getCommandLoc(), err);
- }
-
- return true;
-}
-
-bool ComposerClient::CommandReader::parseSetOutputBuffer(uint16_t length)
-{
- if (length != CommandWriterBase::kSetOutputBufferLength) {
- return false;
- }
-
- bool useCache = false;
- auto slot = read();
- auto rawhandle = readHandle(&useCache);
- auto fence = readFence();
- bool closeFence = true;
-
- const native_handle_t* outputBuffer;
- ComposerResources::ReplacedBufferHandle replacedOutputBuffer;
- auto err = mResources->getDisplayOutputBuffer(mDisplay,
- slot, useCache, rawhandle, &outputBuffer, &replacedOutputBuffer);
- if (err == Error::NONE) {
- err = mHal.setOutputBuffer(mDisplay, outputBuffer, fence);
- if (err == Error::NONE) {
- closeFence = false;
- }
- }
- if (closeFence) {
- close(fence);
- }
- if (err != Error::NONE) {
- mWriter.setError(getCommandLoc(), err);
- }
-
- return true;
-}
-
-bool ComposerClient::CommandReader::parseValidateDisplay(uint16_t length)
-{
- if (length != CommandWriterBase::kValidateDisplayLength) {
- return false;
- }
-
- std::vector<Layer> changedLayers;
- std::vector<IComposerClient::Composition> compositionTypes;
- uint32_t displayRequestMask = 0x0;
- std::vector<Layer> requestedLayers;
- std::vector<uint32_t> requestMasks;
-
- auto err = mHal.validateDisplay(mDisplay, &changedLayers,
- &compositionTypes, &displayRequestMask,
- &requestedLayers, &requestMasks);
- if (err == Error::NONE) {
- mWriter.setChangedCompositionTypes(changedLayers,
- compositionTypes);
- mWriter.setDisplayRequests(displayRequestMask,
- requestedLayers, requestMasks);
- } else {
- mWriter.setError(getCommandLoc(), err);
- }
-
- return true;
-}
-
-bool ComposerClient::CommandReader::parsePresentOrValidateDisplay(uint16_t length)
-{
- if (length != CommandWriterBase::kPresentOrValidateDisplayLength) {
- return false;
- }
-
- // First try to Present as is.
- if (mHal.hasCapability(HWC2_CAPABILITY_SKIP_VALIDATE)) {
- int presentFence = -1;
- std::vector<Layer> layers;
- std::vector<int> fences;
- auto err = mHal.presentDisplay(mDisplay, &presentFence, &layers, &fences);
- if (err == Error::NONE) {
- mWriter.setPresentOrValidateResult(1);
- mWriter.setPresentFence(presentFence);
- mWriter.setReleaseFences(layers, fences);
- return true;
- }
- }
-
- // Present has failed. We need to fallback to validate
- std::vector<Layer> changedLayers;
- std::vector<IComposerClient::Composition> compositionTypes;
- uint32_t displayRequestMask = 0x0;
- std::vector<Layer> requestedLayers;
- std::vector<uint32_t> requestMasks;
-
- auto err = mHal.validateDisplay(mDisplay, &changedLayers, &compositionTypes,
- &displayRequestMask, &requestedLayers, &requestMasks);
- if (err == Error::NONE) {
- mWriter.setPresentOrValidateResult(0);
- mWriter.setChangedCompositionTypes(changedLayers,
- compositionTypes);
- mWriter.setDisplayRequests(displayRequestMask,
- requestedLayers, requestMasks);
- } else {
- mWriter.setError(getCommandLoc(), err);
- }
-
- return true;
-}
-
-bool ComposerClient::CommandReader::parseAcceptDisplayChanges(uint16_t length)
-{
- if (length != CommandWriterBase::kAcceptDisplayChangesLength) {
- return false;
- }
-
- auto err = mHal.acceptDisplayChanges(mDisplay);
- if (err != Error::NONE) {
- mWriter.setError(getCommandLoc(), err);
- }
-
- return true;
-}
-
-bool ComposerClient::CommandReader::parsePresentDisplay(uint16_t length)
-{
- if (length != CommandWriterBase::kPresentDisplayLength) {
- return false;
- }
-
- int presentFence = -1;
- std::vector<Layer> layers;
- std::vector<int> fences;
- auto err = mHal.presentDisplay(mDisplay, &presentFence, &layers, &fences);
- if (err == Error::NONE) {
- mWriter.setPresentFence(presentFence);
- mWriter.setReleaseFences(layers, fences);
- } else {
- mWriter.setError(getCommandLoc(), err);
- }
-
- return true;
-}
-
-bool ComposerClient::CommandReader::parseSetLayerCursorPosition(uint16_t length)
-{
- if (length != CommandWriterBase::kSetLayerCursorPositionLength) {
- return false;
- }
-
- auto err = mHal.setLayerCursorPosition(mDisplay, mLayer,
- readSigned(), readSigned());
- if (err != Error::NONE) {
- mWriter.setError(getCommandLoc(), err);
- }
-
- return true;
-}
-
-bool ComposerClient::CommandReader::parseSetLayerBuffer(uint16_t length)
-{
- if (length != CommandWriterBase::kSetLayerBufferLength) {
- return false;
- }
-
- bool useCache = false;
- auto slot = read();
- auto rawHandle = readHandle(&useCache);
- auto fence = readFence();
- bool closeFence = true;
-
- const native_handle_t* buffer;
- ComposerResources::ReplacedBufferHandle replacedBuffer;
- auto err = mResources->getLayerBuffer(mDisplay, mLayer,
- slot, useCache, rawHandle, &buffer, &replacedBuffer);
- if (err == Error::NONE) {
- err = mHal.setLayerBuffer(mDisplay, mLayer, buffer, fence);
- if (err == Error::NONE) {
- closeFence = false;
- }
- }
- if (closeFence) {
- close(fence);
- }
- if (err != Error::NONE) {
- mWriter.setError(getCommandLoc(), err);
- }
-
- return true;
-}
-
-bool ComposerClient::CommandReader::parseSetLayerSurfaceDamage(uint16_t length)
-{
- // N rectangles
- if (length % 4 != 0) {
- return false;
- }
-
- auto damage = readRegion(length / 4);
- auto err = mHal.setLayerSurfaceDamage(mDisplay, mLayer, damage);
- if (err != Error::NONE) {
- mWriter.setError(getCommandLoc(), err);
- }
-
- return true;
-}
-
-bool ComposerClient::CommandReader::parseSetLayerBlendMode(uint16_t length)
-{
- if (length != CommandWriterBase::kSetLayerBlendModeLength) {
- return false;
- }
-
- auto err = mHal.setLayerBlendMode(mDisplay, mLayer, readSigned());
- if (err != Error::NONE) {
- mWriter.setError(getCommandLoc(), err);
- }
-
- return true;
-}
-
-bool ComposerClient::CommandReader::parseSetLayerColor(uint16_t length)
-{
- if (length != CommandWriterBase::kSetLayerColorLength) {
- return false;
- }
-
- auto err = mHal.setLayerColor(mDisplay, mLayer, readColor());
- if (err != Error::NONE) {
- mWriter.setError(getCommandLoc(), err);
- }
-
- return true;
-}
-
-bool ComposerClient::CommandReader::parseSetLayerCompositionType(
- uint16_t length)
-{
- if (length != CommandWriterBase::kSetLayerCompositionTypeLength) {
- return false;
- }
-
- auto err = mHal.setLayerCompositionType(mDisplay, mLayer, readSigned());
- if (err != Error::NONE) {
- mWriter.setError(getCommandLoc(), err);
- }
-
- return true;
-}
-
-bool ComposerClient::CommandReader::parseSetLayerDataspace(uint16_t length)
-{
- if (length != CommandWriterBase::kSetLayerDataspaceLength) {
- return false;
- }
-
- auto err = mHal.setLayerDataspace(mDisplay, mLayer, readSigned());
- if (err != Error::NONE) {
- mWriter.setError(getCommandLoc(), err);
- }
-
- return true;
-}
-
-bool ComposerClient::CommandReader::parseSetLayerDisplayFrame(uint16_t length)
-{
- if (length != CommandWriterBase::kSetLayerDisplayFrameLength) {
- return false;
- }
-
- auto err = mHal.setLayerDisplayFrame(mDisplay, mLayer, readRect());
- if (err != Error::NONE) {
- mWriter.setError(getCommandLoc(), err);
- }
-
- return true;
-}
-
-bool ComposerClient::CommandReader::parseSetLayerPlaneAlpha(uint16_t length)
-{
- if (length != CommandWriterBase::kSetLayerPlaneAlphaLength) {
- return false;
- }
-
- auto err = mHal.setLayerPlaneAlpha(mDisplay, mLayer, readFloat());
- if (err != Error::NONE) {
- mWriter.setError(getCommandLoc(), err);
- }
-
- return true;
-}
-
-bool ComposerClient::CommandReader::parseSetLayerSidebandStream(uint16_t length)
-{
- if (length != CommandWriterBase::kSetLayerSidebandStreamLength) {
- return false;
- }
-
- auto rawHandle = readHandle();
-
- const native_handle_t* stream;
- ComposerResources::ReplacedStreamHandle replacedStream;
- auto err = mResources->getLayerSidebandStream(mDisplay, mLayer,
- rawHandle, &stream, &replacedStream);
- if (err == Error::NONE) {
- err = mHal.setLayerSidebandStream(mDisplay, mLayer, stream);
- }
- if (err != Error::NONE) {
- mWriter.setError(getCommandLoc(), err);
- }
-
- return true;
-}
-
-bool ComposerClient::CommandReader::parseSetLayerSourceCrop(uint16_t length)
-{
- if (length != CommandWriterBase::kSetLayerSourceCropLength) {
- return false;
- }
-
- auto err = mHal.setLayerSourceCrop(mDisplay, mLayer, readFRect());
- if (err != Error::NONE) {
- mWriter.setError(getCommandLoc(), err);
- }
-
- return true;
-}
-
-bool ComposerClient::CommandReader::parseSetLayerTransform(uint16_t length)
-{
- if (length != CommandWriterBase::kSetLayerTransformLength) {
- return false;
- }
-
- auto err = mHal.setLayerTransform(mDisplay, mLayer, readSigned());
- if (err != Error::NONE) {
- mWriter.setError(getCommandLoc(), err);
- }
-
- return true;
-}
-
-bool ComposerClient::CommandReader::parseSetLayerVisibleRegion(uint16_t length)
-{
- // N rectangles
- if (length % 4 != 0) {
- return false;
- }
-
- auto region = readRegion(length / 4);
- auto err = mHal.setLayerVisibleRegion(mDisplay, mLayer, region);
- if (err != Error::NONE) {
- mWriter.setError(getCommandLoc(), err);
- }
-
- return true;
-}
-
-bool ComposerClient::CommandReader::parseSetLayerZOrder(uint16_t length)
-{
- if (length != CommandWriterBase::kSetLayerZOrderLength) {
- return false;
- }
-
- auto err = mHal.setLayerZOrder(mDisplay, mLayer, read());
- if (err != Error::NONE) {
- mWriter.setError(getCommandLoc(), err);
- }
-
- return true;
-}
-
-hwc_rect_t ComposerClient::CommandReader::readRect()
-{
- return hwc_rect_t{
- readSigned(),
- readSigned(),
- readSigned(),
- readSigned(),
- };
-}
-
-std::vector<hwc_rect_t> ComposerClient::CommandReader::readRegion(size_t count)
-{
- std::vector<hwc_rect_t> region;
- region.reserve(count);
- while (count > 0) {
- region.emplace_back(readRect());
- count--;
- }
-
- return region;
-}
-
-hwc_frect_t ComposerClient::CommandReader::readFRect()
-{
- return hwc_frect_t{
- readFloat(),
- readFloat(),
- readFloat(),
- readFloat(),
- };
+ return std::make_unique<ComposerCommandEngine>(&mHal, mResources.get());
}
} // namespace implementation
diff --git a/graphics/composer/2.1/default/ComposerClient.h b/graphics/composer/2.1/default/ComposerClient.h
index ee71492..bbb0522 100644
--- a/graphics/composer/2.1/default/ComposerClient.h
+++ b/graphics/composer/2.1/default/ComposerClient.h
@@ -22,6 +22,7 @@
#include <vector>
#include <composer-command-buffer/2.1/ComposerCommandBuffer.h>
+#include <composer-hal/2.1/ComposerCommandEngine.h>
#include <composer-hal/2.1/ComposerHal.h>
#include <composer-hal/2.1/ComposerResources.h>
#include <hardware/hwcomposer2.h>
@@ -92,68 +93,17 @@
executeCommands_cb hidl_cb) override;
protected:
- class CommandReader : public CommandReaderBase {
- public:
- CommandReader(ComposerClient& client);
- virtual ~CommandReader();
-
- Error parse();
-
- protected:
- virtual bool parseCommand(IComposerClient::Command command,
- uint16_t length);
-
- bool parseSelectDisplay(uint16_t length);
- bool parseSelectLayer(uint16_t length);
- bool parseSetColorTransform(uint16_t length);
- bool parseSetClientTarget(uint16_t length);
- bool parseSetOutputBuffer(uint16_t length);
- bool parseValidateDisplay(uint16_t length);
- bool parsePresentOrValidateDisplay(uint16_t length);
- bool parseAcceptDisplayChanges(uint16_t length);
- bool parsePresentDisplay(uint16_t length);
- bool parseSetLayerCursorPosition(uint16_t length);
- bool parseSetLayerBuffer(uint16_t length);
- bool parseSetLayerSurfaceDamage(uint16_t length);
- bool parseSetLayerBlendMode(uint16_t length);
- bool parseSetLayerColor(uint16_t length);
- bool parseSetLayerCompositionType(uint16_t length);
- bool parseSetLayerDataspace(uint16_t length);
- bool parseSetLayerDisplayFrame(uint16_t length);
- bool parseSetLayerPlaneAlpha(uint16_t length);
- bool parseSetLayerSidebandStream(uint16_t length);
- bool parseSetLayerSourceCrop(uint16_t length);
- bool parseSetLayerTransform(uint16_t length);
- bool parseSetLayerVisibleRegion(uint16_t length);
- bool parseSetLayerZOrder(uint16_t length);
-
- hwc_rect_t readRect();
- std::vector<hwc_rect_t> readRegion(size_t count);
- hwc_frect_t readFRect();
-
- ComposerHal& mHal;
- ComposerResources* mResources;
- CommandWriterBase& mWriter;
-
- Display mDisplay;
- Layer mLayer;
- };
+ virtual std::unique_ptr<ComposerResources> createResources();
+ virtual std::unique_ptr<ComposerCommandEngine> createCommandEngine();
void destroyResources();
- virtual std::unique_ptr<ComposerResources> createResources();
- virtual std::unique_ptr<CommandReader> createCommandReader();
-
ComposerHal& mHal;
std::unique_ptr<ComposerResources> mResources;
- // 64KiB minus a small space for metadata such as read/write pointers
- static constexpr size_t kWriterInitialSize =
- 64 * 1024 / sizeof(uint32_t) - 16;
- std::mutex mCommandMutex;
- std::unique_ptr<CommandReader> mReader;
- CommandWriterBase mWriter;
+ std::mutex mCommandEngineMutex;
+ std::unique_ptr<ComposerCommandEngine> mCommandEngine;
sp<IComposerCallback> mCallback;
};
diff --git a/graphics/composer/2.1/utils/hal/Android.bp b/graphics/composer/2.1/utils/hal/Android.bp
index a8ff59d..f24e768 100644
--- a/graphics/composer/2.1/utils/hal/Android.bp
+++ b/graphics/composer/2.1/utils/hal/Android.bp
@@ -27,5 +27,11 @@
"android.hardware.graphics.mapper@2.0",
"libhardware",
],
+ header_libs: [
+ "android.hardware.graphics.composer@2.1-command-buffer",
+ ],
+ export_header_lib_headers: [
+ "android.hardware.graphics.composer@2.1-command-buffer",
+ ],
export_include_dirs: ["include"],
}
diff --git a/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerCommandEngine.h b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerCommandEngine.h
new file mode 100644
index 0000000..36aa64e
--- /dev/null
+++ b/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerCommandEngine.h
@@ -0,0 +1,594 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#pragma once
+
+#ifndef LOG_TAG
+#warning "ComposerCommandEngine.h included without LOG_TAG"
+#endif
+
+#include <vector>
+
+#include <composer-command-buffer/2.1/ComposerCommandBuffer.h>
+#include <composer-hal/2.1/ComposerHal.h>
+#include <composer-hal/2.1/ComposerResources.h>
+// TODO remove hwcomposer_defs.h dependency
+#include <hardware/hwcomposer_defs.h>
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace composer {
+namespace V2_1 {
+namespace hal {
+
+// TODO own a CommandReaderBase rather than subclassing
+class ComposerCommandEngine : protected CommandReaderBase {
+ public:
+ ComposerCommandEngine(ComposerHal* hal, ComposerResources* resources)
+ : mHal(hal), mResources(resources) {}
+
+ virtual ~ComposerCommandEngine() = default;
+
+ bool setInputMQDescriptor(const MQDescriptorSync<uint32_t>& descriptor) {
+ return setMQDescriptor(descriptor);
+ }
+
+ Error execute(uint32_t inLength, const hidl_vec<hidl_handle>& inHandles, bool* outQueueChanged,
+ uint32_t* outCommandLength, hidl_vec<hidl_handle>* outCommandHandles) {
+ if (!readQueue(inLength, inHandles)) {
+ return Error::BAD_PARAMETER;
+ }
+
+ IComposerClient::Command command;
+ uint16_t length = 0;
+ while (!isEmpty()) {
+ if (!beginCommand(&command, &length)) {
+ break;
+ }
+
+ bool parsed = executeCommand(command, length);
+ endCommand();
+
+ if (!parsed) {
+ ALOGE("failed to parse command 0x%x, length %" PRIu16, command, length);
+ break;
+ }
+ }
+
+ if (!isEmpty()) {
+ return Error::BAD_PARAMETER;
+ }
+
+ return mWriter.writeQueue(outQueueChanged, outCommandLength, outCommandHandles)
+ ? Error::NONE
+ : Error::NO_RESOURCES;
+ }
+
+ const MQDescriptorSync<uint32_t>* getOutputMQDescriptor() { return mWriter.getMQDescriptor(); }
+
+ void reset() {
+ CommandReaderBase::reset();
+ mWriter.reset();
+ }
+
+ protected:
+ virtual bool executeCommand(IComposerClient::Command command, uint16_t length) {
+ switch (command) {
+ case IComposerClient::Command::SELECT_DISPLAY:
+ return executeSelectDisplay(length);
+ case IComposerClient::Command::SELECT_LAYER:
+ return executeSelectLayer(length);
+ case IComposerClient::Command::SET_COLOR_TRANSFORM:
+ return executeSetColorTransform(length);
+ case IComposerClient::Command::SET_CLIENT_TARGET:
+ return executeSetClientTarget(length);
+ case IComposerClient::Command::SET_OUTPUT_BUFFER:
+ return executeSetOutputBuffer(length);
+ case IComposerClient::Command::VALIDATE_DISPLAY:
+ return executeValidateDisplay(length);
+ case IComposerClient::Command::PRESENT_OR_VALIDATE_DISPLAY:
+ return executePresentOrValidateDisplay(length);
+ case IComposerClient::Command::ACCEPT_DISPLAY_CHANGES:
+ return executeAcceptDisplayChanges(length);
+ case IComposerClient::Command::PRESENT_DISPLAY:
+ return executePresentDisplay(length);
+ case IComposerClient::Command::SET_LAYER_CURSOR_POSITION:
+ return executeSetLayerCursorPosition(length);
+ case IComposerClient::Command::SET_LAYER_BUFFER:
+ return executeSetLayerBuffer(length);
+ case IComposerClient::Command::SET_LAYER_SURFACE_DAMAGE:
+ return executeSetLayerSurfaceDamage(length);
+ case IComposerClient::Command::SET_LAYER_BLEND_MODE:
+ return executeSetLayerBlendMode(length);
+ case IComposerClient::Command::SET_LAYER_COLOR:
+ return executeSetLayerColor(length);
+ case IComposerClient::Command::SET_LAYER_COMPOSITION_TYPE:
+ return executeSetLayerCompositionType(length);
+ case IComposerClient::Command::SET_LAYER_DATASPACE:
+ return executeSetLayerDataspace(length);
+ case IComposerClient::Command::SET_LAYER_DISPLAY_FRAME:
+ return executeSetLayerDisplayFrame(length);
+ case IComposerClient::Command::SET_LAYER_PLANE_ALPHA:
+ return executeSetLayerPlaneAlpha(length);
+ case IComposerClient::Command::SET_LAYER_SIDEBAND_STREAM:
+ return executeSetLayerSidebandStream(length);
+ case IComposerClient::Command::SET_LAYER_SOURCE_CROP:
+ return executeSetLayerSourceCrop(length);
+ case IComposerClient::Command::SET_LAYER_TRANSFORM:
+ return executeSetLayerTransform(length);
+ case IComposerClient::Command::SET_LAYER_VISIBLE_REGION:
+ return executeSetLayerVisibleRegion(length);
+ case IComposerClient::Command::SET_LAYER_Z_ORDER:
+ return executeSetLayerZOrder(length);
+ default:
+ return false;
+ }
+ }
+
+ bool executeSelectDisplay(uint16_t length) {
+ if (length != CommandWriterBase::kSelectDisplayLength) {
+ return false;
+ }
+
+ mCurrentDisplay = read64();
+ mWriter.selectDisplay(mCurrentDisplay);
+
+ return true;
+ }
+
+ bool executeSelectLayer(uint16_t length) {
+ if (length != CommandWriterBase::kSelectLayerLength) {
+ return false;
+ }
+
+ mCurrentLayer = read64();
+
+ return true;
+ }
+
+ bool executeSetColorTransform(uint16_t length) {
+ if (length != CommandWriterBase::kSetColorTransformLength) {
+ return false;
+ }
+
+ 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 != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+ }
+
+ bool executeSetClientTarget(uint16_t length) {
+ // 4 parameters followed by N rectangles
+ if ((length - 4) % 4 != 0) {
+ return false;
+ }
+
+ bool useCache = false;
+ auto slot = read();
+ auto rawHandle = readHandle(&useCache);
+ auto fence = readFence();
+ auto dataspace = readSigned();
+ auto damage = readRegion((length - 4) / 4);
+ bool closeFence = true;
+
+ const native_handle_t* clientTarget;
+ ComposerResources::ReplacedBufferHandle replacedClientTarget;
+ auto err = mResources->getDisplayClientTarget(mCurrentDisplay, slot, useCache, rawHandle,
+ &clientTarget, &replacedClientTarget);
+ if (err == Error::NONE) {
+ err = mHal->setClientTarget(mCurrentDisplay, clientTarget, fence, dataspace, damage);
+ if (err == Error::NONE) {
+ closeFence = false;
+ }
+ }
+ if (closeFence) {
+ close(fence);
+ }
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+ }
+
+ bool executeSetOutputBuffer(uint16_t length) {
+ if (length != CommandWriterBase::kSetOutputBufferLength) {
+ return false;
+ }
+
+ bool useCache = false;
+ auto slot = read();
+ auto rawhandle = readHandle(&useCache);
+ auto fence = readFence();
+ bool closeFence = true;
+
+ const native_handle_t* outputBuffer;
+ ComposerResources::ReplacedBufferHandle replacedOutputBuffer;
+ auto err = mResources->getDisplayOutputBuffer(mCurrentDisplay, slot, useCache, rawhandle,
+ &outputBuffer, &replacedOutputBuffer);
+ if (err == Error::NONE) {
+ err = mHal->setOutputBuffer(mCurrentDisplay, outputBuffer, fence);
+ if (err == Error::NONE) {
+ closeFence = false;
+ }
+ }
+ if (closeFence) {
+ close(fence);
+ }
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+ }
+
+ bool executeValidateDisplay(uint16_t length) {
+ if (length != CommandWriterBase::kValidateDisplayLength) {
+ return false;
+ }
+
+ std::vector<Layer> changedLayers;
+ std::vector<IComposerClient::Composition> compositionTypes;
+ uint32_t displayRequestMask = 0x0;
+ std::vector<Layer> requestedLayers;
+ std::vector<uint32_t> requestMasks;
+
+ auto err = mHal->validateDisplay(mCurrentDisplay, &changedLayers, &compositionTypes,
+ &displayRequestMask, &requestedLayers, &requestMasks);
+ if (err == Error::NONE) {
+ mWriter.setChangedCompositionTypes(changedLayers, compositionTypes);
+ mWriter.setDisplayRequests(displayRequestMask, requestedLayers, requestMasks);
+ } else {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+ }
+
+ bool executePresentOrValidateDisplay(uint16_t length) {
+ if (length != CommandWriterBase::kPresentOrValidateDisplayLength) {
+ return false;
+ }
+
+ // First try to Present as is.
+ if (mHal->hasCapability(HWC2_CAPABILITY_SKIP_VALIDATE)) {
+ int presentFence = -1;
+ std::vector<Layer> layers;
+ std::vector<int> fences;
+ auto err = mHal->presentDisplay(mCurrentDisplay, &presentFence, &layers, &fences);
+ if (err == Error::NONE) {
+ mWriter.setPresentOrValidateResult(1);
+ mWriter.setPresentFence(presentFence);
+ mWriter.setReleaseFences(layers, fences);
+ return true;
+ }
+ }
+
+ // Present has failed. We need to fallback to validate
+ std::vector<Layer> changedLayers;
+ std::vector<IComposerClient::Composition> compositionTypes;
+ uint32_t displayRequestMask = 0x0;
+ std::vector<Layer> requestedLayers;
+ std::vector<uint32_t> requestMasks;
+
+ auto err = mHal->validateDisplay(mCurrentDisplay, &changedLayers, &compositionTypes,
+ &displayRequestMask, &requestedLayers, &requestMasks);
+ if (err == Error::NONE) {
+ mWriter.setPresentOrValidateResult(0);
+ mWriter.setChangedCompositionTypes(changedLayers, compositionTypes);
+ mWriter.setDisplayRequests(displayRequestMask, requestedLayers, requestMasks);
+ } else {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+ }
+
+ bool executeAcceptDisplayChanges(uint16_t length) {
+ if (length != CommandWriterBase::kAcceptDisplayChangesLength) {
+ return false;
+ }
+
+ auto err = mHal->acceptDisplayChanges(mCurrentDisplay);
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+ }
+
+ bool executePresentDisplay(uint16_t length) {
+ if (length != CommandWriterBase::kPresentDisplayLength) {
+ return false;
+ }
+
+ int presentFence = -1;
+ std::vector<Layer> layers;
+ std::vector<int> fences;
+ auto err = mHal->presentDisplay(mCurrentDisplay, &presentFence, &layers, &fences);
+ if (err == Error::NONE) {
+ mWriter.setPresentFence(presentFence);
+ mWriter.setReleaseFences(layers, fences);
+ } else {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+ }
+
+ bool executeSetLayerCursorPosition(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerCursorPositionLength) {
+ return false;
+ }
+
+ auto err = mHal->setLayerCursorPosition(mCurrentDisplay, mCurrentLayer, readSigned(),
+ readSigned());
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+ }
+
+ bool executeSetLayerBuffer(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerBufferLength) {
+ return false;
+ }
+
+ bool useCache = false;
+ auto slot = read();
+ auto rawHandle = readHandle(&useCache);
+ auto fence = readFence();
+ bool closeFence = true;
+
+ const native_handle_t* buffer;
+ ComposerResources::ReplacedBufferHandle replacedBuffer;
+ auto err = mResources->getLayerBuffer(mCurrentDisplay, mCurrentLayer, slot, useCache,
+ rawHandle, &buffer, &replacedBuffer);
+ if (err == Error::NONE) {
+ err = mHal->setLayerBuffer(mCurrentDisplay, mCurrentLayer, buffer, fence);
+ if (err == Error::NONE) {
+ closeFence = false;
+ }
+ }
+ if (closeFence) {
+ close(fence);
+ }
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+ }
+
+ bool 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 != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+ }
+
+ bool executeSetLayerBlendMode(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerBlendModeLength) {
+ return false;
+ }
+
+ auto err = mHal->setLayerBlendMode(mCurrentDisplay, mCurrentLayer, readSigned());
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+ }
+
+ bool executeSetLayerColor(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerColorLength) {
+ return false;
+ }
+
+ auto err = mHal->setLayerColor(mCurrentDisplay, mCurrentLayer, readColor());
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+ }
+
+ bool executeSetLayerCompositionType(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerCompositionTypeLength) {
+ return false;
+ }
+
+ auto err = mHal->setLayerCompositionType(mCurrentDisplay, mCurrentLayer, readSigned());
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+ }
+
+ bool executeSetLayerDataspace(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerDataspaceLength) {
+ return false;
+ }
+
+ auto err = mHal->setLayerDataspace(mCurrentDisplay, mCurrentLayer, readSigned());
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+ }
+
+ bool executeSetLayerDisplayFrame(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerDisplayFrameLength) {
+ return false;
+ }
+
+ auto err = mHal->setLayerDisplayFrame(mCurrentDisplay, mCurrentLayer, readRect());
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+ }
+
+ bool executeSetLayerPlaneAlpha(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerPlaneAlphaLength) {
+ return false;
+ }
+
+ auto err = mHal->setLayerPlaneAlpha(mCurrentDisplay, mCurrentLayer, readFloat());
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+ }
+
+ bool executeSetLayerSidebandStream(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerSidebandStreamLength) {
+ return false;
+ }
+
+ auto rawHandle = readHandle();
+
+ const native_handle_t* stream;
+ ComposerResources::ReplacedStreamHandle replacedStream;
+ auto err = mResources->getLayerSidebandStream(mCurrentDisplay, mCurrentLayer, rawHandle,
+ &stream, &replacedStream);
+ if (err == Error::NONE) {
+ err = mHal->setLayerSidebandStream(mCurrentDisplay, mCurrentLayer, stream);
+ }
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+ }
+
+ bool executeSetLayerSourceCrop(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerSourceCropLength) {
+ return false;
+ }
+
+ auto err = mHal->setLayerSourceCrop(mCurrentDisplay, mCurrentLayer, readFRect());
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+ }
+
+ bool executeSetLayerTransform(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerTransformLength) {
+ return false;
+ }
+
+ auto err = mHal->setLayerTransform(mCurrentDisplay, mCurrentLayer, readSigned());
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+ }
+
+ bool 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 != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+ }
+
+ bool executeSetLayerZOrder(uint16_t length) {
+ if (length != CommandWriterBase::kSetLayerZOrderLength) {
+ return false;
+ }
+
+ auto err = mHal->setLayerZOrder(mCurrentDisplay, mCurrentLayer, read());
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ return true;
+ }
+
+ hwc_rect_t readRect() {
+ return hwc_rect_t{
+ readSigned(), readSigned(), readSigned(), readSigned(),
+ };
+ }
+
+ std::vector<hwc_rect_t> readRegion(size_t count) {
+ std::vector<hwc_rect_t> region;
+ region.reserve(count);
+ while (count > 0) {
+ region.emplace_back(readRect());
+ count--;
+ }
+
+ return region;
+ }
+
+ hwc_frect_t readFRect() {
+ return hwc_frect_t{
+ readFloat(), readFloat(), readFloat(), readFloat(),
+ };
+ }
+
+ ComposerHal* mHal;
+ ComposerResources* mResources;
+
+ // 64KiB minus a small space for metadata such as read/write pointers
+ static constexpr size_t kWriterInitialSize = 64 * 1024 / sizeof(uint32_t) - 16;
+ CommandWriterBase mWriter{kWriterInitialSize};
+
+ Display mCurrentDisplay = 0;
+ Layer mCurrentLayer = 0;
+};
+
+} // namespace hal
+} // namespace V2_1
+} // namespace composer
+} // namespace graphics
+} // namespace hardware
+} // namespace android