Merge "Readback tests from VTS 2.2"

This commit is contained in:
Ram Indani
2021-12-03 16:51:28 +00:00
committed by Android (Google) Code Review
7 changed files with 2122 additions and 1 deletions

View File

@@ -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",

View File

@@ -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",

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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