diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp index 8726043cf2..34dea9ecc2 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_ReadbackTest.cpp @@ -167,8 +167,8 @@ class GraphicsCompositionTestBase : public ::testing::Test { int32_t mDisplayWidth; int32_t mDisplayHeight; std::vector mTestColorModes; - CommandWriterBase mWriter; - CommandReaderBase mReader; + ComposerClientWriter mWriter; + ComposerClientReader mReader; ::android::sp<::android::GraphicBuffer> mGraphicBuffer; std::unique_ptr mTestRenderEngine; diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp index 39825c4ed0..1f30475737 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp @@ -13,7 +13,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -1408,8 +1409,8 @@ class GraphicsComposerAidlCommandTest : public GraphicsComposerAidlTest { }}; // clang-format on - CommandWriterBase mWriter; - CommandReaderBase mReader; + ComposerClientWriter mWriter; + ComposerClientReader mReader; }; TEST_P(GraphicsComposerAidlCommandTest, SET_COLOR_TRANSFORM) { diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp index a6954b4625..4de2d71441 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/ReadbackVts.cpp @@ -32,7 +32,7 @@ const std::vector ReadbackHelper::colorModes = {ColorMode::SRGB, Colo const std::vector ReadbackHelper::dataspaces = {common::Dataspace::SRGB, common::Dataspace::DISPLAY_P3}; -void TestLayer::write(CommandWriterBase& writer) { +void TestLayer::write(ComposerClientWriter& writer) { writer.setLayerDisplayFrame(mDisplay, mLayer, mDisplayFrame); writer.setLayerSourceCrop(mDisplay, mLayer, mSourceCrop); writer.setLayerZOrder(mDisplay, mLayer, mZOrder); @@ -253,7 +253,7 @@ void ReadbackBuffer::checkReadbackBuffer(std::vector expectedColors) { EXPECT_EQ(::android::OK, status); } -void TestColorLayer::write(CommandWriterBase& writer) { +void TestColorLayer::write(ComposerClientWriter& writer) { TestLayer::write(writer); writer.setLayerCompositionType(mDisplay, mLayer, Composition::SOLID_COLOR); writer.setLayerColor(mDisplay, mLayer, mColor); @@ -296,7 +296,7 @@ TestBufferLayer::TestBufferLayer(const std::shared_ptr& client, setSourceCrop({0, 0, (float)width, (float)height}); } -void TestBufferLayer::write(CommandWriterBase& writer) { +void TestBufferLayer::write(ComposerClientWriter& writer) { TestLayer::write(writer); writer.setLayerCompositionType(mDisplay, mLayer, mComposition); writer.setLayerVisibleRegion(mDisplay, mLayer, std::vector(1, mDisplayFrame)); @@ -345,11 +345,11 @@ void TestBufferLayer::setBuffer(std::vector colors) { ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck()); } -void TestBufferLayer::setDataspace(common::Dataspace dataspace, CommandWriterBase& writer) { +void TestBufferLayer::setDataspace(common::Dataspace dataspace, ComposerClientWriter& writer) { writer.setLayerDataspace(mDisplay, mLayer, dataspace); } -void TestBufferLayer::setToClientComposition(CommandWriterBase& writer) { +void TestBufferLayer::setToClientComposition(ComposerClientWriter& writer) { writer.setLayerCompositionType(mDisplay, mLayer, Composition::CLIENT); } diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h index d40e3d2d18..60a036e3fd 100644 --- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h +++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/composer-vts/include/ReadbackVts.h @@ -23,7 +23,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -61,7 +62,7 @@ class TestLayer { // call destroyLayers here virtual ~TestLayer(){}; - virtual void write(CommandWriterBase& writer); + virtual void write(ComposerClientWriter& writer); virtual LayerSettings toRenderEngineLayerSettings(); void setDisplayFrame(Rect frame) { mDisplayFrame = frame; } @@ -105,7 +106,7 @@ class TestColorLayer : public TestLayer { TestColorLayer(const std::shared_ptr& client, int64_t display) : TestLayer{client, display} {} - void write(CommandWriterBase& writer) override; + void write(ComposerClientWriter& writer) override; LayerSettings toRenderEngineLayerSettings() override; @@ -123,7 +124,7 @@ class TestBufferLayer : public TestLayer { uint32_t height, common::PixelFormat format, Composition composition = Composition::DEVICE); - void write(CommandWriterBase& writer) override; + void write(ComposerClientWriter& writer) override; LayerSettings toRenderEngineLayerSettings() override; @@ -131,9 +132,9 @@ class TestBufferLayer : public TestLayer { void setBuffer(std::vector colors); - void setDataspace(Dataspace dataspace, CommandWriterBase& writer); + void setDataspace(Dataspace dataspace, ComposerClientWriter& writer); - void setToClientComposition(CommandWriterBase& writer); + void setToClientComposition(ComposerClientWriter& writer); uint32_t getWidth() const { return mWidth; } diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h new file mode 100644 index 0000000000..1dc914555c --- /dev/null +++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientReader.h @@ -0,0 +1,319 @@ +/* + * Copyright 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. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include + +using aidl::android::hardware::graphics::common::BlendMode; +using aidl::android::hardware::graphics::common::ColorTransform; +using aidl::android::hardware::graphics::common::Dataspace; +using aidl::android::hardware::graphics::common::FRect; +using aidl::android::hardware::graphics::common::Rect; +using aidl::android::hardware::graphics::common::Transform; + +using namespace aidl::android::hardware::graphics::composer3; + +using aidl::android::hardware::common::NativeHandle; + +namespace aidl::android::hardware::graphics::composer3 { + +class ComposerClientReader { + public: + ~ComposerClientReader() { resetData(); } + + // Parse and execute commands from the command queue. The commands are + // actually return values from the server and will be saved in ReturnData. + void parse(const std::vector& results) { + resetData(); + + for (const auto& result : results) { + switch (result.getTag()) { + case CommandResultPayload::Tag::error: + parseSetError(result.get()); + break; + case CommandResultPayload::Tag::changedCompositionTypes: + parseSetChangedCompositionTypes( + result.get()); + break; + case CommandResultPayload::Tag::displayRequest: + parseSetDisplayRequests( + result.get()); + break; + case CommandResultPayload::Tag::presentFence: + parseSetPresentFence(result.get()); + break; + case CommandResultPayload::Tag::releaseFences: + parseSetReleaseFences(result.get()); + break; + case CommandResultPayload::Tag::presentOrValidateResult: + parseSetPresentOrValidateDisplayResult( + result.get()); + break; + case CommandResultPayload::Tag::clientTargetProperty: + parseSetClientTargetProperty( + result.get()); + break; + } + } + } + + std::vector takeErrors() { return std::move(mErrors); } + + bool hasChanges(int64_t display, uint32_t* outNumChangedCompositionTypes, + uint32_t* outNumLayerRequestMasks) const { + auto found = mReturnData.find(display); + if (found == mReturnData.end()) { + *outNumChangedCompositionTypes = 0; + *outNumLayerRequestMasks = 0; + return false; + } + + const ReturnData& data = found->second; + + *outNumChangedCompositionTypes = static_cast(data.compositionTypes.size()); + *outNumLayerRequestMasks = static_cast(data.requestMasks.size()); + + return !(data.compositionTypes.empty() && data.requestMasks.empty()); + } + + // Get and clear saved changed composition types. + void takeChangedCompositionTypes(int64_t display, std::vector* outLayers, + std::vector* outTypes) { + auto found = mReturnData.find(display); + if (found == mReturnData.end()) { + outLayers->clear(); + outTypes->clear(); + return; + } + + ReturnData& data = found->second; + + *outLayers = std::move(data.changedLayers); + *outTypes = std::move(data.compositionTypes); + } + + // Get and clear saved display requests. + void takeDisplayRequests(int64_t display, uint32_t* outDisplayRequestMask, + std::vector* outLayers, + std::vector* outLayerRequestMasks) { + auto found = mReturnData.find(display); + if (found == mReturnData.end()) { + *outDisplayRequestMask = 0; + outLayers->clear(); + outLayerRequestMasks->clear(); + return; + } + + ReturnData& data = found->second; + + *outDisplayRequestMask = data.displayRequests; + *outLayers = std::move(data.requestedLayers); + *outLayerRequestMasks = std::move(data.requestMasks); + } + + // Get and clear saved release fences. + void takeReleaseFences(int64_t display, std::vector* outLayers, + std::vector* outReleaseFences) { + auto found = mReturnData.find(display); + if (found == mReturnData.end()) { + outLayers->clear(); + outReleaseFences->clear(); + return; + } + + ReturnData& data = found->second; + + *outLayers = std::move(data.releasedLayers); + *outReleaseFences = std::move(data.releaseFences); + } + + // Get and clear saved present fence. + void takePresentFence(int64_t display, int* outPresentFence) { + auto found = mReturnData.find(display); + if (found == mReturnData.end()) { + *outPresentFence = -1; + return; + } + + ReturnData& data = found->second; + + *outPresentFence = data.presentFence; + data.presentFence = -1; + } + + // Get what stage succeeded during PresentOrValidate: Present or Validate + void takePresentOrValidateStage(int64_t display, uint32_t* state) { + auto found = mReturnData.find(display); + if (found == mReturnData.end()) { + *state = static_cast(-1); + return; + } + ReturnData& data = found->second; + *state = data.presentOrValidateState; + } + + // Get the client target properties requested by hardware composer. + void takeClientTargetProperty(int64_t display, ClientTargetProperty* outClientTargetProperty, + float* outWhitePointNits) { + auto found = mReturnData.find(display); + + // If not found, return the default values. + if (found == mReturnData.end()) { + outClientTargetProperty->pixelFormat = common::PixelFormat::RGBA_8888; + outClientTargetProperty->dataspace = Dataspace::UNKNOWN; + *outWhitePointNits = -1.f; + return; + } + + ReturnData& data = found->second; + *outClientTargetProperty = data.clientTargetProperty; + *outWhitePointNits = data.clientTargetWhitePointNits; + } + + private: + void resetData() { + mErrors.clear(); + + for (auto& data : mReturnData) { + if (data.second.presentFence >= 0) { + close(data.second.presentFence); + } + for (auto fence : data.second.releaseFences) { + if (fence >= 0) { + close(fence); + } + } + } + + mReturnData.clear(); + } + + void parseSetError(const CommandError& error) { mErrors.emplace_back(error); } + + void parseSetChangedCompositionTypes(const ChangedCompositionTypes& changedCompositionTypes) { + auto& data = mReturnData[changedCompositionTypes.display]; + + data.changedLayers.reserve(changedCompositionTypes.layers.size()); + data.compositionTypes.reserve(changedCompositionTypes.layers.size()); + for (const auto& layer : changedCompositionTypes.layers) { + data.changedLayers.push_back(layer.layer); + data.compositionTypes.push_back(layer.composition); + } + } + + void parseSetDisplayRequests(const DisplayRequest& displayRequest) { + auto& data = mReturnData[displayRequest.display]; + + data.displayRequests = displayRequest.mask; + data.requestedLayers.reserve(displayRequest.layerRequests.size()); + data.requestMasks.reserve(displayRequest.layerRequests.size()); + for (const auto& layerRequest : displayRequest.layerRequests) { + data.requestedLayers.push_back(layerRequest.layer); + data.requestMasks.push_back(layerRequest.mask); + } + } + + void parseSetPresentFence(const PresentFence& presentFence) { + auto& data = mReturnData[presentFence.display]; + if (data.presentFence >= 0) { + close(data.presentFence); + } + data.presentFence = dup(presentFence.fence.get()); + } + + void parseSetReleaseFences(const ReleaseFences& releaseFences) { + auto& data = mReturnData[releaseFences.display]; + data.releasedLayers.reserve(releaseFences.layers.size()); + data.releaseFences.reserve(releaseFences.layers.size()); + for (const auto& layer : releaseFences.layers) { + data.releasedLayers.push_back(layer.layer); + data.releaseFences.push_back(dup(layer.fence.get())); + } + } + + void parseSetPresentOrValidateDisplayResult(const PresentOrValidate& presentOrValidate) { + auto& data = mReturnData[presentOrValidate.display]; + data.presentOrValidateState = + presentOrValidate.result == PresentOrValidate::Result::Presented ? 1 : 0; + } + + void parseSetClientTargetProperty(const ClientTargetPropertyWithNits& clientTargetProperty) { + auto& data = mReturnData[clientTargetProperty.display]; + data.clientTargetProperty.pixelFormat = + clientTargetProperty.clientTargetProperty.pixelFormat; + data.clientTargetProperty.dataspace = clientTargetProperty.clientTargetProperty.dataspace; + data.clientTargetWhitePointNits = clientTargetProperty.whitePointNits; + } + + struct ReturnData { + int32_t displayRequests = 0; + + std::vector changedLayers; + std::vector compositionTypes; + + std::vector requestedLayers; + std::vector requestMasks; + + int presentFence = -1; + + std::vector releasedLayers; + std::vector releaseFences; + + uint32_t presentOrValidateState; + + ClientTargetProperty clientTargetProperty{common::PixelFormat::RGBA_8888, + Dataspace::UNKNOWN}; + float clientTargetWhitePointNits = -1.f; + }; + + std::vector mErrors; + std::unordered_map mReturnData; +}; + +} // namespace aidl::android::hardware::graphics::composer3 diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h new file mode 100644 index 0000000000..bd0367394a --- /dev/null +++ b/graphics/composer/aidl/include/android/hardware/graphics/composer3/ComposerClientWriter.h @@ -0,0 +1,272 @@ +/* + * Copyright 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. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#include + +using aidl::android::hardware::graphics::common::BlendMode; +using aidl::android::hardware::graphics::common::ColorTransform; +using aidl::android::hardware::graphics::common::Dataspace; +using aidl::android::hardware::graphics::common::FRect; +using aidl::android::hardware::graphics::common::Rect; +using aidl::android::hardware::graphics::common::Transform; + +using namespace aidl::android::hardware::graphics::composer3; + +using aidl::android::hardware::common::NativeHandle; + +namespace aidl::android::hardware::graphics::composer3 { + +class ComposerClientWriter { + public: + ComposerClientWriter() { reset(); } + + virtual ~ComposerClientWriter() { reset(); } + + void reset() { + mDisplayCommand.reset(); + mLayerCommand.reset(); + mCommands.clear(); + } + + void setColorTransform(int64_t display, const float* matrix, ColorTransform hint) { + ColorTransformPayload colorTransformPayload; + colorTransformPayload.matrix.assign(matrix, matrix + 16); + colorTransformPayload.hint = hint; + getDisplayCommand(display).colorTransform.emplace(std::move(colorTransformPayload)); + } + + void setClientTarget(int64_t display, uint32_t slot, const native_handle_t* target, + int acquireFence, Dataspace dataspace, const std::vector& damage) { + ClientTarget clientTargetCommand; + clientTargetCommand.buffer = getBuffer(slot, target, acquireFence); + clientTargetCommand.dataspace = dataspace; + clientTargetCommand.damage.assign(damage.begin(), damage.end()); + getDisplayCommand(display).clientTarget.emplace(std::move(clientTargetCommand)); + } + + void setOutputBuffer(int64_t display, uint32_t slot, const native_handle_t* buffer, + int releaseFence) { + getDisplayCommand(display).virtualDisplayOutputBuffer.emplace( + getBuffer(slot, buffer, releaseFence)); + } + + void validateDisplay(int64_t display) { getDisplayCommand(display).validateDisplay = true; } + + void presentOrvalidateDisplay(int64_t display) { + getDisplayCommand(display).presentOrValidateDisplay = true; + } + + void acceptDisplayChanges(int64_t display) { + getDisplayCommand(display).acceptDisplayChanges = true; + } + + void presentDisplay(int64_t display) { getDisplayCommand(display).presentDisplay = true; } + + void setLayerCursorPosition(int64_t display, int64_t layer, int32_t x, int32_t y) { + common::Point cursorPosition; + cursorPosition.x = x; + cursorPosition.y = y; + getLayerCommand(display, layer).cursorPosition.emplace(std::move(cursorPosition)); + } + + void setLayerBuffer(int64_t display, int64_t layer, uint32_t slot, + const native_handle_t* buffer, int acquireFence) { + getLayerCommand(display, layer).buffer = getBuffer(slot, buffer, acquireFence); + } + + void setLayerSurfaceDamage(int64_t display, int64_t layer, const std::vector& damage) { + getLayerCommand(display, layer).damage.emplace(damage.begin(), damage.end()); + } + + void setLayerBlendMode(int64_t display, int64_t layer, BlendMode mode) { + ParcelableBlendMode parcelableBlendMode; + parcelableBlendMode.blendMode = mode; + getLayerCommand(display, layer).blendMode.emplace(std::move(parcelableBlendMode)); + } + + void setLayerColor(int64_t display, int64_t layer, Color color) { + getLayerCommand(display, layer).color.emplace(std::move(color)); + } + + void setLayerCompositionType(int64_t display, int64_t layer, Composition type) { + ParcelableComposition compositionPayload; + compositionPayload.composition = type; + getLayerCommand(display, layer).composition.emplace(std::move(compositionPayload)); + } + + void setLayerDataspace(int64_t display, int64_t layer, Dataspace dataspace) { + ParcelableDataspace dataspacePayload; + dataspacePayload.dataspace = dataspace; + getLayerCommand(display, layer).dataspace.emplace(std::move(dataspacePayload)); + } + + void setLayerDisplayFrame(int64_t display, int64_t layer, const Rect& frame) { + getLayerCommand(display, layer).displayFrame.emplace(frame); + } + + void setLayerPlaneAlpha(int64_t display, int64_t layer, float alpha) { + PlaneAlpha planeAlpha; + planeAlpha.alpha = alpha; + getLayerCommand(display, layer).planeAlpha.emplace(std::move(planeAlpha)); + } + + void setLayerSidebandStream(int64_t display, int64_t layer, const native_handle_t* stream) { + NativeHandle handle; + if (stream) handle = ::android::dupToAidl(stream); + getLayerCommand(display, layer).sidebandStream.emplace(std::move(handle)); + } + + void setLayerSourceCrop(int64_t display, int64_t layer, const FRect& crop) { + getLayerCommand(display, layer).sourceCrop.emplace(crop); + } + + void setLayerTransform(int64_t display, int64_t layer, Transform transform) { + ParcelableTransform transformPayload; + transformPayload.transform = transform; + getLayerCommand(display, layer).transform.emplace(std::move(transformPayload)); + } + + void setLayerVisibleRegion(int64_t display, int64_t layer, const std::vector& visible) { + getLayerCommand(display, layer).visibleRegion.emplace(visible.begin(), visible.end()); + } + + void setLayerZOrder(int64_t display, int64_t layer, uint32_t z) { + ZOrder zorder; + zorder.z = z; + getLayerCommand(display, layer).z.emplace(std::move(zorder)); + } + + void setLayerPerFrameMetadata(int64_t display, int64_t layer, + const std::vector& metadataVec) { + getLayerCommand(display, layer) + .perFrameMetadata.emplace(metadataVec.begin(), metadataVec.end()); + } + + void setLayerColorTransform(int64_t display, int64_t layer, const float* matrix) { + getLayerCommand(display, layer).colorTransform.emplace(matrix, matrix + 16); + } + + void setLayerPerFrameMetadataBlobs(int64_t display, int64_t layer, + const std::vector& metadata) { + getLayerCommand(display, layer) + .perFrameMetadataBlob.emplace(metadata.begin(), metadata.end()); + } + + void setLayerFloatColor(int64_t display, int64_t layer, FloatColor color) { + getLayerCommand(display, layer).floatColor.emplace(color); + } + + void setLayerGenericMetadata(int64_t display, int64_t layer, const std::string& key, + const bool mandatory, const std::vector& value) { + GenericMetadata metadata; + metadata.key.name = key; + metadata.key.mandatory = mandatory; + metadata.value.assign(value.begin(), value.end()); + getLayerCommand(display, layer).genericMetadata.emplace(std::move(metadata)); + } + + void setLayerWhitePointNits(int64_t display, int64_t layer, float whitePointNits) { + getLayerCommand(display, layer) + .whitePointNits.emplace(WhitePointNits{.nits = whitePointNits}); + } + + const std::vector& getPendingCommands() { + flushLayerCommand(); + flushDisplayCommand(); + return mCommands; + } + + private: + std::optional mDisplayCommand; + std::optional mLayerCommand; + std::vector mCommands; + + Buffer getBuffer(int slot, const native_handle_t* bufferHandle, int fence) { + Buffer bufferCommand; + bufferCommand.slot = slot; + if (bufferHandle) bufferCommand.handle.emplace(::android::dupToAidl(bufferHandle)); + if (fence > 0) bufferCommand.fence = ::ndk::ScopedFileDescriptor(fence); + return bufferCommand; + } + + void flushLayerCommand() { + if (mLayerCommand.has_value()) { + mDisplayCommand->layers.emplace_back(std::move(*mLayerCommand)); + mLayerCommand.reset(); + } + } + + void flushDisplayCommand() { + if (mDisplayCommand.has_value()) { + mCommands.emplace_back(std::move(*mDisplayCommand)); + mDisplayCommand.reset(); + } + } + + DisplayCommand& getDisplayCommand(int64_t display) { + if (!mDisplayCommand.has_value() || mDisplayCommand->display != display) { + flushLayerCommand(); + flushDisplayCommand(); + mDisplayCommand.emplace(); + mDisplayCommand->display = display; + } + return *mDisplayCommand; + } + + LayerCommand& getLayerCommand(int64_t display, int64_t layer) { + getDisplayCommand(display); + if (!mLayerCommand.has_value() || mLayerCommand->layer != layer) { + flushLayerCommand(); + mLayerCommand.emplace(); + mLayerCommand->layer = layer; + } + return *mLayerCommand; + } +}; + +} // namespace aidl::android::hardware::graphics::composer3 diff --git a/graphics/composer/aidl/include/android/hardware/graphics/composer3/command-buffer.h b/graphics/composer/aidl/include/android/hardware/graphics/composer3/command-buffer.h deleted file mode 100644 index fcf2a34602..0000000000 --- a/graphics/composer/aidl/include/android/hardware/graphics/composer3/command-buffer.h +++ /dev/null @@ -1,614 +0,0 @@ -/* - * Copyright 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. - */ - -#pragma once - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include - -using aidl::android::hardware::graphics::common::BlendMode; -using aidl::android::hardware::graphics::common::ColorTransform; -using aidl::android::hardware::graphics::common::Dataspace; -using aidl::android::hardware::graphics::common::FRect; -using aidl::android::hardware::graphics::common::Rect; -using aidl::android::hardware::graphics::common::Transform; - -using namespace aidl::android::hardware::graphics::composer3; - -using aidl::android::hardware::common::NativeHandle; - -namespace aidl::android::hardware::graphics::composer3 { - -// This class helps build a command queue. Note that all sizes/lengths are in -// units of uint32_t's. -class CommandWriterBase { - public: - CommandWriterBase() { reset(); } - - virtual ~CommandWriterBase() { reset(); } - - void reset() { - mDisplayCommand.reset(); - mLayerCommand.reset(); - mCommands.clear(); - mCommandsResults.clear(); - } - - void setError(int32_t index, int32_t errorCode) { - CommandError error; - error.commandIndex = index; - error.errorCode = errorCode; - mCommandsResults.emplace_back(std::move(error)); - } - - void setPresentOrValidateResult(int64_t display, PresentOrValidate::Result result) { - PresentOrValidate presentOrValidate; - presentOrValidate.display = display; - presentOrValidate.result = result; - mCommandsResults.emplace_back(std::move(presentOrValidate)); - } - - void setChangedCompositionTypes(int64_t display, const std::vector& layers, - const std::vector& types) { - ChangedCompositionTypes changedCompositionTypes; - changedCompositionTypes.display = display; - changedCompositionTypes.layers.reserve(layers.size()); - for (int i = 0; i < layers.size(); i++) { - auto layer = ChangedCompositionLayer{.layer = layers[i], .composition = types[i]}; - changedCompositionTypes.layers.emplace_back(std::move(layer)); - } - mCommandsResults.emplace_back(std::move(changedCompositionTypes)); - } - - void setDisplayRequests(int64_t display, int32_t displayRequestMask, - const std::vector& layers, - const std::vector& layerRequestMasks) { - DisplayRequest displayRequest; - displayRequest.display = display; - displayRequest.mask = displayRequestMask; - displayRequest.layerRequests.reserve(layers.size()); - for (int i = 0; i < layers.size(); i++) { - auto layerRequest = - DisplayRequest::LayerRequest{.layer = layers[i], .mask = layerRequestMasks[i]}; - displayRequest.layerRequests.emplace_back(std::move(layerRequest)); - } - mCommandsResults.emplace_back(std::move(displayRequest)); - } - - void setPresentFence(int64_t display, ::ndk::ScopedFileDescriptor presentFence) { - if (presentFence.get() >= 0) { - PresentFence presentFenceCommand; - presentFenceCommand.fence = std::move(presentFence); - presentFenceCommand.display = display; - mCommandsResults.emplace_back(std::move(presentFenceCommand)); - } else { - ALOGW("%s: invalid present fence %d", __func__, presentFence.get()); - } - } - - void setReleaseFences(int64_t display, const std::vector& layers, - std::vector<::ndk::ScopedFileDescriptor> releaseFences) { - ReleaseFences releaseFencesCommand; - releaseFencesCommand.display = display; - for (int i = 0; i < layers.size(); i++) { - if (releaseFences[i].get() >= 0) { - ReleaseFences::Layer layer; - layer.layer = layers[i]; - layer.fence = std::move(releaseFences[i]); - releaseFencesCommand.layers.emplace_back(std::move(layer)); - } else { - ALOGW("%s: invalid release fence %d", __func__, releaseFences[i].get()); - } - } - mCommandsResults.emplace_back(std::move(releaseFencesCommand)); - } - - void setClientTargetProperty(int64_t display, const ClientTargetProperty& clientTargetProperty, - float whitePointNits) { - ClientTargetPropertyWithNits clientTargetPropertyWithNits; - clientTargetPropertyWithNits.display = display; - clientTargetPropertyWithNits.clientTargetProperty = clientTargetProperty; - clientTargetPropertyWithNits.whitePointNits = whitePointNits; - mCommandsResults.emplace_back(std::move(clientTargetPropertyWithNits)); - } - - void setColorTransform(int64_t display, const float* matrix, ColorTransform hint) { - ColorTransformPayload colorTransformPayload; - colorTransformPayload.matrix.assign(matrix, matrix + 16); - colorTransformPayload.hint = hint; - getDisplayCommand(display).colorTransform.emplace(std::move(colorTransformPayload)); - } - - void setClientTarget(int64_t display, uint32_t slot, const native_handle_t* target, - int acquireFence, Dataspace dataspace, const std::vector& damage) { - ClientTarget clientTargetCommand; - clientTargetCommand.buffer = getBuffer(slot, target, acquireFence); - clientTargetCommand.dataspace = dataspace; - clientTargetCommand.damage.assign(damage.begin(), damage.end()); - getDisplayCommand(display).clientTarget.emplace(std::move(clientTargetCommand)); - } - - void setOutputBuffer(int64_t display, uint32_t slot, const native_handle_t* buffer, - int releaseFence) { - getDisplayCommand(display).virtualDisplayOutputBuffer.emplace( - getBuffer(slot, buffer, releaseFence)); - } - - void validateDisplay(int64_t display) { getDisplayCommand(display).validateDisplay = true; } - - void presentOrvalidateDisplay(int64_t display) { - getDisplayCommand(display).presentOrValidateDisplay = true; - } - - void acceptDisplayChanges(int64_t display) { - getDisplayCommand(display).acceptDisplayChanges = true; - } - - void presentDisplay(int64_t display) { getDisplayCommand(display).presentDisplay = true; } - - void setLayerCursorPosition(int64_t display, int64_t layer, int32_t x, int32_t y) { - common::Point cursorPosition; - cursorPosition.x = x; - cursorPosition.y = y; - getLayerCommand(display, layer).cursorPosition.emplace(std::move(cursorPosition)); - } - - void setLayerBuffer(int64_t display, int64_t layer, uint32_t slot, - const native_handle_t* buffer, int acquireFence) { - getLayerCommand(display, layer).buffer = getBuffer(slot, buffer, acquireFence); - } - - void setLayerSurfaceDamage(int64_t display, int64_t layer, const std::vector& damage) { - getLayerCommand(display, layer).damage.emplace(damage.begin(), damage.end()); - } - - void setLayerBlendMode(int64_t display, int64_t layer, BlendMode mode) { - ParcelableBlendMode parcelableBlendMode; - parcelableBlendMode.blendMode = mode; - getLayerCommand(display, layer).blendMode.emplace(std::move(parcelableBlendMode)); - } - - void setLayerColor(int64_t display, int64_t layer, Color color) { - getLayerCommand(display, layer).color.emplace(std::move(color)); - } - - void setLayerCompositionType(int64_t display, int64_t layer, Composition type) { - ParcelableComposition compositionPayload; - compositionPayload.composition = type; - getLayerCommand(display, layer).composition.emplace(std::move(compositionPayload)); - } - - void setLayerDataspace(int64_t display, int64_t layer, Dataspace dataspace) { - ParcelableDataspace dataspacePayload; - dataspacePayload.dataspace = dataspace; - getLayerCommand(display, layer).dataspace.emplace(std::move(dataspacePayload)); - } - - void setLayerDisplayFrame(int64_t display, int64_t layer, const Rect& frame) { - getLayerCommand(display, layer).displayFrame.emplace(frame); - } - - void setLayerPlaneAlpha(int64_t display, int64_t layer, float alpha) { - PlaneAlpha planeAlpha; - planeAlpha.alpha = alpha; - getLayerCommand(display, layer).planeAlpha.emplace(std::move(planeAlpha)); - } - - void setLayerSidebandStream(int64_t display, int64_t layer, const native_handle_t* stream) { - NativeHandle handle; - if (stream) handle = ::android::dupToAidl(stream); - getLayerCommand(display, layer).sidebandStream.emplace(std::move(handle)); - } - - void setLayerSourceCrop(int64_t display, int64_t layer, const FRect& crop) { - getLayerCommand(display, layer).sourceCrop.emplace(crop); - } - - void setLayerTransform(int64_t display, int64_t layer, Transform transform) { - ParcelableTransform transformPayload; - transformPayload.transform = transform; - getLayerCommand(display, layer).transform.emplace(std::move(transformPayload)); - } - - void setLayerVisibleRegion(int64_t display, int64_t layer, const std::vector& visible) { - getLayerCommand(display, layer).visibleRegion.emplace(visible.begin(), visible.end()); - } - - void setLayerZOrder(int64_t display, int64_t layer, uint32_t z) { - ZOrder zorder; - zorder.z = z; - getLayerCommand(display, layer).z.emplace(std::move(zorder)); - } - - void setLayerPerFrameMetadata(int64_t display, int64_t layer, - const std::vector& metadataVec) { - getLayerCommand(display, layer) - .perFrameMetadata.emplace(metadataVec.begin(), metadataVec.end()); - } - - void setLayerColorTransform(int64_t display, int64_t layer, const float* matrix) { - getLayerCommand(display, layer).colorTransform.emplace(matrix, matrix + 16); - } - - void setLayerPerFrameMetadataBlobs(int64_t display, int64_t layer, - const std::vector& metadata) { - getLayerCommand(display, layer) - .perFrameMetadataBlob.emplace(metadata.begin(), metadata.end()); - } - - void setLayerFloatColor(int64_t display, int64_t layer, FloatColor color) { - getLayerCommand(display, layer).floatColor.emplace(color); - } - - void setLayerGenericMetadata(int64_t display, int64_t layer, const std::string& key, - const bool mandatory, const std::vector& value) { - GenericMetadata metadata; - metadata.key.name = key; - metadata.key.mandatory = mandatory; - metadata.value.assign(value.begin(), value.end()); - getLayerCommand(display, layer).genericMetadata.emplace(std::move(metadata)); - } - - void setLayerWhitePointNits(int64_t display, int64_t layer, float whitePointNits) { - getLayerCommand(display, layer) - .whitePointNits.emplace(WhitePointNits{.nits = whitePointNits}); - } - - const std::vector& getPendingCommands() { - flushLayerCommand(); - flushDisplayCommand(); - return mCommands; - } - - std::vector getPendingCommandResults() { - return std::move(mCommandsResults); - } - - protected: - Buffer getBuffer(int slot, const native_handle_t* bufferHandle, int fence) { - Buffer bufferCommand; - bufferCommand.slot = slot; - if (bufferHandle) bufferCommand.handle.emplace(::android::dupToAidl(bufferHandle)); - if (fence > 0) bufferCommand.fence = ::ndk::ScopedFileDescriptor(fence); - return bufferCommand; - } - - std::optional mDisplayCommand; - std::optional mLayerCommand; - std::vector mCommands; - std::vector mCommandsResults; - - private: - void flushLayerCommand() { - if (mLayerCommand.has_value()) { - mDisplayCommand->layers.emplace_back(std::move(*mLayerCommand)); - mLayerCommand.reset(); - } - } - - void flushDisplayCommand() { - if (mDisplayCommand.has_value()) { - mCommands.emplace_back(std::move(*mDisplayCommand)); - mDisplayCommand.reset(); - } - } - - DisplayCommand& getDisplayCommand(int64_t display) { - if (!mDisplayCommand.has_value() || mDisplayCommand->display != display) { - flushLayerCommand(); - flushDisplayCommand(); - mDisplayCommand.emplace(); - mDisplayCommand->display = display; - } - return *mDisplayCommand; - } - - LayerCommand& getLayerCommand(int64_t display, int64_t layer) { - getDisplayCommand(display); - if (!mLayerCommand.has_value() || mLayerCommand->layer != layer) { - flushLayerCommand(); - mLayerCommand.emplace(); - mLayerCommand->layer = layer; - } - return *mLayerCommand; - } -}; - -class CommandReaderBase { - public: - ~CommandReaderBase() { resetData(); } - - // Parse and execute commands from the command queue. The commands are - // actually return values from the server and will be saved in ReturnData. - void parse(const std::vector& results) { - resetData(); - - for (const auto& result : results) { - switch (result.getTag()) { - case CommandResultPayload::Tag::error: - parseSetError(result.get()); - break; - case CommandResultPayload::Tag::changedCompositionTypes: - parseSetChangedCompositionTypes( - result.get()); - break; - case CommandResultPayload::Tag::displayRequest: - parseSetDisplayRequests( - result.get()); - break; - case CommandResultPayload::Tag::presentFence: - parseSetPresentFence(result.get()); - break; - case CommandResultPayload::Tag::releaseFences: - parseSetReleaseFences(result.get()); - break; - case CommandResultPayload::Tag::presentOrValidateResult: - parseSetPresentOrValidateDisplayResult( - result.get()); - break; - case CommandResultPayload::Tag::clientTargetProperty: - parseSetClientTargetProperty( - result.get()); - break; - } - } - } - - std::vector takeErrors() { return std::move(mErrors); } - - bool hasChanges(int64_t display, uint32_t* outNumChangedCompositionTypes, - uint32_t* outNumLayerRequestMasks) const { - auto found = mReturnData.find(display); - if (found == mReturnData.end()) { - *outNumChangedCompositionTypes = 0; - *outNumLayerRequestMasks = 0; - return false; - } - - const ReturnData& data = found->second; - - *outNumChangedCompositionTypes = static_cast(data.compositionTypes.size()); - *outNumLayerRequestMasks = static_cast(data.requestMasks.size()); - - return !(data.compositionTypes.empty() && data.requestMasks.empty()); - } - - // Get and clear saved changed composition types. - void takeChangedCompositionTypes(int64_t display, std::vector* outLayers, - std::vector* outTypes) { - auto found = mReturnData.find(display); - if (found == mReturnData.end()) { - outLayers->clear(); - outTypes->clear(); - return; - } - - ReturnData& data = found->second; - - *outLayers = std::move(data.changedLayers); - *outTypes = std::move(data.compositionTypes); - } - - // Get and clear saved display requests. - void takeDisplayRequests(int64_t display, uint32_t* outDisplayRequestMask, - std::vector* outLayers, - std::vector* outLayerRequestMasks) { - auto found = mReturnData.find(display); - if (found == mReturnData.end()) { - *outDisplayRequestMask = 0; - outLayers->clear(); - outLayerRequestMasks->clear(); - return; - } - - ReturnData& data = found->second; - - *outDisplayRequestMask = data.displayRequests; - *outLayers = std::move(data.requestedLayers); - *outLayerRequestMasks = std::move(data.requestMasks); - } - - // Get and clear saved release fences. - void takeReleaseFences(int64_t display, std::vector* outLayers, - std::vector* outReleaseFences) { - auto found = mReturnData.find(display); - if (found == mReturnData.end()) { - outLayers->clear(); - outReleaseFences->clear(); - return; - } - - ReturnData& data = found->second; - - *outLayers = std::move(data.releasedLayers); - *outReleaseFences = std::move(data.releaseFences); - } - - // Get and clear saved present fence. - void takePresentFence(int64_t display, int* outPresentFence) { - auto found = mReturnData.find(display); - if (found == mReturnData.end()) { - *outPresentFence = -1; - return; - } - - ReturnData& data = found->second; - - *outPresentFence = data.presentFence; - data.presentFence = -1; - } - - // Get what stage succeeded during PresentOrValidate: Present or Validate - void takePresentOrValidateStage(int64_t display, uint32_t* state) { - auto found = mReturnData.find(display); - if (found == mReturnData.end()) { - *state = static_cast(-1); - return; - } - ReturnData& data = found->second; - *state = data.presentOrValidateState; - } - - // Get the client target properties requested by hardware composer. - void takeClientTargetProperty(int64_t display, ClientTargetProperty* outClientTargetProperty, - float* outWhitePointNits) { - auto found = mReturnData.find(display); - - // If not found, return the default values. - if (found == mReturnData.end()) { - outClientTargetProperty->pixelFormat = common::PixelFormat::RGBA_8888; - outClientTargetProperty->dataspace = Dataspace::UNKNOWN; - *outWhitePointNits = -1.f; - return; - } - - ReturnData& data = found->second; - *outClientTargetProperty = data.clientTargetProperty; - *outWhitePointNits = data.clientTargetWhitePointNits; - } - - private: - void resetData() { - mErrors.clear(); - - for (auto& data : mReturnData) { - if (data.second.presentFence >= 0) { - close(data.second.presentFence); - } - for (auto fence : data.second.releaseFences) { - if (fence >= 0) { - close(fence); - } - } - } - - mReturnData.clear(); - } - - void parseSetError(const CommandError& error) { mErrors.emplace_back(error); } - - void parseSetChangedCompositionTypes(const ChangedCompositionTypes& changedCompositionTypes) { - auto& data = mReturnData[changedCompositionTypes.display]; - - data.changedLayers.reserve(changedCompositionTypes.layers.size()); - data.compositionTypes.reserve(changedCompositionTypes.layers.size()); - for (const auto& layer : changedCompositionTypes.layers) { - data.changedLayers.push_back(layer.layer); - data.compositionTypes.push_back(layer.composition); - } - } - - void parseSetDisplayRequests(const DisplayRequest& displayRequest) { - auto& data = mReturnData[displayRequest.display]; - - data.displayRequests = displayRequest.mask; - data.requestedLayers.reserve(displayRequest.layerRequests.size()); - data.requestMasks.reserve(displayRequest.layerRequests.size()); - for (const auto& layerRequest : displayRequest.layerRequests) { - data.requestedLayers.push_back(layerRequest.layer); - data.requestMasks.push_back(layerRequest.mask); - } - } - - void parseSetPresentFence(const PresentFence& presentFence) { - auto& data = mReturnData[presentFence.display]; - if (data.presentFence >= 0) { - close(data.presentFence); - } - data.presentFence = dup(presentFence.fence.get()); - } - - void parseSetReleaseFences(const ReleaseFences& releaseFences) { - auto& data = mReturnData[releaseFences.display]; - data.releasedLayers.reserve(releaseFences.layers.size()); - data.releaseFences.reserve(releaseFences.layers.size()); - for (const auto& layer : releaseFences.layers) { - data.releasedLayers.push_back(layer.layer); - data.releaseFences.push_back(dup(layer.fence.get())); - } - } - - void parseSetPresentOrValidateDisplayResult(const PresentOrValidate& presentOrValidate) { - auto& data = mReturnData[presentOrValidate.display]; - data.presentOrValidateState = - presentOrValidate.result == PresentOrValidate::Result::Presented ? 1 : 0; - } - - void parseSetClientTargetProperty(const ClientTargetPropertyWithNits& clientTargetProperty) { - auto& data = mReturnData[clientTargetProperty.display]; - data.clientTargetProperty.pixelFormat = - clientTargetProperty.clientTargetProperty.pixelFormat; - data.clientTargetProperty.dataspace = clientTargetProperty.clientTargetProperty.dataspace; - data.clientTargetWhitePointNits = clientTargetProperty.whitePointNits; - } - - struct ReturnData { - int32_t displayRequests = 0; - - std::vector changedLayers; - std::vector compositionTypes; - - std::vector requestedLayers; - std::vector requestMasks; - - int presentFence = -1; - - std::vector releasedLayers; - std::vector releaseFences; - - uint32_t presentOrValidateState; - - ClientTargetProperty clientTargetProperty{common::PixelFormat::RGBA_8888, - Dataspace::UNKNOWN}; - float clientTargetWhitePointNits = -1.f; - }; - - std::vector mErrors; - std::unordered_map mReturnData; -}; - -} // namespace aidl::android::hardware::graphics::composer3