Add VTS readback tests for buffer slot clearing
Bug: 258196272
Test: atest VtsHalGraphicsComposer3_ReadbackTest
Test: atest VtsHalGraphicsComposerV2_2TargetTest
Change-Id: I95d24f9cf10d95e54bc228c02bedab9a8281cfd1
diff --git a/graphics/composer/2.2/utils/vts/ComposerVts.cpp b/graphics/composer/2.2/utils/vts/ComposerVts.cpp
index b706596..a6dfcaf 100644
--- a/graphics/composer/2.2/utils/vts/ComposerVts.cpp
+++ b/graphics/composer/2.2/utils/vts/ComposerVts.cpp
@@ -126,15 +126,23 @@
ASSERT_EQ(Error::NONE, error) << "failed to setReadbackBuffer";
}
-void ComposerClient::getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
- Dataspace* outDataspace) {
+void ComposerClient::getRequiredReadbackBufferAttributes(Display display,
+ PixelFormat* outPixelFormat,
+ Dataspace* outDataspace) {
+ ASSERT_EQ(Error::NONE, getReadbackBufferAttributes(display, outPixelFormat, outDataspace));
+}
+
+Error ComposerClient::getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
+ Dataspace* outDataspace) {
+ Error error;
mClient->getReadbackBufferAttributes(
- display,
- [&](const auto& tmpError, const auto& tmpOutPixelFormat, const auto& tmpOutDataspace) {
- ASSERT_EQ(Error::NONE, tmpError) << "failed to get readback buffer attributes";
- *outPixelFormat = tmpOutPixelFormat;
- *outDataspace = tmpOutDataspace;
- });
+ display, [&](const Error& tmpError, const PixelFormat& tmpPixelFormat,
+ const Dataspace& tmpDataspace) {
+ error = tmpError;
+ *outPixelFormat = tmpPixelFormat;
+ *outDataspace = tmpDataspace;
+ });
+ return error;
}
void ComposerClient::getReadbackBufferFence(Display display, int32_t* outFence) {
diff --git a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp
index a1794af..5dd68df 100644
--- a/graphics/composer/2.2/utils/vts/ReadbackVts.cpp
+++ b/graphics/composer/2.2/utils/vts/ReadbackVts.cpp
@@ -19,6 +19,8 @@
#include "renderengine/ExternalTexture.h"
#include "renderengine/impl/ExternalTexture.h"
+using ::android::status_t;
+
namespace android {
namespace hardware {
namespace graphics {
@@ -107,6 +109,40 @@
}
}
+void ReadbackHelper::fillBufferAndGetFence(const sp<GraphicBuffer>& graphicBuffer,
+ IComposerClient::Color desiredColor, int* fillFence) {
+ ASSERT_NE(nullptr, fillFence);
+ std::vector<IComposerClient::Color> desiredColors(
+ static_cast<size_t>(graphicBuffer->getWidth() * graphicBuffer->getHeight()));
+ ::android::Rect bounds = graphicBuffer->getBounds();
+ fillColorsArea(desiredColors, static_cast<int32_t>(graphicBuffer->getWidth()),
+ {bounds.left, bounds.top, bounds.right, bounds.bottom}, desiredColor);
+ ASSERT_NO_FATAL_FAILURE(fillBufferAndGetFence(graphicBuffer, desiredColors, fillFence));
+}
+
+void ReadbackHelper::fillBufferAndGetFence(const sp<GraphicBuffer>& graphicBuffer,
+ const std::vector<IComposerClient::Color>& desiredColors,
+ int* fillFence) {
+ ASSERT_TRUE(graphicBuffer->getPixelFormat() == ::android::PIXEL_FORMAT_RGB_888 ||
+ graphicBuffer->getPixelFormat() == ::android::PIXEL_FORMAT_RGBA_8888);
+ void* bufData;
+ int32_t bytesPerPixel = -1;
+ int32_t bytesPerStride = -1;
+ status_t status =
+ graphicBuffer->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
+ &bufData, &bytesPerPixel, &bytesPerStride);
+ ASSERT_EQ(::android::OK, status);
+
+ const uint32_t stride = (bytesPerPixel > 0 && bytesPerStride > 0)
+ ? static_cast<uint32_t>(bytesPerStride / bytesPerPixel)
+ : graphicBuffer->getStride();
+ ReadbackHelper::fillBuffer(graphicBuffer->getWidth(), graphicBuffer->getHeight(), stride,
+ bufData, static_cast<PixelFormat>(graphicBuffer->getPixelFormat()),
+ desiredColors);
+ status = graphicBuffer->unlockAsync(fillFence);
+ ASSERT_EQ(::android::OK, status);
+}
+
void ReadbackHelper::fillBuffer(int32_t width, int32_t height, uint32_t stride, void* bufferData,
PixelFormat pixelFormat,
std::vector<IComposerClient::Color> desiredPixelColors) {
@@ -116,16 +152,16 @@
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
int pixel = row * width + col;
- IComposerClient::Color srcColor = desiredPixelColors[pixel];
+ IComposerClient::Color desiredColor = desiredPixelColors[pixel];
int offset = (row * stride + col) * bytesPerPixel;
uint8_t* pixelColor = (uint8_t*)bufferData + offset;
- pixelColor[0] = srcColor.r;
- pixelColor[1] = srcColor.g;
- pixelColor[2] = srcColor.b;
+ pixelColor[0] = desiredColor.r;
+ pixelColor[1] = desiredColor.g;
+ pixelColor[2] = desiredColor.b;
if (bytesPerPixel == 4) {
- pixelColor[3] = srcColor.a;
+ pixelColor[3] = desiredColor.a;
}
}
}
@@ -152,12 +188,14 @@
}
}
-bool ReadbackHelper::readbackSupported(const PixelFormat& pixelFormat, const Dataspace& dataspace,
- const Error error) {
+bool ReadbackHelper::readbackSupported(PixelFormat pixelFormat, Dataspace dataspace, Error error) {
if (error != Error::NONE) {
return false;
}
- // TODO: add support for RGBA_1010102
+ return readbackSupported(pixelFormat, dataspace);
+}
+
+bool ReadbackHelper::readbackSupported(PixelFormat pixelFormat, Dataspace dataspace) {
if (pixelFormat != PixelFormat::RGB_888 && pixelFormat != PixelFormat::RGBA_8888) {
return false;
}
@@ -167,71 +205,94 @@
return true;
}
-void ReadbackHelper::compareColorBuffers(std::vector<IComposerClient::Color>& expectedColors,
- void* bufferData, const uint32_t stride,
- const uint32_t width, const uint32_t height,
- const 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++) {
- int pixel = row * width + col;
- int offset = (row * stride + col) * bytesPerPixel;
- uint8_t* pixelColor = (uint8_t*)bufferData + offset;
+void ReadbackHelper::createReadbackBuffer(uint32_t width, uint32_t height, PixelFormat pixelFormat,
+ Dataspace dataspace, sp<GraphicBuffer>* graphicBuffer) {
+ ASSERT_NE(nullptr, graphicBuffer);
+ if (!readbackSupported(pixelFormat, dataspace)) {
+ *graphicBuffer = nullptr;
+ }
+ android::PixelFormat bufferFormat = static_cast<android::PixelFormat>(pixelFormat);
+ uint32_t layerCount = 1;
+ uint64_t usage = static_cast<uint64_t>(static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN) |
+ static_cast<uint64_t>(BufferUsage::GPU_TEXTURE));
+ *graphicBuffer = sp<GraphicBuffer>::make(width, height, bufferFormat, layerCount, usage,
+ "ReadbackBuffer");
+ ASSERT_NE(nullptr, *graphicBuffer);
+ ASSERT_EQ(::android::OK, (*graphicBuffer)->initCheck());
+}
- ASSERT_EQ(expectedColors[pixel].r, pixelColor[0]);
- ASSERT_EQ(expectedColors[pixel].g, pixelColor[1]);
- ASSERT_EQ(expectedColors[pixel].b, pixelColor[2]);
+void ReadbackHelper::compareColorToBuffer(IComposerClient::Color expectedColor,
+ const sp<GraphicBuffer>& graphicBuffer, int32_t fence) {
+ std::vector<IComposerClient::Color> expectedColors(
+ static_cast<size_t>(graphicBuffer->getWidth() * graphicBuffer->getHeight()));
+ ::android::Rect bounds = graphicBuffer->getBounds();
+ fillColorsArea(expectedColors, static_cast<int32_t>(graphicBuffer->getWidth()),
+ {bounds.left, bounds.top, bounds.right, bounds.bottom}, expectedColor);
+ compareColorsToBuffer(expectedColors, graphicBuffer, fence);
+}
+
+void ReadbackHelper::compareColorsToBuffer(std::vector<IComposerClient::Color>& expectedColors,
+ const sp<GraphicBuffer>& graphicBuffer, int32_t fence) {
+ ASSERT_TRUE(graphicBuffer->getPixelFormat() == ::android::PIXEL_FORMAT_RGB_888 ||
+ graphicBuffer->getPixelFormat() == ::android::PIXEL_FORMAT_RGBA_8888);
+
+ int bytesPerPixel = -1;
+ int bytesPerStride = -1;
+ void* bufData = nullptr;
+ status_t status = graphicBuffer->lockAsync(GRALLOC_USAGE_SW_READ_OFTEN, &bufData, fence,
+ &bytesPerPixel, &bytesPerStride);
+ ASSERT_EQ(::android::OK, status);
+
+ const uint32_t stride = (bytesPerPixel > 0 && bytesPerStride > 0)
+ ? static_cast<uint32_t>(bytesPerStride / bytesPerPixel)
+ : graphicBuffer->getStride();
+
+ if (bytesPerPixel == -1) {
+ PixelFormat pixelFormat = static_cast<PixelFormat>(graphicBuffer->getPixelFormat());
+ bytesPerPixel = ReadbackHelper::GetBytesPerPixel(pixelFormat);
+ }
+ ASSERT_NE(-1, bytesPerPixel);
+ for (int row = 0; row < graphicBuffer->getHeight(); row++) {
+ for (int col = 0; col < graphicBuffer->getWidth(); col++) {
+ int pixel = row * static_cast<int32_t>(graphicBuffer->getWidth()) + col;
+ int offset = (row * static_cast<int32_t>(stride) + col) * bytesPerPixel;
+ uint8_t* pixelColor = (uint8_t*)bufData + offset;
+ const IComposerClient::Color expectedColor = expectedColors[static_cast<size_t>(pixel)];
+ ASSERT_EQ(std::round(255.0f * expectedColor.r), pixelColor[0]);
+ ASSERT_EQ(std::round(255.0f * expectedColor.g), pixelColor[1]);
+ ASSERT_EQ(std::round(255.0f * expectedColor.b), pixelColor[2]);
}
}
+
+ status = graphicBuffer->unlock();
+ ASSERT_EQ(::android::OK, status);
}
ReadbackBuffer::ReadbackBuffer(Display display, const std::shared_ptr<ComposerClient>& client,
- const std::shared_ptr<Gralloc>& gralloc, uint32_t width,
- uint32_t height, PixelFormat pixelFormat, Dataspace dataspace) {
+ uint32_t width, uint32_t height, PixelFormat pixelFormat) {
mDisplay = display;
-
mComposerClient = client;
- mGralloc = gralloc;
-
- mPixelFormat = pixelFormat;
- mDataspace = dataspace;
-
mWidth = width;
mHeight = height;
+ mPixelFormat = pixelFormat;
mLayerCount = 1;
- mFormat = mPixelFormat;
mUsage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::GPU_TEXTURE);
-
- mAccessRegion.top = 0;
- mAccessRegion.left = 0;
- mAccessRegion.width = width;
- mAccessRegion.height = height;
}
void ReadbackBuffer::setReadbackBuffer() {
- mBufferHandle.reset(new Gralloc::NativeHandleWrapper(
- mGralloc->allocate(mWidth, mHeight, mLayerCount, mFormat, mUsage,
- /*import*/ true, &mStride)));
- ASSERT_NE(false, mGralloc->validateBufferSize(mBufferHandle->get(), mWidth, mHeight,
- mLayerCount, mFormat, mUsage, mStride));
- ASSERT_NO_FATAL_FAILURE(mComposerClient->setReadbackBuffer(mDisplay, mBufferHandle->get(), -1));
+ mGraphicBuffer = sp<GraphicBuffer>::make(mWidth, mHeight,
+ static_cast<::android::PixelFormat>(mPixelFormat),
+ mLayerCount, mUsage, "ReadbackBuffer");
+ ASSERT_NE(nullptr, mGraphicBuffer);
+ ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
+ mComposerClient->setReadbackBuffer(mDisplay, mGraphicBuffer->handle, -1 /* fence */);
}
void ReadbackBuffer::checkReadbackBuffer(std::vector<IComposerClient::Color> expectedColors) {
// lock buffer for reading
int32_t fenceHandle;
ASSERT_NO_FATAL_FAILURE(mComposerClient->getReadbackBufferFence(mDisplay, &fenceHandle));
-
- void* bufData = mGralloc->lock(mBufferHandle->get(), mUsage, mAccessRegion, fenceHandle);
- ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888);
- ReadbackHelper::compareColorBuffers(expectedColors, bufData, mStride, mWidth, mHeight,
- mPixelFormat);
- int32_t unlockFence = mGralloc->unlock(mBufferHandle->get());
- if (unlockFence != -1) {
- sync_wait(unlockFence, -1);
- close(unlockFence);
- }
+ ReadbackHelper::compareColorsToBuffer(expectedColors, mGraphicBuffer, fenceHandle);
}
void TestColorLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
diff --git a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
index 1700b2a..254ff3b 100644
--- a/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
+++ b/graphics/composer/2.2/utils/vts/RenderEngineVts.cpp
@@ -83,9 +83,7 @@
void TestRenderEngine::checkColorBuffer(std::vector<V2_2::IComposerClient::Color>& expectedColors) {
void* bufferData;
ASSERT_EQ(0, mGraphicBuffer->lock(mGraphicBuffer->getUsage(), &bufferData));
- ReadbackHelper::compareColorBuffers(expectedColors, bufferData, mGraphicBuffer->getStride(),
- mGraphicBuffer->getWidth(), mGraphicBuffer->getHeight(),
- mFormat);
+ ReadbackHelper::compareColorsToBuffer(expectedColors, mGraphicBuffer, -1 /* fence */);
ASSERT_EQ(0, mGraphicBuffer->unlock());
}
diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h
index 02d7bdb..bbf8ef3 100644
--- a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h
+++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ComposerVts.h
@@ -78,8 +78,10 @@
PixelFormat format, Dataspace dataspace);
void setPowerMode_2_2(Display display, IComposerClient::PowerMode mode);
void setReadbackBuffer(Display display, const native_handle_t* buffer, int32_t releaseFence);
- void getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
- Dataspace* outDataspace);
+ void getRequiredReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
+ Dataspace* outDataspace);
+ Error getReadbackBufferAttributes(Display display, PixelFormat* outPixelFormat,
+ Dataspace* outDataspace);
void getReadbackBufferFence(Display display, int32_t* outFence);
std::vector<ColorMode> getColorModes(Display display);
diff --git a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h
index 58efde9..7100297 100644
--- a/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h
+++ b/graphics/composer/2.2/utils/vts/include/composer-vts/2.2/ReadbackVts.h
@@ -34,6 +34,8 @@
namespace V2_2 {
namespace vts {
+using android::GraphicBuffer;
+using android::sp;
using android::hardware::hidl_handle;
using common::V1_1::BufferUsage;
using common::V1_1::Dataspace;
@@ -156,6 +158,13 @@
static int32_t GetBytesPerPixel(PixelFormat pixelFormat);
+ static void fillBufferAndGetFence(const sp<GraphicBuffer>& graphicBuffer,
+ IComposerClient::Color desiredColor, int* fillFence);
+
+ static void fillBufferAndGetFence(const sp<GraphicBuffer>& graphicBuffer,
+ const std::vector<IComposerClient::Color>& desiredColors,
+ int* fillFence);
+
static void fillBuffer(int32_t width, int32_t height, uint32_t stride, void* bufferData,
PixelFormat pixelFormat,
std::vector<IComposerClient::Color> desiredPixelColors);
@@ -166,40 +175,39 @@
static void fillColorsArea(std::vector<IComposerClient::Color>& expectedColors, int32_t stride,
IComposerClient::Rect area, IComposerClient::Color color);
- static bool readbackSupported(const PixelFormat& pixelFormat, const Dataspace& dataspace,
- const Error error);
-
static const std::vector<ColorMode> colorModes;
static const std::vector<Dataspace> dataspaces;
- static void compareColorBuffers(std::vector<IComposerClient::Color>& expectedColors,
- void* bufferData, const uint32_t stride, const uint32_t width,
- const uint32_t height, const PixelFormat pixelFormat);
+ static bool readbackSupported(PixelFormat pixelFormat, Dataspace dataspace, Error error);
+ static bool readbackSupported(PixelFormat pixelFormat, Dataspace dataspace);
+
+ static void createReadbackBuffer(uint32_t width, uint32_t height, PixelFormat pixelFormat,
+ Dataspace dataspace, sp<GraphicBuffer>* graphicBuffer);
+
+ static void compareColorToBuffer(IComposerClient::Color expectedColors,
+ const sp<GraphicBuffer>& graphicBuffer, int32_t fence);
+
+ static void compareColorsToBuffer(std::vector<IComposerClient::Color>& expectedColors,
+ const sp<GraphicBuffer>& graphicBuffer, int32_t fence);
};
class ReadbackBuffer {
public:
- ReadbackBuffer(Display display, const std::shared_ptr<ComposerClient>& client,
- const std::shared_ptr<Gralloc>& gralloc, uint32_t width, uint32_t height,
- PixelFormat pixelFormat, Dataspace dataspace);
+ ReadbackBuffer(Display display, const std::shared_ptr<ComposerClient>& client, uint32_t width,
+ uint32_t height, PixelFormat pixelFormat);
void setReadbackBuffer();
void checkReadbackBuffer(std::vector<IComposerClient::Color> expectedColors);
protected:
+ sp<GraphicBuffer> mGraphicBuffer;
uint32_t mWidth;
uint32_t mHeight;
- uint32_t mLayerCount;
- PixelFormat mFormat;
- uint64_t mUsage;
- AccessRegion mAccessRegion;
- uint32_t mStride;
- std::unique_ptr<Gralloc::NativeHandleWrapper> mBufferHandle = nullptr;
PixelFormat mPixelFormat;
- Dataspace mDataspace;
+ uint32_t mLayerCount;
+ uint64_t mUsage;
Display mDisplay;
- std::shared_ptr<Gralloc> mGralloc;
std::shared_ptr<ComposerClient> mComposerClient;
};