Start VTS for color management.
Right now this only makes sure that extended sRGB buffers aren't
corrupted by the time it hits the display. This is especially important
for Ultra HDR, because display compensation is defined by the spec.
Bug: 276331687
Bug: 259144781
Test: VtsHalGraphicsComposer3_ReadbackTest
Change-Id: Ib6c39858289d5559ae76280ca1a0ef756f2daef0
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
index 4b0f336..466954f 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
@@ -70,9 +70,9 @@
ContextPriority::HIGH)
.build())));
- ::android::renderengine::DisplaySettings clientCompositionDisplay;
- clientCompositionDisplay.physicalDisplay = Rect(getDisplayWidth(), getDisplayHeight());
- clientCompositionDisplay.clip = clientCompositionDisplay.physicalDisplay;
+ mClientCompositionDisplaySettings.physicalDisplay =
+ Rect(getDisplayWidth(), getDisplayHeight());
+ mClientCompositionDisplaySettings.clip = mClientCompositionDisplaySettings.physicalDisplay;
mTestRenderEngine->initGraphicBuffer(
static_cast<uint32_t>(getDisplayWidth()), static_cast<uint32_t>(getDisplayHeight()),
@@ -81,7 +81,7 @@
static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
static_cast<uint64_t>(common::BufferUsage::GPU_RENDER_TARGET)));
- mTestRenderEngine->setDisplaySettings(clientCompositionDisplay);
+ mTestRenderEngine->setDisplaySettings(mClientCompositionDisplaySettings);
}
void TearDown() override {
@@ -163,6 +163,7 @@
std::unique_ptr<TestRenderEngine> mTestRenderEngine;
common::PixelFormat mPixelFormat;
common::Dataspace mDataspace;
+ ::android::renderengine::DisplaySettings mClientCompositionDisplaySettings;
static constexpr uint32_t kClientTargetSlotCount = 64;
@@ -271,7 +272,7 @@
getDisplayHeight(), common::PixelFormat::RGBA_8888);
layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
layer->setZOrder(10);
- layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
+ layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
std::vector<std::shared_ptr<TestLayer>> layers = {layer};
@@ -455,7 +456,7 @@
getDisplayHeight(), PixelFormat::RGBA_FP16);
layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
layer->setZOrder(10);
- layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
+ layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
std::vector<std::shared_ptr<TestLayer>> layers = {layer};
@@ -553,7 +554,7 @@
deviceLayer->setDisplayFrame({0, 0, static_cast<int32_t>(deviceLayer->getWidth()),
static_cast<int32_t>(deviceLayer->getHeight())});
deviceLayer->setZOrder(10);
- deviceLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
+ deviceLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
ASSERT_NO_FATAL_FAILURE(deviceLayer->setBuffer(deviceColors));
deviceLayer->write(*mWriter);
@@ -640,7 +641,7 @@
getDisplayHeight(), PixelFormat::RGBA_8888);
layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
layer->setZOrder(10);
- layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
+ layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
std::vector<std::shared_ptr<TestLayer>> layers = {layer};
@@ -768,7 +769,7 @@
getDisplayHeight(), PixelFormat::RGBA_8888);
layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
layer->setZOrder(10);
- layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
+ layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
layer->setSourceCrop({0, static_cast<float>(getDisplayHeight() / 2),
static_cast<float>(getDisplayWidth()),
static_cast<float>(getDisplayHeight())});
@@ -987,7 +988,7 @@
getDisplayHeight(), PixelFormat::RGBA_8888);
layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
layer->setZOrder(10);
- layer->setDataspace(Dataspace::UNKNOWN, *mWriter);
+ layer->setDataspace(Dataspace::UNKNOWN);
ASSERT_NO_FATAL_FAILURE(layer->setBuffer(topLayerPixelColors));
layer->setBlendMode(blendMode);
@@ -1222,7 +1223,7 @@
getDisplayHeight(), mPixelFormat, mDataspace);
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
mLayer->setTransform(Transform::FLIP_H);
- mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
+ mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
std::vector<Color> expectedColors(
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
@@ -1268,7 +1269,7 @@
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
mLayer->setTransform(Transform::FLIP_V);
- mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
+ mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
std::vector<Color> expectedColors(
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
@@ -1313,7 +1314,7 @@
ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
mLayer->setTransform(Transform::ROT_180);
- mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode), *mWriter);
+ mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
std::vector<Color> expectedColors(
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
@@ -1342,6 +1343,100 @@
}
}
+class GraphicsColorManagementCompositionTest
+ : public GraphicsCompositionTestBase,
+ public testing::WithParamInterface<std::tuple<std::string, Dataspace, Dataspace, Dataspace>> {
+ public:
+ void SetUp() override {
+ SetUpBase(std::get<0>(GetParam()));
+ // for some reason only sRGB reliably works
+ mTestColorModes.erase(
+ std::remove_if(mTestColorModes.begin(), mTestColorModes.end(),
+ [](ColorMode mode) { return mode != ColorMode::SRGB; }),
+ mTestColorModes.end());
+ auto standard = std::get<1>(GetParam());
+ auto transfer = std::get<2>(GetParam());
+ auto range = std::get<3>(GetParam());
+
+ mLayerDataspace = static_cast<Dataspace>(static_cast<int32_t>(standard) |
+ static_cast<int32_t>(transfer) |
+ static_cast<int32_t>(range));
+ ALOGD("Invoking test for dataspace: {%s, %s, %s}", toString(standard).c_str(),
+ toString(transfer).c_str(), toString(range).c_str());
+ }
+
+ void makeLayer() {
+ mLayer = std::make_shared<TestBufferLayer>(
+ mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
+ getDisplayHeight(), common::PixelFormat::RGBA_8888);
+ mLayer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
+ mLayer->setZOrder(10);
+ mLayer->setAlpha(1.f);
+ mLayer->setDataspace(mLayerDataspace);
+ }
+
+ void fillColor(Color color) {
+ std::vector<Color> baseColors(static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
+ ReadbackHelper::fillColorsArea(baseColors, getDisplayWidth(),
+ common::Rect{.left = 0,
+ .top = 0,
+ .right = getDisplayWidth(),
+ .bottom = getDisplayHeight()},
+ color);
+ ASSERT_NO_FATAL_FAILURE(mLayer->setBuffer(baseColors));
+ }
+
+ Dataspace mLayerDataspace;
+ std::shared_ptr<TestBufferLayer> mLayer;
+};
+
+TEST_P(GraphicsColorManagementCompositionTest, ColorConversion) {
+ 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;
+ }
+
+ mClientCompositionDisplaySettings.outputDataspace =
+ static_cast<::android::ui::Dataspace>(mDataspace);
+ mTestRenderEngine->setDisplaySettings(mClientCompositionDisplaySettings);
+
+ makeLayer();
+ for (auto color : {LIGHT_RED, LIGHT_GREEN, LIGHT_BLUE}) {
+ ALOGD("Testing color: %f, %f, %f, %f with color mode: %d", color.r, color.g, color.b,
+ color.a, mode);
+ ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
+ getDisplayHeight(), mPixelFormat, mDataspace);
+ ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
+ fillColor(color);
+ writeLayers({mLayer});
+ EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
+
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp);
+ execute();
+ if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
+ continue;
+ }
+ ASSERT_TRUE(mReader.takeErrors().empty());
+ mWriter->presentDisplay(getPrimaryDisplayId());
+ execute();
+ ASSERT_TRUE(mReader.takeErrors().empty());
+
+ mTestRenderEngine->setRenderLayers({mLayer});
+ ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
+ ASSERT_NO_FATAL_FAILURE(
+ mTestRenderEngine->checkColorBuffer(readbackBuffer.getBuffer()));
+ }
+ }
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsCompositionTest);
INSTANTIATE_TEST_SUITE_P(
PerInstance, GraphicsCompositionTest,
@@ -1360,5 +1455,17 @@
testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
::android::PrintInstanceNameToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsColorManagementCompositionTest);
+INSTANTIATE_TEST_SUITE_P(PerInstance, GraphicsColorManagementCompositionTest,
+ testing::Combine(testing::ValuesIn(::android::getAidlHalInstanceNames(
+ IComposer::descriptor)),
+ // Only check sRGB, but verify that extended range
+ // doesn't trigger any gamma shifts
+ testing::Values(Dataspace::STANDARD_BT709),
+ testing::Values(Dataspace::TRANSFER_SRGB),
+ // Don't test limited range until we send YUV overlays
+ testing::Values(Dataspace::RANGE_FULL,
+ Dataspace::RANGE_EXTENDED)));
+
} // namespace
} // namespace aidl::android::hardware::graphics::composer3::vts