mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 16:09:42 +00:00
Readback tests from VTS 2.2
Tests are from https://source.corp.google.com/android/hardware/interfaces/graphics/composer/2.2/vts/functional/VtsHalGraphicsComposerV2_2ReadbackTest.cpp;rcl=4796867049599ae1618d63cb93a38b269687164b;l=52 Test: atest VtsHalGraphicsComposer3_TargetTest BUG: 202766745 Change-Id: I495819c168429873dc88decb20f398569c1a8128
This commit is contained in:
@@ -19,7 +19,7 @@ package {
|
||||
// A large-scale-change added 'default_applicable_licenses' to import
|
||||
// all of the 'license_kinds' from "hardware_interfaces_license"
|
||||
// to get the below license kinds:
|
||||
// SPDX-license-identifier-Apache-2.0
|
||||
// SPDX-license-identifier-Apache-2.0
|
||||
default_applicable_licenses: ["hardware_interfaces_license"],
|
||||
}
|
||||
|
||||
@@ -28,20 +28,29 @@ cc_test {
|
||||
defaults: [
|
||||
"VtsHalTargetTestDefaults",
|
||||
"use_libaidlvintf_gtest_helper_static",
|
||||
// Needed for librenderengine
|
||||
"skia_deps",
|
||||
],
|
||||
srcs: [
|
||||
"VtsHalGraphicsComposer3_TargetTest.cpp",
|
||||
"VtsHalGraphicsComposer3_ReadbackTest.cpp",
|
||||
"composer-vts/GraphicsComposerCallback.cpp",
|
||||
"composer-vts/TestCommandReader.cpp",
|
||||
],
|
||||
|
||||
shared_libs: [
|
||||
"libEGL",
|
||||
"libGLESv1_CM",
|
||||
"libGLESv2",
|
||||
"libbinder_ndk",
|
||||
"libbinder",
|
||||
"libfmq",
|
||||
"libbase",
|
||||
"libsync",
|
||||
"libui",
|
||||
"libgui",
|
||||
"libhidlbase",
|
||||
"libprocessgroup",
|
||||
"android.hardware.graphics.mapper@2.0",
|
||||
"android.hardware.graphics.mapper@2.1",
|
||||
"android.hardware.graphics.mapper@3.0",
|
||||
@@ -69,6 +78,10 @@ cc_test {
|
||||
"android.hardware.graphics.mapper@3.0-vts",
|
||||
"android.hardware.graphics.mapper@4.0-vts",
|
||||
"libaidlcommonsupport",
|
||||
"libgtest",
|
||||
"librenderengine",
|
||||
"libshaders",
|
||||
"libtonemap",
|
||||
],
|
||||
cflags: [
|
||||
"-Wconversion",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -29,6 +29,8 @@ cc_library_static {
|
||||
srcs: [
|
||||
"GraphicsComposerCallback.cpp",
|
||||
"TestCommandReader.cpp",
|
||||
"ReadbackVts.cpp",
|
||||
"RenderEngineVts.cpp",
|
||||
],
|
||||
header_libs: [
|
||||
"android.hardware.graphics.composer3-command-buffer",
|
||||
@@ -38,20 +40,32 @@ cc_library_static {
|
||||
"android.hardware.graphics.common-V3-ndk",
|
||||
"android.hardware.common-V2-ndk",
|
||||
"android.hardware.common.fmq-V1-ndk",
|
||||
"libarect",
|
||||
"libgtest",
|
||||
"libbase",
|
||||
"libfmq",
|
||||
"libsync",
|
||||
"libmath",
|
||||
"libaidlcommonsupport",
|
||||
"libnativewindow",
|
||||
"librenderengine",
|
||||
"libshaders",
|
||||
"libtonemap",
|
||||
"android.hardware.graphics.mapper@2.0-vts",
|
||||
"android.hardware.graphics.mapper@2.1-vts",
|
||||
"android.hardware.graphics.mapper@3.0-vts",
|
||||
"android.hardware.graphics.mapper@4.0-vts",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbinder_ndk",
|
||||
"libhidlbase",
|
||||
"libui",
|
||||
"android.hardware.graphics.composer3-V1-ndk",
|
||||
],
|
||||
export_static_lib_headers: [
|
||||
"android.hardware.graphics.mapper@2.1-vts",
|
||||
"librenderengine",
|
||||
],
|
||||
cflags: [
|
||||
"-O0",
|
||||
"-g",
|
||||
|
||||
@@ -0,0 +1,360 @@
|
||||
/**
|
||||
* Copyright (c) 2021, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// TODO(b/129481165): remove the #pragma below and fix conversion issues
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
|
||||
#include "include/ReadbackVts.h"
|
||||
#include <aidl/android/hardware/graphics/common/BufferUsage.h>
|
||||
#include "include/RenderEngineVts.h"
|
||||
#include "renderengine/ExternalTexture.h"
|
||||
|
||||
// TODO(b/129481165): remove the #pragma below and fix conversion issues
|
||||
#pragma clang diagnostic pop // ignored "-Wconversion
|
||||
|
||||
namespace aidl::android::hardware::graphics::composer3::vts {
|
||||
|
||||
const std::vector<ColorMode> ReadbackHelper::colorModes = {ColorMode::SRGB, ColorMode::DISPLAY_P3};
|
||||
const std::vector<Dataspace> ReadbackHelper::dataspaces = {common::Dataspace::SRGB,
|
||||
common::Dataspace::DISPLAY_P3};
|
||||
|
||||
void TestLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
|
||||
writer->selectLayer(mLayer);
|
||||
writer->setLayerDisplayFrame(mDisplayFrame);
|
||||
writer->setLayerSourceCrop(mSourceCrop);
|
||||
writer->setLayerZOrder(mZOrder);
|
||||
writer->setLayerSurfaceDamage(mSurfaceDamage);
|
||||
writer->setLayerTransform(mTransform);
|
||||
writer->setLayerPlaneAlpha(mAlpha);
|
||||
writer->setLayerBlendMode(mBlendMode);
|
||||
}
|
||||
|
||||
std::string ReadbackHelper::getColorModeString(ColorMode mode) {
|
||||
switch (mode) {
|
||||
case ColorMode::SRGB:
|
||||
return {"SRGB"};
|
||||
case ColorMode::DISPLAY_P3:
|
||||
return {"DISPLAY_P3"};
|
||||
default:
|
||||
return {"Unsupported color mode for readback"};
|
||||
}
|
||||
}
|
||||
|
||||
std::string ReadbackHelper::getDataspaceString(common::Dataspace dataspace) {
|
||||
switch (dataspace) {
|
||||
case common::Dataspace::SRGB:
|
||||
return {"SRGB"};
|
||||
case common::Dataspace::DISPLAY_P3:
|
||||
return {"DISPLAY_P3"};
|
||||
case common::Dataspace::UNKNOWN:
|
||||
return {"UNKNOWN"};
|
||||
default:
|
||||
return {"Unsupported dataspace for readback"};
|
||||
}
|
||||
}
|
||||
|
||||
Dataspace ReadbackHelper::getDataspaceForColorMode(ColorMode mode) {
|
||||
switch (mode) {
|
||||
case ColorMode::DISPLAY_P3:
|
||||
return Dataspace::DISPLAY_P3;
|
||||
case ColorMode::SRGB:
|
||||
default:
|
||||
return common::Dataspace::UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
LayerSettings TestLayer::toRenderEngineLayerSettings() {
|
||||
LayerSettings layerSettings;
|
||||
|
||||
layerSettings.alpha = ::android::half(mAlpha);
|
||||
layerSettings.disableBlending = mBlendMode == BlendMode::NONE;
|
||||
layerSettings.geometry.boundaries = ::android::FloatRect(
|
||||
static_cast<float>(mDisplayFrame.left), static_cast<float>(mDisplayFrame.top),
|
||||
static_cast<float>(mDisplayFrame.right), static_cast<float>(mDisplayFrame.bottom));
|
||||
|
||||
const ::android::mat4 translation = ::android::mat4::translate(::android::vec4(
|
||||
(static_cast<uint64_t>(mTransform) & static_cast<uint64_t>(Transform::FLIP_H)
|
||||
? static_cast<float>(-mDisplayFrame.right)
|
||||
: 0.0f),
|
||||
(static_cast<uint64_t>(mTransform) & static_cast<uint64_t>(Transform::FLIP_V)
|
||||
? static_cast<float>(-mDisplayFrame.bottom)
|
||||
: 0.0f),
|
||||
0.0f, 1.0f));
|
||||
|
||||
const ::android::mat4 scale = ::android::mat4::scale(::android::vec4(
|
||||
static_cast<uint64_t>(mTransform) & static_cast<uint64_t>(Transform::FLIP_H) ? -1.0f
|
||||
: 1.0f,
|
||||
static_cast<uint64_t>(mTransform) & static_cast<uint64_t>(Transform::FLIP_V) ? -1.0f
|
||||
: 1.0f,
|
||||
1.0f, 1.0f));
|
||||
|
||||
layerSettings.geometry.positionTransform = scale * translation;
|
||||
|
||||
return layerSettings;
|
||||
}
|
||||
|
||||
int32_t ReadbackHelper::GetBytesPerPixel(common::PixelFormat pixelFormat) {
|
||||
switch (pixelFormat) {
|
||||
case common::PixelFormat::RGBA_8888:
|
||||
return 4;
|
||||
case common::PixelFormat::RGB_888:
|
||||
return 3;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void ReadbackHelper::fillBuffer(uint32_t width, uint32_t height, uint32_t stride, void* bufferData,
|
||||
common::PixelFormat pixelFormat,
|
||||
std::vector<Color> desiredPixelColors) {
|
||||
ASSERT_TRUE(pixelFormat == common::PixelFormat::RGB_888 ||
|
||||
pixelFormat == common::PixelFormat::RGBA_8888);
|
||||
int32_t bytesPerPixel = GetBytesPerPixel(pixelFormat);
|
||||
ASSERT_NE(-1, bytesPerPixel);
|
||||
for (int row = 0; row < height; row++) {
|
||||
for (int col = 0; col < width; col++) {
|
||||
auto pixel = row * static_cast<int32_t>(width) + col;
|
||||
Color srcColor = desiredPixelColors[static_cast<size_t>(pixel)];
|
||||
|
||||
int offset = (row * static_cast<int32_t>(stride) + col) * bytesPerPixel;
|
||||
uint8_t* pixelColor = (uint8_t*)bufferData + offset;
|
||||
pixelColor[0] = static_cast<uint8_t>(srcColor.r);
|
||||
pixelColor[1] = static_cast<uint8_t>(srcColor.g);
|
||||
pixelColor[2] = static_cast<uint8_t>(srcColor.b);
|
||||
|
||||
if (bytesPerPixel == 4) {
|
||||
pixelColor[3] = static_cast<uint8_t>(srcColor.a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ReadbackHelper::clearColors(std::vector<Color>& expectedColors, int32_t width, int32_t height,
|
||||
int32_t displayWidth) {
|
||||
for (int row = 0; row < height; row++) {
|
||||
for (int col = 0; col < width; col++) {
|
||||
int pixel = row * displayWidth + col;
|
||||
expectedColors[static_cast<size_t>(pixel)] = BLACK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ReadbackHelper::fillColorsArea(std::vector<Color>& expectedColors, int32_t stride, Rect area,
|
||||
Color color) {
|
||||
for (int row = area.top; row < area.bottom; row++) {
|
||||
for (int col = area.left; col < area.right; col++) {
|
||||
int pixel = row * stride + col;
|
||||
expectedColors[static_cast<size_t>(pixel)] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ReadbackHelper::readbackSupported(const common::PixelFormat& pixelFormat,
|
||||
const common::Dataspace& dataspace) {
|
||||
if (pixelFormat != common::PixelFormat::RGB_888 &&
|
||||
pixelFormat != common::PixelFormat::RGBA_8888) {
|
||||
return false;
|
||||
}
|
||||
if (std::find(dataspaces.begin(), dataspaces.end(), dataspace) == dataspaces.end()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ReadbackHelper::compareColorBuffers(std::vector<Color>& expectedColors, void* bufferData,
|
||||
const int32_t stride, const uint32_t width,
|
||||
const uint32_t height, common::PixelFormat pixelFormat) {
|
||||
const int32_t bytesPerPixel = ReadbackHelper::GetBytesPerPixel(pixelFormat);
|
||||
ASSERT_NE(-1, bytesPerPixel);
|
||||
for (int row = 0; row < height; row++) {
|
||||
for (int col = 0; col < width; col++) {
|
||||
auto pixel = row * static_cast<int32_t>(width) + col;
|
||||
int offset = (row * stride + col) * bytesPerPixel;
|
||||
uint8_t* pixelColor = (uint8_t*)bufferData + offset;
|
||||
|
||||
ASSERT_EQ(static_cast<int8_t>(expectedColors[static_cast<size_t>(pixel)].r),
|
||||
pixelColor[0]);
|
||||
ASSERT_EQ(static_cast<int8_t>(expectedColors[static_cast<size_t>(pixel)].g),
|
||||
pixelColor[1]);
|
||||
ASSERT_EQ(static_cast<int8_t>(expectedColors[static_cast<size_t>(pixel)].b),
|
||||
pixelColor[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ReadbackBuffer::ReadbackBuffer(int64_t display, const std::shared_ptr<IComposerClient>& client,
|
||||
const ::android::sp<::android::GraphicBuffer>& graphicBuffer,
|
||||
int32_t width, int32_t height, common::PixelFormat pixelFormat,
|
||||
common::Dataspace dataspace) {
|
||||
mDisplay = display;
|
||||
|
||||
mComposerClient = client;
|
||||
mGraphicBuffer = graphicBuffer;
|
||||
|
||||
mPixelFormat = pixelFormat;
|
||||
mDataspace = dataspace;
|
||||
|
||||
mWidth = static_cast<uint32_t>(width);
|
||||
mHeight = static_cast<uint32_t>(height);
|
||||
mLayerCount = 1;
|
||||
mUsage = static_cast<uint64_t>(static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
|
||||
static_cast<uint64_t>(common::BufferUsage::GPU_TEXTURE));
|
||||
|
||||
mAccessRegion.top = 0;
|
||||
mAccessRegion.left = 0;
|
||||
mAccessRegion.right = static_cast<int32_t>(width);
|
||||
mAccessRegion.bottom = static_cast<int32_t>(height);
|
||||
}
|
||||
|
||||
::android::sp<::android::GraphicBuffer> ReadbackBuffer::allocate() {
|
||||
return ::android::sp<::android::GraphicBuffer>::make(
|
||||
mWidth, mHeight, static_cast<::android::PixelFormat>(mPixelFormat), mLayerCount, mUsage,
|
||||
"ReadbackVts");
|
||||
}
|
||||
|
||||
void ReadbackBuffer::setReadbackBuffer() {
|
||||
mGraphicBuffer = allocate();
|
||||
ASSERT_NE(nullptr, mGraphicBuffer);
|
||||
ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
|
||||
aidl::android::hardware::common::NativeHandle bufferHandle =
|
||||
::android::dupToAidl(mGraphicBuffer->handle);
|
||||
::ndk::ScopedFileDescriptor fence = ::ndk::ScopedFileDescriptor(-1);
|
||||
EXPECT_TRUE(mComposerClient->setReadbackBuffer(mDisplay, bufferHandle, fence).isOk());
|
||||
}
|
||||
|
||||
void ReadbackBuffer::checkReadbackBuffer(std::vector<Color> expectedColors) {
|
||||
// lock buffer for reading
|
||||
ndk::ScopedFileDescriptor fenceHandle;
|
||||
EXPECT_TRUE(mComposerClient->getReadbackBufferFence(mDisplay, &fenceHandle).isOk());
|
||||
|
||||
int outBytesPerPixel;
|
||||
int outBytesPerStride;
|
||||
auto status = mGraphicBuffer->lockAsync(mUsage, mAccessRegion, nullptr, fenceHandle.get(),
|
||||
&outBytesPerPixel, &outBytesPerStride);
|
||||
EXPECT_EQ(::android::OK, status);
|
||||
ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888);
|
||||
ReadbackHelper::compareColorBuffers(expectedColors, mGraphicBuffer.get(),
|
||||
static_cast<int32_t>(mStride), mWidth, mHeight,
|
||||
mPixelFormat);
|
||||
status = mGraphicBuffer->unlock();
|
||||
EXPECT_EQ(::android::OK, status);
|
||||
}
|
||||
|
||||
void TestColorLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
|
||||
TestLayer::write(writer);
|
||||
writer->setLayerCompositionType(Composition::SOLID_COLOR);
|
||||
writer->setLayerColor(mColor);
|
||||
}
|
||||
|
||||
LayerSettings TestColorLayer::toRenderEngineLayerSettings() {
|
||||
LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
|
||||
|
||||
layerSettings.source.solidColor =
|
||||
::android::half3(static_cast<::android::half>(mColor.r) / 255.0,
|
||||
static_cast<::android::half>(mColor.g) / 255.0,
|
||||
static_cast<::android::half>(mColor.b) / 255.0);
|
||||
layerSettings.alpha =
|
||||
mAlpha * static_cast<float>((static_cast<::android::half>(mColor.a) / 255.0));
|
||||
return layerSettings;
|
||||
}
|
||||
|
||||
TestBufferLayer::TestBufferLayer(const std::shared_ptr<IComposerClient>& client,
|
||||
const ::android::sp<::android::GraphicBuffer>& graphicBuffer,
|
||||
TestRenderEngine& renderEngine, int32_t display, uint32_t width,
|
||||
uint32_t height, common::PixelFormat format,
|
||||
Composition composition)
|
||||
: TestLayer{client, display}, mRenderEngine(renderEngine) {
|
||||
mGraphicBuffer = graphicBuffer;
|
||||
mComposition = composition;
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
mLayerCount = 1;
|
||||
mPixelFormat = format;
|
||||
mUsage = (static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
|
||||
static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
|
||||
static_cast<uint64_t>(common::BufferUsage::COMPOSER_OVERLAY) |
|
||||
static_cast<uint64_t>(common::BufferUsage::GPU_TEXTURE));
|
||||
|
||||
mAccessRegion.top = 0;
|
||||
mAccessRegion.left = 0;
|
||||
mAccessRegion.right = static_cast<int32_t>(width);
|
||||
mAccessRegion.bottom = static_cast<int32_t>(height);
|
||||
|
||||
setSourceCrop({0, 0, (float)width, (float)height});
|
||||
}
|
||||
|
||||
void TestBufferLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
|
||||
TestLayer::write(writer);
|
||||
writer->setLayerCompositionType(mComposition);
|
||||
writer->setLayerVisibleRegion(std::vector<Rect>(1, mDisplayFrame));
|
||||
if (mGraphicBuffer->handle != nullptr)
|
||||
writer->setLayerBuffer(0, mGraphicBuffer->handle, mFillFence);
|
||||
}
|
||||
|
||||
LayerSettings TestBufferLayer::toRenderEngineLayerSettings() {
|
||||
LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
|
||||
layerSettings.source.buffer.buffer = std::make_shared<::android::renderengine::ExternalTexture>(
|
||||
::android::sp<::android::GraphicBuffer>::make(
|
||||
mGraphicBuffer->handle, ::android::GraphicBuffer::CLONE_HANDLE, mWidth, mHeight,
|
||||
static_cast<int32_t>(mPixelFormat), 1, mUsage, mStride),
|
||||
mRenderEngine.getInternalRenderEngine(),
|
||||
::android::renderengine::ExternalTexture::Usage::READABLE);
|
||||
|
||||
layerSettings.source.buffer.usePremultipliedAlpha = mBlendMode == BlendMode::PREMULTIPLIED;
|
||||
|
||||
const float scaleX = (mSourceCrop.right - mSourceCrop.left) / (static_cast<float>(mWidth));
|
||||
const float scaleY = (mSourceCrop.bottom - mSourceCrop.top) / (static_cast<float>(mHeight));
|
||||
const float translateX = mSourceCrop.left / (static_cast<float>(mWidth));
|
||||
const float translateY = mSourceCrop.top / (static_cast<float>(mHeight));
|
||||
|
||||
layerSettings.source.buffer.textureTransform =
|
||||
::android::mat4::translate(::android::vec4(translateX, translateY, 0, 1)) *
|
||||
::android::mat4::scale(::android::vec4(scaleX, scaleY, 1.0, 1.0));
|
||||
|
||||
return layerSettings;
|
||||
}
|
||||
|
||||
void TestBufferLayer::fillBuffer(std::vector<Color>& expectedColors) {
|
||||
void* bufData;
|
||||
auto status = mGraphicBuffer->lock(mUsage, &bufData);
|
||||
EXPECT_EQ(::android::OK, status);
|
||||
ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(mWidth, mHeight, mStride, bufData,
|
||||
mPixelFormat, expectedColors));
|
||||
EXPECT_EQ(::android::OK, mGraphicBuffer->unlock());
|
||||
}
|
||||
|
||||
void TestBufferLayer::setBuffer(std::vector<Color> colors) {
|
||||
mGraphicBuffer->reallocate(mWidth, mHeight, static_cast<::android::PixelFormat>(mPixelFormat),
|
||||
mLayerCount, mUsage);
|
||||
ASSERT_NE(nullptr, mGraphicBuffer);
|
||||
ASSERT_NE(nullptr, mGraphicBuffer->handle);
|
||||
ASSERT_NO_FATAL_FAILURE(fillBuffer(colors));
|
||||
ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
|
||||
}
|
||||
|
||||
void TestBufferLayer::setDataspace(common::Dataspace dataspace,
|
||||
const std::shared_ptr<CommandWriterBase>& writer) {
|
||||
writer->selectLayer(mLayer);
|
||||
writer->setLayerDataspace(dataspace);
|
||||
}
|
||||
|
||||
void TestBufferLayer::setToClientComposition(const std::shared_ptr<CommandWriterBase>& writer) {
|
||||
writer->selectLayer(mLayer);
|
||||
writer->setLayerCompositionType(Composition::CLIENT);
|
||||
}
|
||||
|
||||
} // namespace aidl::android::hardware::graphics::composer3::vts
|
||||
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* Copyright (c) 2021, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "include/RenderEngineVts.h"
|
||||
|
||||
namespace aidl::android::hardware::graphics::composer3::vts {
|
||||
|
||||
using ::android::hardware::graphics::mapper::V2_1::IMapper;
|
||||
using ::android::renderengine::DisplaySettings;
|
||||
using ::android::renderengine::LayerSettings;
|
||||
using ::android::renderengine::RenderEngineCreationArgs;
|
||||
|
||||
TestRenderEngine::TestRenderEngine(const RenderEngineCreationArgs& args) {
|
||||
mFormat = static_cast<common::PixelFormat>(args.pixelFormat);
|
||||
mRenderEngine = ::android::renderengine::RenderEngine::create(args);
|
||||
}
|
||||
|
||||
TestRenderEngine::~TestRenderEngine() {
|
||||
mRenderEngine.release();
|
||||
}
|
||||
|
||||
void TestRenderEngine::setRenderLayers(std::vector<std::shared_ptr<TestLayer>> layers) {
|
||||
sort(layers.begin(), layers.end(),
|
||||
[](const std::shared_ptr<TestLayer>& lhs, const std::shared_ptr<TestLayer>& rhs) -> bool {
|
||||
return lhs->getZOrder() < rhs->getZOrder();
|
||||
});
|
||||
|
||||
if (!mCompositionLayers.empty()) {
|
||||
mCompositionLayers.clear();
|
||||
}
|
||||
for (auto& layer : layers) {
|
||||
LayerSettings settings = layer->toRenderEngineLayerSettings();
|
||||
mCompositionLayers.push_back(settings);
|
||||
}
|
||||
}
|
||||
|
||||
void TestRenderEngine::initGraphicBuffer(uint32_t width, uint32_t height, uint32_t layerCount,
|
||||
uint64_t usage) {
|
||||
mGraphicBuffer = ::android::sp<::android::GraphicBuffer>::make(
|
||||
width, height, static_cast<int32_t>(mFormat), layerCount, usage);
|
||||
}
|
||||
|
||||
void TestRenderEngine::drawLayers() {
|
||||
::android::base::unique_fd bufferFence;
|
||||
|
||||
std::vector<::android::renderengine::LayerSettings> compositionLayers;
|
||||
compositionLayers.reserve(mCompositionLayers.size());
|
||||
std::transform(mCompositionLayers.begin(), mCompositionLayers.end(),
|
||||
std::back_insert_iterator(compositionLayers),
|
||||
[](::android::renderengine::LayerSettings& settings)
|
||||
-> ::android::renderengine::LayerSettings { return settings; });
|
||||
auto texture = std::make_shared<::android::renderengine::ExternalTexture>(
|
||||
mGraphicBuffer, *mRenderEngine,
|
||||
::android::renderengine::ExternalTexture::Usage::WRITEABLE);
|
||||
auto [status, readyFence] = mRenderEngine
|
||||
->drawLayers(mDisplaySettings, compositionLayers, texture,
|
||||
true, std::move(bufferFence))
|
||||
.get();
|
||||
int fd = readyFence.release();
|
||||
if (fd != -1) {
|
||||
ASSERT_EQ(0, sync_wait(fd, -1));
|
||||
ASSERT_EQ(0, close(fd));
|
||||
}
|
||||
}
|
||||
|
||||
void TestRenderEngine::checkColorBuffer(std::vector<Color>& expectedColors) {
|
||||
void* bufferData;
|
||||
ASSERT_EQ(0,
|
||||
mGraphicBuffer->lock(static_cast<uint32_t>(mGraphicBuffer->getUsage()), &bufferData));
|
||||
ReadbackHelper::compareColorBuffers(
|
||||
expectedColors, bufferData, static_cast<int32_t>(mGraphicBuffer->getStride()),
|
||||
mGraphicBuffer->getWidth(), mGraphicBuffer->getHeight(), mFormat);
|
||||
ASSERT_EQ(::android::OK, mGraphicBuffer->unlock());
|
||||
}
|
||||
|
||||
} // namespace aidl::android::hardware::graphics::composer3::vts
|
||||
@@ -0,0 +1,214 @@
|
||||
/**
|
||||
* Copyright (c) 2021, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// TODO(b/129481165): remove the #pragma below and fix conversion issues
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
|
||||
#include <GraphicsComposerCallback.h>
|
||||
#include <TestCommandReader.h>
|
||||
#include <aidl/android/hardware/graphics/composer3/IComposerClient.h>
|
||||
#include <android-base/unique_fd.h>
|
||||
#include <android/hardware/graphics/composer3/command-buffer.h>
|
||||
#include <mapper-vts/2.1/MapperVts.h>
|
||||
#include <renderengine/RenderEngine.h>
|
||||
#include <ui/GraphicBuffer.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
// TODO(b/129481165): remove the #pragma below and fix conversion issues
|
||||
#pragma clang diagnostic pop // ignored "-Wconversion
|
||||
|
||||
namespace aidl::android::hardware::graphics::composer3::vts {
|
||||
|
||||
using ::android::renderengine::LayerSettings;
|
||||
using common::Dataspace;
|
||||
using common::PixelFormat;
|
||||
using IMapper2_1 = ::android::hardware::graphics::mapper::V2_1::IMapper;
|
||||
|
||||
static const Color BLACK = {0, 0, 0, static_cast<int8_t>(0xff)};
|
||||
static const Color RED = {static_cast<int8_t>(0xff), 0, 0, static_cast<int8_t>(0xff)};
|
||||
static const Color TRANSLUCENT_RED = {static_cast<int8_t>(0xff), 0, 0, 0x33};
|
||||
static const Color GREEN = {0, static_cast<int8_t>(0xff), 0, static_cast<int8_t>(0xff)};
|
||||
static const Color BLUE = {0, 0, static_cast<int8_t>(0xff), static_cast<int8_t>(0xff)};
|
||||
static const Color WHITE = {static_cast<int8_t>(0xff), static_cast<int8_t>(0xff),
|
||||
static_cast<int8_t>(0xff), static_cast<int8_t>(0xff)};
|
||||
|
||||
class TestRenderEngine;
|
||||
|
||||
class TestLayer {
|
||||
public:
|
||||
TestLayer(const std::shared_ptr<IComposerClient>& client, int32_t display)
|
||||
: mComposerClient(client) {
|
||||
client->createLayer(display, kBufferSlotCount, &mLayer);
|
||||
}
|
||||
|
||||
// ComposerClient will take care of destroying layers, no need to explicitly
|
||||
// call destroyLayers here
|
||||
virtual ~TestLayer(){};
|
||||
|
||||
virtual void write(const std::shared_ptr<CommandWriterBase>& writer);
|
||||
virtual LayerSettings toRenderEngineLayerSettings();
|
||||
|
||||
void setDisplayFrame(Rect frame) { mDisplayFrame = frame; }
|
||||
void setSourceCrop(FRect crop) { mSourceCrop = crop; }
|
||||
void setZOrder(uint32_t z) { mZOrder = z; }
|
||||
|
||||
void setSurfaceDamage(std::vector<Rect> surfaceDamage) {
|
||||
mSurfaceDamage = std::move(surfaceDamage);
|
||||
}
|
||||
|
||||
void setTransform(Transform transform) { mTransform = transform; }
|
||||
void setAlpha(float alpha) { mAlpha = alpha; }
|
||||
void setBlendMode(BlendMode blendMode) { mBlendMode = blendMode; }
|
||||
|
||||
BlendMode getBlendMode() const { return mBlendMode; }
|
||||
|
||||
uint32_t getZOrder() const { return mZOrder; }
|
||||
|
||||
float getAlpha() const { return mAlpha; }
|
||||
|
||||
protected:
|
||||
int64_t mLayer;
|
||||
Rect mDisplayFrame = {0, 0, 0, 0};
|
||||
std::vector<Rect> mSurfaceDamage;
|
||||
Transform mTransform = static_cast<Transform>(0);
|
||||
FRect mSourceCrop = {0, 0, 0, 0};
|
||||
static constexpr uint32_t kBufferSlotCount = 64;
|
||||
float mAlpha = 1.0;
|
||||
BlendMode mBlendMode = BlendMode::NONE;
|
||||
uint32_t mZOrder = 0;
|
||||
|
||||
private:
|
||||
std::shared_ptr<IComposerClient> const mComposerClient;
|
||||
};
|
||||
|
||||
class TestColorLayer : public TestLayer {
|
||||
public:
|
||||
TestColorLayer(const std::shared_ptr<IComposerClient>& client, int32_t display)
|
||||
: TestLayer{client, display} {}
|
||||
|
||||
void write(const std::shared_ptr<CommandWriterBase>& writer) override;
|
||||
|
||||
LayerSettings toRenderEngineLayerSettings() override;
|
||||
|
||||
void setColor(Color color) { mColor = color; }
|
||||
|
||||
private:
|
||||
Color mColor = WHITE;
|
||||
};
|
||||
|
||||
class TestBufferLayer : public TestLayer {
|
||||
public:
|
||||
TestBufferLayer(const std::shared_ptr<IComposerClient>& client,
|
||||
const ::android::sp<::android::GraphicBuffer>& graphicBuffer,
|
||||
TestRenderEngine& renderEngine, int32_t display, uint32_t width,
|
||||
uint32_t height, common::PixelFormat format,
|
||||
Composition composition = Composition::DEVICE);
|
||||
|
||||
void write(const std::shared_ptr<CommandWriterBase>& writer) override;
|
||||
|
||||
LayerSettings toRenderEngineLayerSettings() override;
|
||||
|
||||
void fillBuffer(std::vector<Color>& expectedColors);
|
||||
|
||||
void setBuffer(std::vector<Color> colors);
|
||||
|
||||
void setDataspace(Dataspace dataspace, const std::shared_ptr<CommandWriterBase>& writer);
|
||||
|
||||
void setToClientComposition(const std::shared_ptr<CommandWriterBase>& writer);
|
||||
|
||||
uint32_t getWidth() const { return mWidth; }
|
||||
|
||||
uint32_t getHeight() const { return mHeight; }
|
||||
|
||||
::android::Rect getAccessRegion() const { return mAccessRegion; }
|
||||
|
||||
uint32_t getLayerCount() const { return mLayerCount; }
|
||||
|
||||
protected:
|
||||
Composition mComposition;
|
||||
::android::sp<::android::GraphicBuffer> mGraphicBuffer;
|
||||
TestRenderEngine& mRenderEngine;
|
||||
int32_t mFillFence;
|
||||
uint32_t mWidth;
|
||||
uint32_t mHeight;
|
||||
uint32_t mLayerCount;
|
||||
PixelFormat mPixelFormat;
|
||||
uint32_t mUsage;
|
||||
uint32_t mStride;
|
||||
::android::Rect mAccessRegion;
|
||||
};
|
||||
|
||||
class ReadbackHelper {
|
||||
public:
|
||||
static std::string getColorModeString(ColorMode mode);
|
||||
|
||||
static std::string getDataspaceString(Dataspace dataspace);
|
||||
|
||||
static Dataspace getDataspaceForColorMode(ColorMode mode);
|
||||
|
||||
static int32_t GetBytesPerPixel(PixelFormat pixelFormat);
|
||||
|
||||
static void fillBuffer(uint32_t width, uint32_t height, uint32_t stride, void* bufferData,
|
||||
PixelFormat pixelFormat, std::vector<Color> desiredPixelColors);
|
||||
|
||||
static void clearColors(std::vector<Color>& expectedColors, int32_t width, int32_t height,
|
||||
int32_t displayWidth);
|
||||
|
||||
static void fillColorsArea(std::vector<Color>& expectedColors, int32_t stride, Rect area,
|
||||
Color color);
|
||||
|
||||
static bool readbackSupported(const PixelFormat& pixelFormat, const Dataspace& dataspace);
|
||||
|
||||
static const std::vector<ColorMode> colorModes;
|
||||
static const std::vector<Dataspace> dataspaces;
|
||||
|
||||
static void compareColorBuffers(std::vector<Color>& expectedColors, void* bufferData,
|
||||
const int32_t stride, const uint32_t width,
|
||||
const uint32_t height, PixelFormat pixelFormat);
|
||||
};
|
||||
|
||||
class ReadbackBuffer {
|
||||
public:
|
||||
ReadbackBuffer(int64_t display, const std::shared_ptr<IComposerClient>& client,
|
||||
const ::android::sp<::android::GraphicBuffer>& graphicBuffer, int32_t width,
|
||||
int32_t height, common::PixelFormat pixelFormat, common::Dataspace dataspace);
|
||||
|
||||
void setReadbackBuffer();
|
||||
|
||||
void checkReadbackBuffer(std::vector<Color> expectedColors);
|
||||
|
||||
::android::sp<::android::GraphicBuffer> allocate();
|
||||
|
||||
protected:
|
||||
uint32_t mWidth;
|
||||
uint32_t mHeight;
|
||||
uint32_t mLayerCount;
|
||||
uint32_t mUsage;
|
||||
uint32_t mStride;
|
||||
PixelFormat mPixelFormat;
|
||||
Dataspace mDataspace;
|
||||
int64_t mDisplay;
|
||||
::android::sp<::android::GraphicBuffer> mGraphicBuffer;
|
||||
std::shared_ptr<IComposerClient> mComposerClient;
|
||||
::android::Rect mAccessRegion;
|
||||
native_handle_t mBufferHandle;
|
||||
};
|
||||
|
||||
} // namespace aidl::android::hardware::graphics::composer3::vts
|
||||
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Copyright (c) 2021, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// TODO(b/129481165): remove the #pragma below and fix conversion issues
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
|
||||
#include <ReadbackVts.h>
|
||||
#include <mapper-vts/2.1/MapperVts.h>
|
||||
#include <math/half.h>
|
||||
#include <math/vec3.h>
|
||||
#include <renderengine/ExternalTexture.h>
|
||||
#include <renderengine/RenderEngine.h>
|
||||
#include <ui/GraphicBuffer.h>
|
||||
#include <ui/GraphicBufferAllocator.h>
|
||||
#include <ui/PixelFormat.h>
|
||||
#include <ui/Rect.h>
|
||||
#include <ui/Region.h>
|
||||
|
||||
// TODO(b/129481165): remove the #pragma below and fix conversion issues
|
||||
#pragma clang diagnostic pop // ignored "-Wconversion
|
||||
|
||||
namespace aidl::android::hardware::graphics::composer3::vts {
|
||||
|
||||
using ::android::hardware::graphics::mapper::V2_1::IMapper;
|
||||
using ::android::renderengine::DisplaySettings;
|
||||
using ::android::renderengine::ExternalTexture;
|
||||
using ::android::renderengine::RenderEngineCreationArgs;
|
||||
|
||||
class TestRenderEngine {
|
||||
public:
|
||||
static constexpr uint32_t sMaxFrameBufferAcquireBuffers = 2;
|
||||
|
||||
TestRenderEngine(const RenderEngineCreationArgs& args);
|
||||
~TestRenderEngine();
|
||||
|
||||
void setRenderLayers(std::vector<std::shared_ptr<TestLayer>> layers);
|
||||
void initGraphicBuffer(uint32_t width, uint32_t height, uint32_t layerCount, uint64_t usage);
|
||||
void setDisplaySettings(DisplaySettings& displaySettings) {
|
||||
mDisplaySettings = displaySettings;
|
||||
};
|
||||
void drawLayers();
|
||||
void checkColorBuffer(std::vector<Color>& expectedColors);
|
||||
|
||||
::android::renderengine::RenderEngine& getInternalRenderEngine() { return *mRenderEngine; }
|
||||
|
||||
private:
|
||||
common::PixelFormat mFormat;
|
||||
std::vector<::android::renderengine::LayerSettings> mCompositionLayers;
|
||||
std::unique_ptr<::android::renderengine::RenderEngine> mRenderEngine;
|
||||
std::vector<::android::renderengine::LayerSettings> mRenderLayers;
|
||||
::android::sp<::android::GraphicBuffer> mGraphicBuffer;
|
||||
|
||||
DisplaySettings mDisplaySettings;
|
||||
};
|
||||
|
||||
} // namespace aidl::android::hardware::graphics::composer3::vts
|
||||
Reference in New Issue
Block a user