[Lut vts] add readback test
Bug: 377944262
Test: this
Change-Id: Iec108244be303b13f76a84a1fe5ca9dbdbde2737
diff --git a/graphics/composer/aidl/vts/ReadbackVts.cpp b/graphics/composer/aidl/vts/ReadbackVts.cpp
index 9d5928d..b45c8c0 100644
--- a/graphics/composer/aidl/vts/ReadbackVts.cpp
+++ b/graphics/composer/aidl/vts/ReadbackVts.cpp
@@ -37,6 +37,12 @@
writer.setLayerBlendMode(mDisplay, mLayer, mBlendMode);
writer.setLayerBrightness(mDisplay, mLayer, mBrightness);
writer.setLayerDataspace(mDisplay, mLayer, mDataspace);
+ Luts luts{
+ .pfd = ::ndk::ScopedFileDescriptor(dup(mLuts.pfd.get())),
+ .offsets = mLuts.offsets,
+ .lutProperties = mLuts.lutProperties,
+ };
+ writer.setLayerLuts(mDisplay, mLayer, luts);
}
std::string ReadbackHelper::getColorModeString(ColorMode mode) {
@@ -103,6 +109,24 @@
layerSettings.geometry.positionTransform = scale * translation;
layerSettings.whitePointNits = mWhitePointNits;
layerSettings.sourceDataspace = static_cast<::android::ui::Dataspace>(mDataspace);
+ if (mLuts.pfd.get() >= 0 && mLuts.offsets) {
+ std::vector<int32_t> dimensions;
+ std::vector<int32_t> sizes;
+ std::vector<int32_t> keys;
+ dimensions.reserve(mLuts.lutProperties.size());
+ sizes.reserve(mLuts.lutProperties.size());
+ keys.reserve(mLuts.lutProperties.size());
+
+ for (auto& l : mLuts.lutProperties) {
+ dimensions.emplace_back(static_cast<int32_t>(l.dimension));
+ sizes.emplace_back(static_cast<int32_t>(l.size));
+ keys.emplace_back(static_cast<int32_t>(l.samplingKeys[0]));
+ }
+
+ layerSettings.luts = std::make_shared<::android::gui::DisplayLuts>(
+ ::android::base::unique_fd(dup(mLuts.pfd.get())), *mLuts.offsets, dimensions, sizes,
+ keys);
+ }
return layerSettings;
}
diff --git a/graphics/composer/aidl/vts/ReadbackVts.h b/graphics/composer/aidl/vts/ReadbackVts.h
index e3b2384..c04e37a 100644
--- a/graphics/composer/aidl/vts/ReadbackVts.h
+++ b/graphics/composer/aidl/vts/ReadbackVts.h
@@ -17,6 +17,7 @@
#pragma once
#include <aidl/android/hardware/graphics/composer3/IComposerClient.h>
+#include <aidl/android/hardware/graphics/composer3/Luts.h>
#include <android-base/unique_fd.h>
#include <android/hardware/graphics/composer3/ComposerClientReader.h>
#include <android/hardware/graphics/composer3/ComposerClientWriter.h>
@@ -26,6 +27,8 @@
#include "GraphicsComposerCallback.h"
#include "VtsComposerClient.h"
+using aidl::android::hardware::graphics::composer3::Luts;
+
namespace aidl::android::hardware::graphics::composer3::vts {
using ::android::renderengine::LayerSettings;
@@ -80,6 +83,7 @@
void setTransform(Transform transform) { mTransform = transform; }
void setAlpha(float alpha) { mAlpha = alpha; }
void setBlendMode(BlendMode blendMode) { mBlendMode = blendMode; }
+ void setLuts(Luts luts) { mLuts = std::move(luts); }
BlendMode getBlendMode() const { return mBlendMode; }
@@ -105,6 +109,7 @@
BlendMode mBlendMode = BlendMode::NONE;
uint32_t mZOrder = 0;
Dataspace mDataspace = Dataspace::UNKNOWN;
+ Luts mLuts;
};
class TestColorLayer : public TestLayer {
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
index 9db8794..f81289a 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
@@ -20,6 +20,7 @@
#include <aidl/Vintf.h>
#include <aidl/android/hardware/graphics/common/BufferUsage.h>
#include <aidl/android/hardware/graphics/composer3/IComposer.h>
+#include <cutils/ashmem.h>
#include <gtest/gtest.h>
#include <ui/DisplayId.h>
#include <ui/DisplayIdentification.h>
@@ -527,6 +528,118 @@
}
}
+void generateLuts(Luts* luts, LutProperties::Dimension dimension, int32_t size,
+ LutProperties::SamplingKey key) {
+ size_t bufferSize = dimension == LutProperties::Dimension::ONE_D
+ ? static_cast<size_t>(size) * sizeof(float)
+ : static_cast<size_t>(size * size * size) * sizeof(float);
+ int32_t fd = ashmem_create_region("lut_shared_mem", bufferSize);
+ void* ptr = mmap(nullptr, bufferSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ std::vector<float> buffers(static_cast<size_t>(size), 0.5f);
+ memcpy(ptr, buffers.data(), bufferSize);
+ munmap(ptr, bufferSize);
+ luts->pfd = ndk::ScopedFileDescriptor(fd);
+ luts->offsets = std::vector<int32_t>{0};
+ luts->lutProperties = {LutProperties{dimension, size, {key}}};
+}
+
+TEST_P(GraphicsCompositionTest, Luts) {
+ ASSERT_TRUE(
+ mComposerClient->setClientTargetSlotCount(getPrimaryDisplayId(), kClientTargetSlotCount)
+ .isOk());
+ const auto& [status, properties] = mComposerClient->getOverlaySupport();
+ if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
+ status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
+ GTEST_SKIP() << "getOverlaySupport is not supported";
+ return;
+ }
+
+ if (!properties.lutProperties) {
+ GTEST_SKIP() << "lutProperties is not supported";
+ return;
+ }
+
+ for (const auto& lutProperties : *properties.lutProperties) {
+ if (!lutProperties) {
+ continue;
+ }
+ auto& l = *lutProperties;
+
+ for (const auto& key : l.samplingKeys) {
+ for (ColorMode mode : mTestColorModes) {
+ EXPECT_TRUE(mComposerClient
+ ->setColorMode(getPrimaryDisplayId(), mode,
+ RenderIntent::COLORIMETRIC)
+ .isOk());
+
+ bool isSupported;
+ ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
+ if (!isSupported) {
+ GTEST_SUCCEED()
+ << "Readback not supported or unsupported pixelFormat/dataspace";
+ return;
+ }
+
+ common::Rect coloredSquare({0, 0, getDisplayWidth(), getDisplayHeight()});
+
+ // expected color for each pixel
+ std::vector<Color> expectedColors(
+ static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
+ ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), coloredSquare,
+ WHITE);
+
+ auto layer = std::make_shared<TestBufferLayer>(
+ mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(),
+ getDisplayWidth(), getDisplayHeight(), PixelFormat::RGBA_8888, *mWriter);
+ layer->setDisplayFrame(coloredSquare);
+ layer->setZOrder(10);
+ layer->setDataspace(Dataspace::SRGB);
+
+ Luts luts;
+ generateLuts(&luts, l.dimension, l.size, key);
+ layer->setLuts(std::move(luts));
+
+ ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
+
+ std::vector<std::shared_ptr<TestLayer>> layers = {layer};
+
+ ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient,
+ getDisplayWidth(), getDisplayHeight(), mPixelFormat,
+ mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+
+ writeLayers(layers);
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
+ VtsComposerClient::kNoFrameIntervalNs);
+ execute();
+ // if hwc cannot handle and asks for composition change,
+ // just succeed the test
+ if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
+ GTEST_SUCCEED();
+ return;
+ }
+
+ auto changedCompositionTypes =
+ mReader.takeChangedCompositionTypes(getPrimaryDisplayId());
+ ASSERT_TRUE(changedCompositionTypes.empty());
+
+ mWriter->presentDisplay(getPrimaryDisplayId());
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), coloredSquare,
+ {188.f / 255.f, 188.f / 255.f, 188.f / 255.f, 1.0f});
+
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
+ mTestRenderEngine->setRenderLayers(layers);
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
+ }
+ }
+ }
+}
+
TEST_P(GraphicsCompositionTest, MixedColorSpaces) {
ASSERT_TRUE(
mComposerClient->setClientTargetSlotCount(getPrimaryDisplayId(), kClientTargetSlotCount)