Loading graphics/composer/aidl/vts/ReadbackVts.cpp +24 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,12 @@ void TestLayer::write(ComposerClientWriter& writer) { 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) { Loading Loading @@ -103,6 +109,24 @@ LayerSettings TestLayer::toRenderEngineLayerSettings() { 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; } Loading graphics/composer/aidl/vts/ReadbackVts.h +5 −0 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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; Loading Loading @@ -80,6 +83,7 @@ class TestLayer { 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; } Loading @@ -105,6 +109,7 @@ class TestLayer { BlendMode mBlendMode = BlendMode::NONE; uint32_t mZOrder = 0; Dataspace mDataspace = Dataspace::UNKNOWN; Luts mLuts; }; class TestColorLayer : public TestLayer { Loading graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp +113 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -527,6 +528,118 @@ TEST_P(GraphicsCompositionTest, ClientComposition) { } } 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) Loading Loading
graphics/composer/aidl/vts/ReadbackVts.cpp +24 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,12 @@ void TestLayer::write(ComposerClientWriter& writer) { 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) { Loading Loading @@ -103,6 +109,24 @@ LayerSettings TestLayer::toRenderEngineLayerSettings() { 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; } Loading
graphics/composer/aidl/vts/ReadbackVts.h +5 −0 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -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; Loading Loading @@ -80,6 +83,7 @@ class TestLayer { 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; } Loading @@ -105,6 +109,7 @@ class TestLayer { BlendMode mBlendMode = BlendMode::NONE; uint32_t mZOrder = 0; Dataspace mDataspace = Dataspace::UNKNOWN; Luts mLuts; }; class TestColorLayer : public TestLayer { Loading
graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp +113 −0 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -527,6 +528,118 @@ TEST_P(GraphicsCompositionTest, ClientComposition) { } } 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) Loading