mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Merge "composer: cleanup CommandWriterBase and CommandReaderBase"
This commit is contained in:
@@ -167,8 +167,8 @@ class GraphicsCompositionTestBase : public ::testing::Test {
|
||||
int32_t mDisplayWidth;
|
||||
int32_t mDisplayHeight;
|
||||
std::vector<ColorMode> mTestColorModes;
|
||||
CommandWriterBase mWriter;
|
||||
CommandReaderBase mReader;
|
||||
ComposerClientWriter mWriter;
|
||||
ComposerClientReader mReader;
|
||||
::android::sp<::android::GraphicBuffer> mGraphicBuffer;
|
||||
std::unique_ptr<TestRenderEngine> mTestRenderEngine;
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
#include <android-base/properties.h>
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_process.h>
|
||||
#include <android/hardware/graphics/composer3/command-buffer.h>
|
||||
#include <android/hardware/graphics/composer3/ComposerClientReader.h>
|
||||
#include <android/hardware/graphics/composer3/ComposerClientWriter.h>
|
||||
#include <binder/ProcessState.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <ui/GraphicBuffer.h>
|
||||
@@ -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) {
|
||||
|
||||
@@ -32,7 +32,7 @@ const std::vector<ColorMode> ReadbackHelper::colorModes = {ColorMode::SRGB, Colo
|
||||
const std::vector<Dataspace> 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<Color> 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<IComposerClient>& 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<Rect>(1, mDisplayFrame));
|
||||
@@ -345,11 +345,11 @@ void TestBufferLayer::setBuffer(std::vector<Color> 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
#include <GraphicsComposerCallback.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/IComposerClient.h>
|
||||
#include <android-base/unique_fd.h>
|
||||
#include <android/hardware/graphics/composer3/command-buffer.h>
|
||||
#include <android/hardware/graphics/composer3/ComposerClientReader.h>
|
||||
#include <android/hardware/graphics/composer3/ComposerClientWriter.h>
|
||||
#include <mapper-vts/2.1/MapperVts.h>
|
||||
#include <renderengine/RenderEngine.h>
|
||||
#include <ui/GraphicBuffer.h>
|
||||
@@ -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<IComposerClient>& 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<Color> 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; }
|
||||
|
||||
|
||||
@@ -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 <algorithm>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <aidl/android/hardware/graphics/common/BlendMode.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/ClientTargetProperty.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/Color.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/Composition.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/FloatColor.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/HandleIndex.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/IComposer.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/IComposerClient.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/PerFrameMetadata.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h>
|
||||
|
||||
#include <aidl/android/hardware/graphics/composer3/CommandResultPayload.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/DisplayCommand.h>
|
||||
|
||||
#include <aidl/android/hardware/graphics/common/ColorTransform.h>
|
||||
#include <aidl/android/hardware/graphics/common/FRect.h>
|
||||
#include <aidl/android/hardware/graphics/common/Rect.h>
|
||||
#include <aidl/android/hardware/graphics/common/Transform.h>
|
||||
|
||||
#include <log/log.h>
|
||||
#include <sync/sync.h>
|
||||
|
||||
#include <aidlcommonsupport/NativeHandle.h>
|
||||
|
||||
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<CommandResultPayload>& results) {
|
||||
resetData();
|
||||
|
||||
for (const auto& result : results) {
|
||||
switch (result.getTag()) {
|
||||
case CommandResultPayload::Tag::error:
|
||||
parseSetError(result.get<CommandResultPayload::Tag::error>());
|
||||
break;
|
||||
case CommandResultPayload::Tag::changedCompositionTypes:
|
||||
parseSetChangedCompositionTypes(
|
||||
result.get<CommandResultPayload::Tag::changedCompositionTypes>());
|
||||
break;
|
||||
case CommandResultPayload::Tag::displayRequest:
|
||||
parseSetDisplayRequests(
|
||||
result.get<CommandResultPayload::Tag::displayRequest>());
|
||||
break;
|
||||
case CommandResultPayload::Tag::presentFence:
|
||||
parseSetPresentFence(result.get<CommandResultPayload::Tag::presentFence>());
|
||||
break;
|
||||
case CommandResultPayload::Tag::releaseFences:
|
||||
parseSetReleaseFences(result.get<CommandResultPayload::Tag::releaseFences>());
|
||||
break;
|
||||
case CommandResultPayload::Tag::presentOrValidateResult:
|
||||
parseSetPresentOrValidateDisplayResult(
|
||||
result.get<CommandResultPayload::Tag::presentOrValidateResult>());
|
||||
break;
|
||||
case CommandResultPayload::Tag::clientTargetProperty:
|
||||
parseSetClientTargetProperty(
|
||||
result.get<CommandResultPayload::Tag::clientTargetProperty>());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<CommandError> 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<uint32_t>(data.compositionTypes.size());
|
||||
*outNumLayerRequestMasks = static_cast<uint32_t>(data.requestMasks.size());
|
||||
|
||||
return !(data.compositionTypes.empty() && data.requestMasks.empty());
|
||||
}
|
||||
|
||||
// Get and clear saved changed composition types.
|
||||
void takeChangedCompositionTypes(int64_t display, std::vector<int64_t>* outLayers,
|
||||
std::vector<Composition>* 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<int64_t>* outLayers,
|
||||
std::vector<uint32_t>* 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<int64_t>* outLayers,
|
||||
std::vector<int>* 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<uint32_t>(-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<int64_t> changedLayers;
|
||||
std::vector<Composition> compositionTypes;
|
||||
|
||||
std::vector<int64_t> requestedLayers;
|
||||
std::vector<uint32_t> requestMasks;
|
||||
|
||||
int presentFence = -1;
|
||||
|
||||
std::vector<int64_t> releasedLayers;
|
||||
std::vector<int> releaseFences;
|
||||
|
||||
uint32_t presentOrValidateState;
|
||||
|
||||
ClientTargetProperty clientTargetProperty{common::PixelFormat::RGBA_8888,
|
||||
Dataspace::UNKNOWN};
|
||||
float clientTargetWhitePointNits = -1.f;
|
||||
};
|
||||
|
||||
std::vector<CommandError> mErrors;
|
||||
std::unordered_map<int64_t, ReturnData> mReturnData;
|
||||
};
|
||||
|
||||
} // namespace aidl::android::hardware::graphics::composer3
|
||||
@@ -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 <algorithm>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <aidl/android/hardware/graphics/common/BlendMode.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/Color.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/Composition.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/FloatColor.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/HandleIndex.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/IComposer.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/IComposerClient.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/PerFrameMetadata.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h>
|
||||
|
||||
#include <aidl/android/hardware/graphics/composer3/DisplayCommand.h>
|
||||
|
||||
#include <aidl/android/hardware/graphics/common/ColorTransform.h>
|
||||
#include <aidl/android/hardware/graphics/common/FRect.h>
|
||||
#include <aidl/android/hardware/graphics/common/Rect.h>
|
||||
#include <aidl/android/hardware/graphics/common/Transform.h>
|
||||
|
||||
#include <log/log.h>
|
||||
#include <sync/sync.h>
|
||||
|
||||
#include <aidlcommonsupport/NativeHandle.h>
|
||||
|
||||
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<Rect>& 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<Rect>& 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<Rect>& 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<PerFrameMetadata>& 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<PerFrameMetadataBlob>& 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<uint8_t>& 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<DisplayCommand>& getPendingCommands() {
|
||||
flushLayerCommand();
|
||||
flushDisplayCommand();
|
||||
return mCommands;
|
||||
}
|
||||
|
||||
private:
|
||||
std::optional<DisplayCommand> mDisplayCommand;
|
||||
std::optional<LayerCommand> mLayerCommand;
|
||||
std::vector<DisplayCommand> 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
|
||||
@@ -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 <algorithm>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <aidl/android/hardware/graphics/common/BlendMode.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/ClientTargetProperty.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/Color.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/Composition.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/FloatColor.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/HandleIndex.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/IComposer.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/IComposerClient.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/PerFrameMetadata.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h>
|
||||
|
||||
#include <aidl/android/hardware/graphics/composer3/CommandResultPayload.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/DisplayCommand.h>
|
||||
|
||||
#include <aidl/android/hardware/graphics/common/ColorTransform.h>
|
||||
#include <aidl/android/hardware/graphics/common/FRect.h>
|
||||
#include <aidl/android/hardware/graphics/common/Rect.h>
|
||||
#include <aidl/android/hardware/graphics/common/Transform.h>
|
||||
|
||||
#include <log/log.h>
|
||||
#include <sync/sync.h>
|
||||
|
||||
#include <aidlcommonsupport/NativeHandle.h>
|
||||
|
||||
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<int64_t>& layers,
|
||||
const std::vector<Composition>& 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<int64_t>& layers,
|
||||
const std::vector<int32_t>& 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<int64_t>& 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<Rect>& 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<Rect>& 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<Rect>& 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<PerFrameMetadata>& 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<PerFrameMetadataBlob>& 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<uint8_t>& 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<DisplayCommand>& getPendingCommands() {
|
||||
flushLayerCommand();
|
||||
flushDisplayCommand();
|
||||
return mCommands;
|
||||
}
|
||||
|
||||
std::vector<CommandResultPayload> 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<DisplayCommand> mDisplayCommand;
|
||||
std::optional<LayerCommand> mLayerCommand;
|
||||
std::vector<DisplayCommand> mCommands;
|
||||
std::vector<CommandResultPayload> 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<CommandResultPayload>& results) {
|
||||
resetData();
|
||||
|
||||
for (const auto& result : results) {
|
||||
switch (result.getTag()) {
|
||||
case CommandResultPayload::Tag::error:
|
||||
parseSetError(result.get<CommandResultPayload::Tag::error>());
|
||||
break;
|
||||
case CommandResultPayload::Tag::changedCompositionTypes:
|
||||
parseSetChangedCompositionTypes(
|
||||
result.get<CommandResultPayload::Tag::changedCompositionTypes>());
|
||||
break;
|
||||
case CommandResultPayload::Tag::displayRequest:
|
||||
parseSetDisplayRequests(
|
||||
result.get<CommandResultPayload::Tag::displayRequest>());
|
||||
break;
|
||||
case CommandResultPayload::Tag::presentFence:
|
||||
parseSetPresentFence(result.get<CommandResultPayload::Tag::presentFence>());
|
||||
break;
|
||||
case CommandResultPayload::Tag::releaseFences:
|
||||
parseSetReleaseFences(result.get<CommandResultPayload::Tag::releaseFences>());
|
||||
break;
|
||||
case CommandResultPayload::Tag::presentOrValidateResult:
|
||||
parseSetPresentOrValidateDisplayResult(
|
||||
result.get<CommandResultPayload::Tag::presentOrValidateResult>());
|
||||
break;
|
||||
case CommandResultPayload::Tag::clientTargetProperty:
|
||||
parseSetClientTargetProperty(
|
||||
result.get<CommandResultPayload::Tag::clientTargetProperty>());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<CommandError> 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<uint32_t>(data.compositionTypes.size());
|
||||
*outNumLayerRequestMasks = static_cast<uint32_t>(data.requestMasks.size());
|
||||
|
||||
return !(data.compositionTypes.empty() && data.requestMasks.empty());
|
||||
}
|
||||
|
||||
// Get and clear saved changed composition types.
|
||||
void takeChangedCompositionTypes(int64_t display, std::vector<int64_t>* outLayers,
|
||||
std::vector<Composition>* 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<int64_t>* outLayers,
|
||||
std::vector<uint32_t>* 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<int64_t>* outLayers,
|
||||
std::vector<int>* 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<uint32_t>(-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<int64_t> changedLayers;
|
||||
std::vector<Composition> compositionTypes;
|
||||
|
||||
std::vector<int64_t> requestedLayers;
|
||||
std::vector<uint32_t> requestMasks;
|
||||
|
||||
int presentFence = -1;
|
||||
|
||||
std::vector<int64_t> releasedLayers;
|
||||
std::vector<int> releaseFences;
|
||||
|
||||
uint32_t presentOrValidateState;
|
||||
|
||||
ClientTargetProperty clientTargetProperty{common::PixelFormat::RGBA_8888,
|
||||
Dataspace::UNKNOWN};
|
||||
float clientTargetWhitePointNits = -1.f;
|
||||
};
|
||||
|
||||
std::vector<CommandError> mErrors;
|
||||
std::unordered_map<int64_t, ReturnData> mReturnData;
|
||||
};
|
||||
|
||||
} // namespace aidl::android::hardware::graphics::composer3
|
||||
Reference in New Issue
Block a user