blob: d4ce3ba2b662251638157d00e945c392a5ca7757 [file] [log] [blame]
ramindanibab8ba92021-11-18 01:24:11 +00001/**
2 * Copyright (c) 2021, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "graphics_composer_aidl_hal_readback_tests@3"
18
19#include <aidl/Gtest.h>
20#include <aidl/Vintf.h>
Brian Lindahle887a252023-01-17 14:54:19 -070021#include <aidl/android/hardware/graphics/common/BufferUsage.h>
Ady Abraham46219f52021-12-20 09:44:31 -080022#include <aidl/android/hardware/graphics/composer3/IComposer.h>
ramindanibab8ba92021-11-18 01:24:11 +000023#include <gtest/gtest.h>
Alec Mouri51067012022-01-06 17:28:39 -080024#include <ui/DisplayId.h>
25#include <ui/DisplayIdentification.h>
ramindanibab8ba92021-11-18 01:24:11 +000026#include <ui/GraphicBuffer.h>
ramindanibab8ba92021-11-18 01:24:11 +000027#include <ui/PixelFormat.h>
28#include <ui/Rect.h>
ramindani458e53e2022-02-23 17:30:16 +000029#include "GraphicsComposerCallback.h"
30#include "ReadbackVts.h"
31#include "RenderEngineVts.h"
32#include "VtsComposerClient.h"
Alec Mouri51067012022-01-06 17:28:39 -080033
ramindanibab8ba92021-11-18 01:24:11 +000034namespace aidl::android::hardware::graphics::composer3::vts {
35namespace {
36
37using ::android::Rect;
38using common::Dataspace;
39using common::PixelFormat;
40
41class GraphicsCompositionTestBase : public ::testing::Test {
42 protected:
43 void SetUpBase(const std::string& name) {
ramindanidcecfd42022-02-03 23:52:19 +000044 mComposerClient = std::make_shared<VtsComposerClient>(name);
45 ASSERT_TRUE(mComposerClient->createClient().isOk());
ramindanibab8ba92021-11-18 01:24:11 +000046
ramindanidcecfd42022-02-03 23:52:19 +000047 const auto& [status, displays] = mComposerClient->getDisplays();
48 ASSERT_TRUE(status.isOk());
49 mDisplays = displays;
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -040050 mWriter.reset(new ComposerClientWriter(getPrimaryDisplayId()));
ramindanibab8ba92021-11-18 01:24:11 +000051
52 setTestColorModes();
53
54 // explicitly disable vsync
ramindanidcecfd42022-02-03 23:52:19 +000055 for (const auto& display : mDisplays) {
56 EXPECT_TRUE(mComposerClient->setVsync(display.getDisplayId(), /*enable*/ false).isOk());
57 }
58 mComposerClient->setVsyncAllowed(/*isAllowed*/ false);
ramindanibab8ba92021-11-18 01:24:11 +000059
ramindanidcecfd42022-02-03 23:52:19 +000060 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
ramindanibab8ba92021-11-18 01:24:11 +000061
62 ASSERT_NO_FATAL_FAILURE(
63 mTestRenderEngine = std::unique_ptr<TestRenderEngine>(new TestRenderEngine(
64 ::android::renderengine::RenderEngineCreationArgs::Builder()
65 .setPixelFormat(static_cast<int>(common::PixelFormat::RGBA_8888))
66 .setImageCacheSize(TestRenderEngine::sMaxFrameBufferAcquireBuffers)
ramindanibab8ba92021-11-18 01:24:11 +000067 .setEnableProtectedContext(false)
68 .setPrecacheToneMapperShaderOnly(false)
69 .setContextPriority(::android::renderengine::RenderEngine::
70 ContextPriority::HIGH)
71 .build())));
72
Alec Mourif6c039a2023-10-06 23:02:17 +000073 mClientCompositionDisplaySettings.physicalDisplay =
74 Rect(getDisplayWidth(), getDisplayHeight());
75 mClientCompositionDisplaySettings.clip = mClientCompositionDisplaySettings.physicalDisplay;
ramindanibab8ba92021-11-18 01:24:11 +000076
Brian Lindahle887a252023-01-17 14:54:19 -070077 mTestRenderEngine->initGraphicBuffer(
78 static_cast<uint32_t>(getDisplayWidth()), static_cast<uint32_t>(getDisplayHeight()),
79 /*layerCount*/ 1U,
80 static_cast<uint64_t>(
81 static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
82 static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
83 static_cast<uint64_t>(common::BufferUsage::GPU_RENDER_TARGET)));
Alec Mourif6c039a2023-10-06 23:02:17 +000084 mTestRenderEngine->setDisplaySettings(mClientCompositionDisplaySettings);
ramindanibab8ba92021-11-18 01:24:11 +000085 }
86
87 void TearDown() override {
Leon Scroggins III94f4b202024-01-09 11:43:45 -050088 ASSERT_FALSE(mDisplays.empty());
ramindanidcecfd42022-02-03 23:52:19 +000089 ASSERT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::OFF).isOk());
Ady Abrahama00d2462023-12-26 14:21:20 -080090 ASSERT_TRUE(mComposerClient->tearDown(mWriter.get()));
ramindanidcecfd42022-02-03 23:52:19 +000091 mComposerClient.reset();
Ady Abraham3192f3d2021-12-03 16:08:56 -080092 const auto errors = mReader.takeErrors();
93 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcecfd42022-02-03 23:52:19 +000094 ASSERT_TRUE(mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty());
ramindanibab8ba92021-11-18 01:24:11 +000095 }
96
ramindanidcecfd42022-02-03 23:52:19 +000097 const VtsDisplay& getPrimaryDisplay() const { return mDisplays[0]; }
98
99 int64_t getPrimaryDisplayId() const { return getPrimaryDisplay().getDisplayId(); }
100
101 int64_t getInvalidDisplayId() const { return mComposerClient->getInvalidDisplayId(); }
102
103 int32_t getDisplayWidth() const { return getPrimaryDisplay().getDisplayWidth(); }
104
105 int32_t getDisplayHeight() const { return getPrimaryDisplay().getDisplayHeight(); }
106
ramindanid5751092022-04-22 22:30:20 +0000107 void assertServiceSpecificError(const ScopedAStatus& status, int32_t serviceSpecificError) {
108 ASSERT_EQ(status.getExceptionCode(), EX_SERVICE_SPECIFIC);
109 ASSERT_EQ(status.getServiceSpecificError(), serviceSpecificError);
110 }
111
Brian Lindahle887a252023-01-17 14:54:19 -0700112 std::pair<bool, ::android::sp<::android::GraphicBuffer>> allocateBuffer(uint32_t usage) {
113 const auto width = static_cast<uint32_t>(getDisplayWidth());
114 const auto height = static_cast<uint32_t>(getDisplayHeight());
115
116 const auto& graphicBuffer = ::android::sp<::android::GraphicBuffer>::make(
117 width, height, ::android::PIXEL_FORMAT_RGBA_8888,
118 /*layerCount*/ 1u, usage, "VtsHalGraphicsComposer3_ReadbackTest");
ramindani0a2bee42022-02-10 01:27:42 +0000119
120 if (graphicBuffer && ::android::OK == graphicBuffer->initCheck()) {
Brian Lindahle887a252023-01-17 14:54:19 -0700121 return {true, graphicBuffer};
ramindani0a2bee42022-02-10 01:27:42 +0000122 }
Brian Lindahle887a252023-01-17 14:54:19 -0700123 return {false, graphicBuffer};
ramindanibab8ba92021-11-18 01:24:11 +0000124 }
125
ramindanibab8ba92021-11-18 01:24:11 +0000126 void writeLayers(const std::vector<std::shared_ptr<TestLayer>>& layers) {
ramindanidcecfd42022-02-03 23:52:19 +0000127 for (const auto& layer : layers) {
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -0400128 layer->write(*mWriter);
ramindanibab8ba92021-11-18 01:24:11 +0000129 }
130 execute();
131 }
132
133 void execute() {
Huihong Luo651806f2023-04-21 18:48:48 +0000134 auto commands = mWriter->takePendingCommands();
Ady Abraham3192f3d2021-12-03 16:08:56 -0800135 if (commands.empty()) {
Ady Abraham3192f3d2021-12-03 16:08:56 -0800136 return;
ramindanibab8ba92021-11-18 01:24:11 +0000137 }
138
ramindanidcecfd42022-02-03 23:52:19 +0000139 auto [status, results] = mComposerClient->executeCommands(commands);
Ady Abraham3192f3d2021-12-03 16:08:56 -0800140 ASSERT_TRUE(status.isOk()) << "executeCommands failed " << status.getDescription();
ramindanibab8ba92021-11-18 01:24:11 +0000141
Ady Abraham46219f52021-12-20 09:44:31 -0800142 mReader.parse(std::move(results));
ramindanibab8ba92021-11-18 01:24:11 +0000143 }
144
ramindani44c952f2022-02-28 23:29:29 +0000145 bool getHasReadbackBuffer() {
ramindanidcecfd42022-02-03 23:52:19 +0000146 auto [status, readBackBufferAttributes] =
147 mComposerClient->getReadbackBufferAttributes(getPrimaryDisplayId());
148 if (status.isOk()) {
149 mPixelFormat = readBackBufferAttributes.format;
150 mDataspace = readBackBufferAttributes.dataspace;
ramindani44c952f2022-02-28 23:29:29 +0000151 return ReadbackHelper::readbackSupported(mPixelFormat, mDataspace);
ramindanidcecfd42022-02-03 23:52:19 +0000152 }
ramindanid5751092022-04-22 22:30:20 +0000153 EXPECT_NO_FATAL_FAILURE(
154 assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
ramindani44c952f2022-02-28 23:29:29 +0000155 return false;
ramindanib27f33b2021-12-03 19:36:10 +0000156 }
157
ramindanidcecfd42022-02-03 23:52:19 +0000158 std::shared_ptr<VtsComposerClient> mComposerClient;
159 std::vector<VtsDisplay> mDisplays;
160 // use the slot count usually set by SF
ramindanibab8ba92021-11-18 01:24:11 +0000161 std::vector<ColorMode> mTestColorModes;
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -0400162 std::unique_ptr<ComposerClientWriter> mWriter;
Ady Abraham91c9d1a2021-12-15 18:14:45 -0800163 ComposerClientReader mReader;
ramindanibab8ba92021-11-18 01:24:11 +0000164 std::unique_ptr<TestRenderEngine> mTestRenderEngine;
ramindanibab8ba92021-11-18 01:24:11 +0000165 common::PixelFormat mPixelFormat;
166 common::Dataspace mDataspace;
Alec Mourif6c039a2023-10-06 23:02:17 +0000167 ::android::renderengine::DisplaySettings mClientCompositionDisplaySettings;
ramindanibab8ba92021-11-18 01:24:11 +0000168
169 static constexpr uint32_t kClientTargetSlotCount = 64;
170
171 private:
ramindanibab8ba92021-11-18 01:24:11 +0000172 void setTestColorModes() {
173 mTestColorModes.clear();
ramindanidcecfd42022-02-03 23:52:19 +0000174 const auto& [status, modes] = mComposerClient->getColorModes(getPrimaryDisplayId());
175 ASSERT_TRUE(status.isOk());
ramindanibab8ba92021-11-18 01:24:11 +0000176
177 for (ColorMode mode : modes) {
178 if (std::find(ReadbackHelper::colorModes.begin(), ReadbackHelper::colorModes.end(),
179 mode) != ReadbackHelper::colorModes.end()) {
180 mTestColorModes.push_back(mode);
181 }
182 }
183 }
184};
185
186class GraphicsCompositionTest : public GraphicsCompositionTestBase,
187 public testing::WithParamInterface<std::string> {
188 public:
189 void SetUp() override { SetUpBase(GetParam()); }
190};
191
192TEST_P(GraphicsCompositionTest, SingleSolidColorLayer) {
193 for (ColorMode mode : mTestColorModes) {
ramindanidcecfd42022-02-03 23:52:19 +0000194 EXPECT_TRUE(mComposerClient
195 ->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
196 .isOk());
ramindanibab8ba92021-11-18 01:24:11 +0000197
ramindani44c952f2022-02-28 23:29:29 +0000198 bool isSupported;
199 ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
ramindanidcecfd42022-02-03 23:52:19 +0000200 if (!isSupported) {
ramindanibab8ba92021-11-18 01:24:11 +0000201 GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
202 return;
203 }
204
Ady Abrahama00d2462023-12-26 14:21:20 -0800205 auto layer =
206 std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
ramindanidcecfd42022-02-03 23:52:19 +0000207 common::Rect coloredSquare({0, 0, getDisplayWidth(), getDisplayHeight()});
ramindanibab8ba92021-11-18 01:24:11 +0000208 layer->setColor(BLUE);
209 layer->setDisplayFrame(coloredSquare);
210 layer->setZOrder(10);
211
212 std::vector<std::shared_ptr<TestLayer>> layers = {layer};
213
214 // expected color for each pixel
ramindanidcecfd42022-02-03 23:52:19 +0000215 std::vector<Color> expectedColors(
216 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
217 ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), coloredSquare, BLUE);
ramindanibab8ba92021-11-18 01:24:11 +0000218
ramindanidcecfd42022-02-03 23:52:19 +0000219 ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
Brian Lindahle887a252023-01-17 14:54:19 -0700220 getDisplayHeight(), mPixelFormat, mDataspace);
ramindanibab8ba92021-11-18 01:24:11 +0000221 ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
222
223 writeLayers(layers);
Ady Abraham3192f3d2021-12-03 16:08:56 -0800224 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanicdcfcaf2023-11-09 10:00:10 -0800225 mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
226 VtsComposerClient::kNoFrameIntervalNs);
ramindanibab8ba92021-11-18 01:24:11 +0000227 execute();
228 // if hwc cannot handle and asks for composition change,
229 // just succeed the test
ramindanidcecfd42022-02-03 23:52:19 +0000230 if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
ramindanibab8ba92021-11-18 01:24:11 +0000231 GTEST_SUCCEED();
232 return;
233 }
Ady Abraham3192f3d2021-12-03 16:08:56 -0800234 ASSERT_TRUE(mReader.takeErrors().empty());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -0400235 mWriter->presentDisplay(getPrimaryDisplayId());
ramindanibab8ba92021-11-18 01:24:11 +0000236 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -0800237 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanibab8ba92021-11-18 01:24:11 +0000238
239 ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
240 mTestRenderEngine->setRenderLayers(layers);
241 ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
242 ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
243 }
244}
245
246TEST_P(GraphicsCompositionTest, SetLayerBuffer) {
247 for (ColorMode mode : mTestColorModes) {
ramindanidcecfd42022-02-03 23:52:19 +0000248 EXPECT_TRUE(mComposerClient
249 ->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
250 .isOk());
ramindanibab8ba92021-11-18 01:24:11 +0000251
ramindani44c952f2022-02-28 23:29:29 +0000252 bool isSupported;
253 ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
ramindanidcecfd42022-02-03 23:52:19 +0000254 if (!isSupported) {
ramindanibab8ba92021-11-18 01:24:11 +0000255 GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
256 return;
257 }
258
ramindanidcecfd42022-02-03 23:52:19 +0000259 ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
Brian Lindahle887a252023-01-17 14:54:19 -0700260 getDisplayHeight(), mPixelFormat, mDataspace);
ramindanibab8ba92021-11-18 01:24:11 +0000261 ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
ramindanidcecfd42022-02-03 23:52:19 +0000262 std::vector<Color> expectedColors(
263 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
264 ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(),
265 {0, 0, getDisplayWidth(), getDisplayHeight() / 4}, RED);
266 ReadbackHelper::fillColorsArea(
267 expectedColors, getDisplayWidth(),
268 {0, getDisplayHeight() / 4, getDisplayWidth(), getDisplayHeight() / 2}, GREEN);
269 ReadbackHelper::fillColorsArea(
270 expectedColors, getDisplayWidth(),
271 {0, getDisplayHeight() / 2, getDisplayWidth(), getDisplayHeight()}, BLUE);
ramindanibab8ba92021-11-18 01:24:11 +0000272
273 auto layer = std::make_shared<TestBufferLayer>(
ramindani0a2bee42022-02-10 01:27:42 +0000274 mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
Ady Abrahama00d2462023-12-26 14:21:20 -0800275 getDisplayHeight(), common::PixelFormat::RGBA_8888, *mWriter);
ramindanidcecfd42022-02-03 23:52:19 +0000276 layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
ramindanibab8ba92021-11-18 01:24:11 +0000277 layer->setZOrder(10);
Alec Mourif6c039a2023-10-06 23:02:17 +0000278 layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
ramindanibab8ba92021-11-18 01:24:11 +0000279 ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
280
281 std::vector<std::shared_ptr<TestLayer>> layers = {layer};
282
283 writeLayers(layers);
Ady Abraham3192f3d2021-12-03 16:08:56 -0800284 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanicdcfcaf2023-11-09 10:00:10 -0800285 mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
286 VtsComposerClient::kNoFrameIntervalNs);
ramindanibab8ba92021-11-18 01:24:11 +0000287 execute();
288
ramindanidcecfd42022-02-03 23:52:19 +0000289 if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
ramindanibab8ba92021-11-18 01:24:11 +0000290 GTEST_SUCCEED();
291 return;
292 }
Ady Abraham3192f3d2021-12-03 16:08:56 -0800293 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanibab8ba92021-11-18 01:24:11 +0000294
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -0400295 mWriter->presentDisplay(getPrimaryDisplayId());
ramindanibab8ba92021-11-18 01:24:11 +0000296 execute();
297
Ady Abraham3192f3d2021-12-03 16:08:56 -0800298 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanibab8ba92021-11-18 01:24:11 +0000299
300 ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
301 mTestRenderEngine->setRenderLayers(layers);
302 ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
303 ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
304 }
305}
306
307TEST_P(GraphicsCompositionTest, SetLayerBufferNoEffect) {
308 for (ColorMode mode : mTestColorModes) {
ramindanidcecfd42022-02-03 23:52:19 +0000309 EXPECT_TRUE(mComposerClient
310 ->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
311 .isOk());
ramindanibab8ba92021-11-18 01:24:11 +0000312
ramindani44c952f2022-02-28 23:29:29 +0000313 bool isSupported;
314 ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
ramindanidcecfd42022-02-03 23:52:19 +0000315 if (!isSupported) {
ramindanibab8ba92021-11-18 01:24:11 +0000316 GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
317 return;
318 }
319
Ady Abrahama00d2462023-12-26 14:21:20 -0800320 auto layer =
321 std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
ramindanidcecfd42022-02-03 23:52:19 +0000322 common::Rect coloredSquare({0, 0, getDisplayWidth(), getDisplayHeight()});
ramindanibab8ba92021-11-18 01:24:11 +0000323 layer->setColor(BLUE);
324 layer->setDisplayFrame(coloredSquare);
325 layer->setZOrder(10);
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -0400326 layer->write(*mWriter);
ramindanibab8ba92021-11-18 01:24:11 +0000327
328 // This following buffer call should have no effect
Brian Lindahle887a252023-01-17 14:54:19 -0700329 const auto usage = static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
330 static_cast<uint32_t>(common::BufferUsage::CPU_READ_OFTEN);
331 const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(usage);
332 ASSERT_TRUE(graphicBufferStatus);
ramindani0a2bee42022-02-10 01:27:42 +0000333 const auto& buffer = graphicBuffer->handle;
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -0400334 mWriter->setLayerBuffer(getPrimaryDisplayId(), layer->getLayer(), /*slot*/ 0, buffer,
335 /*acquireFence*/ -1);
ramindanibab8ba92021-11-18 01:24:11 +0000336
337 // expected color for each pixel
ramindanidcecfd42022-02-03 23:52:19 +0000338 std::vector<Color> expectedColors(
339 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
340 ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), coloredSquare, BLUE);
ramindanibab8ba92021-11-18 01:24:11 +0000341
ramindanidcecfd42022-02-03 23:52:19 +0000342 ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
Brian Lindahle887a252023-01-17 14:54:19 -0700343 getDisplayHeight(), mPixelFormat, mDataspace);
ramindanibab8ba92021-11-18 01:24:11 +0000344 ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
345
ramindanicdcfcaf2023-11-09 10:00:10 -0800346 mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
347 VtsComposerClient::kNoFrameIntervalNs);
ramindanibab8ba92021-11-18 01:24:11 +0000348 execute();
349
ramindanidcecfd42022-02-03 23:52:19 +0000350 if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
ramindanibab8ba92021-11-18 01:24:11 +0000351 GTEST_SUCCEED();
352 return;
353 }
Ady Abraham3192f3d2021-12-03 16:08:56 -0800354 ASSERT_TRUE(mReader.takeErrors().empty());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -0400355 mWriter->presentDisplay(getPrimaryDisplayId());
ramindanibab8ba92021-11-18 01:24:11 +0000356 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -0800357 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanibab8ba92021-11-18 01:24:11 +0000358
359 ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
360 }
361}
362
ramindanib27f33b2021-12-03 19:36:10 +0000363TEST_P(GraphicsCompositionTest, SetReadbackBuffer) {
ramindani44c952f2022-02-28 23:29:29 +0000364 bool isSupported;
365 ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
ramindanidcecfd42022-02-03 23:52:19 +0000366 if (!isSupported) {
ramindanib27f33b2021-12-03 19:36:10 +0000367 GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
368 return;
369 }
370
ramindanidcecfd42022-02-03 23:52:19 +0000371 ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
Brian Lindahle887a252023-01-17 14:54:19 -0700372 getDisplayHeight(), mPixelFormat, mDataspace);
ramindanib27f33b2021-12-03 19:36:10 +0000373
374 ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
375}
376
ramindanidcecfd42022-02-03 23:52:19 +0000377TEST_P(GraphicsCompositionTest, SetReadbackBuffer_BadDisplay) {
ramindani44c952f2022-02-28 23:29:29 +0000378 bool isSupported;
379 ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
ramindanidcecfd42022-02-03 23:52:19 +0000380 if (!isSupported) {
ramindanib27f33b2021-12-03 19:36:10 +0000381 GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
382 return;
383 }
384
Brian Lindahle887a252023-01-17 14:54:19 -0700385 const auto usage = static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
386 static_cast<uint32_t>(common::BufferUsage::CPU_READ_OFTEN);
387 const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(usage);
388 ASSERT_TRUE(graphicBufferStatus);
ramindani0a2bee42022-02-10 01:27:42 +0000389 const auto& bufferHandle = graphicBuffer->handle;
ramindanib27f33b2021-12-03 19:36:10 +0000390 ::ndk::ScopedFileDescriptor fence = ::ndk::ScopedFileDescriptor(-1);
391
ramindanidcecfd42022-02-03 23:52:19 +0000392 const auto status =
393 mComposerClient->setReadbackBuffer(getInvalidDisplayId(), bufferHandle, fence);
ramindanib27f33b2021-12-03 19:36:10 +0000394
ramindanidcecfd42022-02-03 23:52:19 +0000395 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000396 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_DISPLAY));
ramindanib27f33b2021-12-03 19:36:10 +0000397}
398
ramindanidcecfd42022-02-03 23:52:19 +0000399TEST_P(GraphicsCompositionTest, SetReadbackBuffer_BadParameter) {
ramindani44c952f2022-02-28 23:29:29 +0000400 bool isSupported;
401 ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
ramindanidcecfd42022-02-03 23:52:19 +0000402 if (!isSupported) {
ramindanib27f33b2021-12-03 19:36:10 +0000403 GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
404 return;
405 }
406
ramindanidcecfd42022-02-03 23:52:19 +0000407 const native_handle_t bufferHandle{};
ramindanib27f33b2021-12-03 19:36:10 +0000408 ndk::ScopedFileDescriptor releaseFence = ndk::ScopedFileDescriptor(-1);
ramindanidcecfd42022-02-03 23:52:19 +0000409 const auto status =
410 mComposerClient->setReadbackBuffer(getPrimaryDisplayId(), &bufferHandle, releaseFence);
ramindanib27f33b2021-12-03 19:36:10 +0000411
ramindanidcecfd42022-02-03 23:52:19 +0000412 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000413 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_BAD_PARAMETER));
ramindanib27f33b2021-12-03 19:36:10 +0000414}
415
416TEST_P(GraphicsCompositionTest, GetReadbackBufferFenceInactive) {
ramindani44c952f2022-02-28 23:29:29 +0000417 bool isSupported;
418 ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
ramindanidcecfd42022-02-03 23:52:19 +0000419 if (!isSupported) {
ramindanib27f33b2021-12-03 19:36:10 +0000420 GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
421 return;
422 }
423
ramindanidcecfd42022-02-03 23:52:19 +0000424 const auto& [status, releaseFence] =
425 mComposerClient->getReadbackBufferFence(getPrimaryDisplayId());
ramindanib27f33b2021-12-03 19:36:10 +0000426
ramindanidcecfd42022-02-03 23:52:19 +0000427 EXPECT_FALSE(status.isOk());
ramindanid5751092022-04-22 22:30:20 +0000428 EXPECT_NO_FATAL_FAILURE(assertServiceSpecificError(status, IComposerClient::EX_UNSUPPORTED));
Alec Mouri62ae37b2022-01-20 17:16:38 -0800429 EXPECT_EQ(-1, releaseFence.get());
ramindanib27f33b2021-12-03 19:36:10 +0000430}
431
ramindanibab8ba92021-11-18 01:24:11 +0000432TEST_P(GraphicsCompositionTest, ClientComposition) {
ramindanidcecfd42022-02-03 23:52:19 +0000433 EXPECT_TRUE(
434 mComposerClient->setClientTargetSlotCount(getPrimaryDisplayId(), kClientTargetSlotCount)
435 .isOk());
ramindanibab8ba92021-11-18 01:24:11 +0000436
437 for (ColorMode mode : mTestColorModes) {
ramindanidcecfd42022-02-03 23:52:19 +0000438 EXPECT_TRUE(mComposerClient
439 ->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
ramindanibab8ba92021-11-18 01:24:11 +0000440 .isOk());
441
ramindani44c952f2022-02-28 23:29:29 +0000442 bool isSupported;
443 ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
ramindanidcecfd42022-02-03 23:52:19 +0000444 if (!isSupported) {
ramindanibab8ba92021-11-18 01:24:11 +0000445 GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
446 return;
447 }
448
ramindanidcecfd42022-02-03 23:52:19 +0000449 std::vector<Color> expectedColors(
450 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
451 ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(),
452 {0, 0, getDisplayWidth(), getDisplayHeight() / 4}, RED);
453 ReadbackHelper::fillColorsArea(
454 expectedColors, getDisplayWidth(),
455 {0, getDisplayHeight() / 4, getDisplayWidth(), getDisplayHeight() / 2}, GREEN);
456 ReadbackHelper::fillColorsArea(
457 expectedColors, getDisplayWidth(),
458 {0, getDisplayHeight() / 2, getDisplayWidth(), getDisplayHeight()}, BLUE);
ramindanibab8ba92021-11-18 01:24:11 +0000459
Ady Abrahama00d2462023-12-26 14:21:20 -0800460 auto layer = std::make_shared<TestBufferLayer>(
461 mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
462 getDisplayHeight(), PixelFormat::RGBA_FP16, *mWriter);
ramindanidcecfd42022-02-03 23:52:19 +0000463 layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
ramindanibab8ba92021-11-18 01:24:11 +0000464 layer->setZOrder(10);
Alec Mourif6c039a2023-10-06 23:02:17 +0000465 layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
ramindanibab8ba92021-11-18 01:24:11 +0000466
467 std::vector<std::shared_ptr<TestLayer>> layers = {layer};
468
ramindanidcecfd42022-02-03 23:52:19 +0000469 ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
Brian Lindahle887a252023-01-17 14:54:19 -0700470 getDisplayHeight(), mPixelFormat, mDataspace);
ramindanibab8ba92021-11-18 01:24:11 +0000471 ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
472 writeLayers(layers);
Ady Abraham3192f3d2021-12-03 16:08:56 -0800473 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanicdcfcaf2023-11-09 10:00:10 -0800474 mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
475 VtsComposerClient::kNoFrameIntervalNs);
ramindanibab8ba92021-11-18 01:24:11 +0000476 execute();
477
ramindanidcecfd42022-02-03 23:52:19 +0000478 auto changedCompositionTypes = mReader.takeChangedCompositionTypes(getPrimaryDisplayId());
Ady Abraham46219f52021-12-20 09:44:31 -0800479 if (!changedCompositionTypes.empty()) {
Ady Abraham3192f3d2021-12-03 16:08:56 -0800480 ASSERT_EQ(1, changedCompositionTypes.size());
Ady Abraham46219f52021-12-20 09:44:31 -0800481 ASSERT_EQ(Composition::CLIENT, changedCompositionTypes[0].composition);
ramindanibab8ba92021-11-18 01:24:11 +0000482
483 PixelFormat clientFormat = PixelFormat::RGBA_8888;
Brian Lindahle887a252023-01-17 14:54:19 -0700484 auto clientUsage = static_cast<uint32_t>(
485 static_cast<uint32_t>(common::BufferUsage::CPU_READ_OFTEN) |
486 static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
487 static_cast<uint32_t>(common::BufferUsage::COMPOSER_CLIENT_TARGET));
ramindanibab8ba92021-11-18 01:24:11 +0000488 Dataspace clientDataspace = ReadbackHelper::getDataspaceForColorMode(mode);
ramindanidcecfd42022-02-03 23:52:19 +0000489 common::Rect damage{0, 0, getDisplayWidth(), getDisplayHeight()};
ramindanibab8ba92021-11-18 01:24:11 +0000490
491 // create client target buffer
Brian Lindahle887a252023-01-17 14:54:19 -0700492 const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(clientUsage);
493 ASSERT_TRUE(graphicBufferStatus);
ramindani0a2bee42022-02-10 01:27:42 +0000494 const auto& buffer = graphicBuffer->handle;
ramindanibab8ba92021-11-18 01:24:11 +0000495 void* clientBufData;
ramindani0a2bee42022-02-10 01:27:42 +0000496 const auto stride = static_cast<uint32_t>(graphicBuffer->stride);
497 graphicBuffer->lock(clientUsage, layer->getAccessRegion(), &clientBufData);
ramindanibab8ba92021-11-18 01:24:11 +0000498
499 ASSERT_NO_FATAL_FAILURE(
ramindani0a2bee42022-02-10 01:27:42 +0000500 ReadbackHelper::fillBuffer(layer->getWidth(), layer->getHeight(), stride,
ramindanibab8ba92021-11-18 01:24:11 +0000501 clientBufData, clientFormat, expectedColors));
ramindanib1144212022-02-10 01:51:24 +0000502 int32_t clientFence;
503 const auto unlockStatus = graphicBuffer->unlockAsync(&clientFence);
504 ASSERT_EQ(::android::OK, unlockStatus);
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -0400505 mWriter->setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, buffer, clientFence,
Alec Mouri8062f1f2023-09-06 02:14:47 +0000506 clientDataspace, std::vector<common::Rect>(1, damage), 1.f);
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -0400507 layer->setToClientComposition(*mWriter);
ramindanicdcfcaf2023-11-09 10:00:10 -0800508 mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
509 VtsComposerClient::kNoFrameIntervalNs);
ramindanibab8ba92021-11-18 01:24:11 +0000510 execute();
ramindanidcecfd42022-02-03 23:52:19 +0000511 changedCompositionTypes = mReader.takeChangedCompositionTypes(getPrimaryDisplayId());
Ady Abraham46219f52021-12-20 09:44:31 -0800512 ASSERT_TRUE(changedCompositionTypes.empty());
ramindanibab8ba92021-11-18 01:24:11 +0000513 }
Ady Abraham3192f3d2021-12-03 16:08:56 -0800514 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanibab8ba92021-11-18 01:24:11 +0000515
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -0400516 mWriter->presentDisplay(getPrimaryDisplayId());
ramindanibab8ba92021-11-18 01:24:11 +0000517 execute();
518
Ady Abraham3192f3d2021-12-03 16:08:56 -0800519 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanibab8ba92021-11-18 01:24:11 +0000520
521 ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
522 }
523}
524
Sally Qi0ca29272024-02-23 11:07:08 -0800525TEST_P(GraphicsCompositionTest, MixedColorSpaces) {
526 ASSERT_TRUE(
527 mComposerClient->setClientTargetSlotCount(getPrimaryDisplayId(), kClientTargetSlotCount)
528 .isOk());
529 const auto& [status, properties] = mComposerClient->getOverlaySupport();
530 if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
531 status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
532 GTEST_SUCCEED() << "getOverlaySupport is not supported";
533 return;
534 }
535
536 if (properties.supportMixedColorSpaces == false) {
537 GTEST_SUCCEED() << "supportMixedColorSpaces is not supported";
538 return;
539 }
540
541 for (ColorMode mode : mTestColorModes) {
542 EXPECT_TRUE(mComposerClient
543 ->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
544 .isOk());
545
546 bool isSupported;
547 ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
548 if (!isSupported) {
549 GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
550 return;
551 }
552
553 // sRGB layer
554 auto srgbLayer = std::make_shared<TestBufferLayer>(
555 mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
556 getDisplayHeight() / 2, PixelFormat::RGBA_8888, *mWriter);
557 std::vector<Color> sRgbDeviceColors(srgbLayer->getWidth() * srgbLayer->getHeight());
558 ReadbackHelper::fillColorsArea(sRgbDeviceColors, getDisplayWidth(),
559 {0, 0, static_cast<int32_t>(srgbLayer->getWidth()),
560 static_cast<int32_t>(srgbLayer->getHeight())},
561 GREEN);
562 srgbLayer->setDisplayFrame({0, 0, static_cast<int32_t>(srgbLayer->getWidth()),
563 static_cast<int32_t>(srgbLayer->getHeight())});
564 srgbLayer->setZOrder(10);
565 srgbLayer->setDataspace(Dataspace::SRGB);
566 ASSERT_NO_FATAL_FAILURE(srgbLayer->setBuffer(sRgbDeviceColors));
567
568 // display P3 layer
569 auto displayP3Layer = std::make_shared<TestBufferLayer>(
570 mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
571 getDisplayHeight() / 2, PixelFormat::RGBA_8888, *mWriter);
572 std::vector<Color> displayP3DeviceColors(
573 static_cast<size_t>(displayP3Layer->getWidth() * displayP3Layer->getHeight()));
574 ReadbackHelper::fillColorsArea(displayP3DeviceColors, getDisplayWidth(),
575 {0, 0, static_cast<int32_t>(displayP3Layer->getWidth()),
576 static_cast<int32_t>(displayP3Layer->getHeight())},
577 RED);
578 displayP3Layer->setDisplayFrame(
579 {0, getDisplayHeight() / 2, getDisplayWidth(), getDisplayHeight()});
580 displayP3Layer->setZOrder(10);
581 displayP3Layer->setDataspace(Dataspace::DISPLAY_P3);
582 ASSERT_NO_FATAL_FAILURE(displayP3Layer->setBuffer(displayP3DeviceColors));
583
584 writeLayers({srgbLayer, displayP3Layer});
585
586 mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
587 VtsComposerClient::kNoFrameIntervalNs);
588 execute();
589
590 auto changedCompositionTypes = mReader.takeChangedCompositionTypes(getPrimaryDisplayId());
591 ASSERT_TRUE(changedCompositionTypes.empty());
592
593 mWriter->presentDisplay(getPrimaryDisplayId());
594 execute();
595
596 changedCompositionTypes = mReader.takeChangedCompositionTypes(getPrimaryDisplayId());
597 ASSERT_TRUE(changedCompositionTypes.empty());
598 ASSERT_TRUE(mReader.takeErrors().empty());
599 }
600}
601
ramindanibab8ba92021-11-18 01:24:11 +0000602TEST_P(GraphicsCompositionTest, DeviceAndClientComposition) {
ramindanidcecfd42022-02-03 23:52:19 +0000603 ASSERT_TRUE(
604 mComposerClient->setClientTargetSlotCount(getPrimaryDisplayId(), kClientTargetSlotCount)
605 .isOk());
ramindanibab8ba92021-11-18 01:24:11 +0000606
607 for (ColorMode mode : mTestColorModes) {
ramindanidcecfd42022-02-03 23:52:19 +0000608 EXPECT_TRUE(mComposerClient
609 ->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
610 .isOk());
ramindanibab8ba92021-11-18 01:24:11 +0000611
ramindani44c952f2022-02-28 23:29:29 +0000612 bool isSupported;
613 ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
ramindanidcecfd42022-02-03 23:52:19 +0000614 if (!isSupported) {
ramindanibab8ba92021-11-18 01:24:11 +0000615 GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
616 return;
617 }
618
ramindanidcecfd42022-02-03 23:52:19 +0000619 std::vector<Color> expectedColors(
620 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
621 ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(),
622 {0, 0, getDisplayWidth(), getDisplayHeight() / 2}, GREEN);
623 ReadbackHelper::fillColorsArea(
624 expectedColors, getDisplayWidth(),
625 {0, getDisplayHeight() / 2, getDisplayWidth(), getDisplayHeight()}, RED);
ramindanibab8ba92021-11-18 01:24:11 +0000626
ramindanidcecfd42022-02-03 23:52:19 +0000627 ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
Brian Lindahle887a252023-01-17 14:54:19 -0700628 getDisplayHeight(), mPixelFormat, mDataspace);
ramindanibab8ba92021-11-18 01:24:11 +0000629 ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
630
631 auto deviceLayer = std::make_shared<TestBufferLayer>(
ramindani0a2bee42022-02-10 01:27:42 +0000632 mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
Ady Abrahama00d2462023-12-26 14:21:20 -0800633 getDisplayHeight() / 2, PixelFormat::RGBA_8888, *mWriter);
ramindanibab8ba92021-11-18 01:24:11 +0000634 std::vector<Color> deviceColors(deviceLayer->getWidth() * deviceLayer->getHeight());
635 ReadbackHelper::fillColorsArea(deviceColors, static_cast<int32_t>(deviceLayer->getWidth()),
636 {0, 0, static_cast<int32_t>(deviceLayer->getWidth()),
637 static_cast<int32_t>(deviceLayer->getHeight())},
638 GREEN);
639 deviceLayer->setDisplayFrame({0, 0, static_cast<int32_t>(deviceLayer->getWidth()),
640 static_cast<int32_t>(deviceLayer->getHeight())});
641 deviceLayer->setZOrder(10);
Alec Mourif6c039a2023-10-06 23:02:17 +0000642 deviceLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
ramindanibab8ba92021-11-18 01:24:11 +0000643 ASSERT_NO_FATAL_FAILURE(deviceLayer->setBuffer(deviceColors));
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -0400644 deviceLayer->write(*mWriter);
ramindanibab8ba92021-11-18 01:24:11 +0000645
646 PixelFormat clientFormat = PixelFormat::RGBA_8888;
Brian Lindahle887a252023-01-17 14:54:19 -0700647 auto clientUsage = static_cast<uint32_t>(
648 static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
649 static_cast<uint32_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
650 static_cast<uint32_t>(common::BufferUsage::COMPOSER_CLIENT_TARGET));
ramindanibab8ba92021-11-18 01:24:11 +0000651 Dataspace clientDataspace = ReadbackHelper::getDataspaceForColorMode(mode);
ramindanidcecfd42022-02-03 23:52:19 +0000652 int32_t clientWidth = getDisplayWidth();
653 int32_t clientHeight = getDisplayHeight() / 2;
ramindanibab8ba92021-11-18 01:24:11 +0000654
655 auto clientLayer = std::make_shared<TestBufferLayer>(
ramindani0a2bee42022-02-10 01:27:42 +0000656 mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), clientWidth,
Ady Abrahama00d2462023-12-26 14:21:20 -0800657 clientHeight, PixelFormat::RGBA_FP16, *mWriter, Composition::DEVICE);
ramindanidcecfd42022-02-03 23:52:19 +0000658 common::Rect clientFrame = {0, getDisplayHeight() / 2, getDisplayWidth(),
659 getDisplayHeight()};
ramindanibab8ba92021-11-18 01:24:11 +0000660 clientLayer->setDisplayFrame(clientFrame);
661 clientLayer->setZOrder(0);
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -0400662 clientLayer->write(*mWriter);
ramindanicdcfcaf2023-11-09 10:00:10 -0800663 mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
664 VtsComposerClient::kNoFrameIntervalNs);
ramindanibab8ba92021-11-18 01:24:11 +0000665 execute();
666
ramindanidcecfd42022-02-03 23:52:19 +0000667 auto changedCompositionTypes = mReader.takeChangedCompositionTypes(getPrimaryDisplayId());
Ady Abraham3192f3d2021-12-03 16:08:56 -0800668 if (changedCompositionTypes.size() != 1) {
ramindanibab8ba92021-11-18 01:24:11 +0000669 continue;
670 }
671 // create client target buffer
Ady Abraham46219f52021-12-20 09:44:31 -0800672 ASSERT_EQ(Composition::CLIENT, changedCompositionTypes[0].composition);
Brian Lindahle887a252023-01-17 14:54:19 -0700673 const auto& [graphicBufferStatus, graphicBuffer] = allocateBuffer(clientUsage);
674 ASSERT_TRUE(graphicBufferStatus);
ramindani0a2bee42022-02-10 01:27:42 +0000675 const auto& buffer = graphicBuffer->handle;
ramindanibab8ba92021-11-18 01:24:11 +0000676
677 void* clientBufData;
ramindani0a2bee42022-02-10 01:27:42 +0000678 graphicBuffer->lock(clientUsage, {0, 0, getDisplayWidth(), getDisplayHeight()},
679 &clientBufData);
ramindanibab8ba92021-11-18 01:24:11 +0000680
ramindanidcecfd42022-02-03 23:52:19 +0000681 std::vector<Color> clientColors(
682 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
683 ReadbackHelper::fillColorsArea(clientColors, getDisplayWidth(), clientFrame, RED);
ramindanibab8ba92021-11-18 01:24:11 +0000684 ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(
ramindanidcecfd42022-02-03 23:52:19 +0000685 static_cast<uint32_t>(getDisplayWidth()), static_cast<uint32_t>(getDisplayHeight()),
ramindani0a2bee42022-02-10 01:27:42 +0000686 graphicBuffer->getStride(), clientBufData, clientFormat, clientColors));
ramindanib1144212022-02-10 01:51:24 +0000687 int32_t clientFence;
688 const auto unlockStatus = graphicBuffer->unlockAsync(&clientFence);
689 ASSERT_EQ(::android::OK, unlockStatus);
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -0400690 mWriter->setClientTarget(getPrimaryDisplayId(), /*slot*/ 0, buffer, clientFence,
Alec Mouri8062f1f2023-09-06 02:14:47 +0000691 clientDataspace, std::vector<common::Rect>(1, clientFrame), 1.f);
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -0400692 clientLayer->setToClientComposition(*mWriter);
ramindanicdcfcaf2023-11-09 10:00:10 -0800693 mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
694 VtsComposerClient::kNoFrameIntervalNs);
ramindanibab8ba92021-11-18 01:24:11 +0000695 execute();
ramindanidcecfd42022-02-03 23:52:19 +0000696 changedCompositionTypes = mReader.takeChangedCompositionTypes(getPrimaryDisplayId());
Ady Abraham46219f52021-12-20 09:44:31 -0800697 ASSERT_TRUE(changedCompositionTypes.empty());
Ady Abraham3192f3d2021-12-03 16:08:56 -0800698 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanibab8ba92021-11-18 01:24:11 +0000699
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -0400700 mWriter->presentDisplay(getPrimaryDisplayId());
ramindanibab8ba92021-11-18 01:24:11 +0000701 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -0800702 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanibab8ba92021-11-18 01:24:11 +0000703 ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
704 }
705}
706
707TEST_P(GraphicsCompositionTest, SetLayerDamage) {
708 for (ColorMode mode : mTestColorModes) {
ramindanidcecfd42022-02-03 23:52:19 +0000709 EXPECT_TRUE(mComposerClient
710 ->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
711 .isOk());
ramindanibab8ba92021-11-18 01:24:11 +0000712
ramindani44c952f2022-02-28 23:29:29 +0000713 bool isSupported;
714 ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
ramindanidcecfd42022-02-03 23:52:19 +0000715 if (!isSupported) {
ramindanibab8ba92021-11-18 01:24:11 +0000716 GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
717 return;
718 }
719
ramindanidcecfd42022-02-03 23:52:19 +0000720 common::Rect redRect = {0, 0, getDisplayWidth() / 4, getDisplayHeight() / 4};
ramindanibab8ba92021-11-18 01:24:11 +0000721
ramindanidcecfd42022-02-03 23:52:19 +0000722 std::vector<Color> expectedColors(
723 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
724 ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), redRect, RED);
ramindanibab8ba92021-11-18 01:24:11 +0000725
Ady Abrahama00d2462023-12-26 14:21:20 -0800726 auto layer = std::make_shared<TestBufferLayer>(
727 mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
728 getDisplayHeight(), PixelFormat::RGBA_8888, *mWriter);
ramindanidcecfd42022-02-03 23:52:19 +0000729 layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
ramindanibab8ba92021-11-18 01:24:11 +0000730 layer->setZOrder(10);
Alec Mourif6c039a2023-10-06 23:02:17 +0000731 layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
ramindanibab8ba92021-11-18 01:24:11 +0000732 ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
733
734 std::vector<std::shared_ptr<TestLayer>> layers = {layer};
735
ramindanidcecfd42022-02-03 23:52:19 +0000736 ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
Brian Lindahle887a252023-01-17 14:54:19 -0700737 getDisplayHeight(), mPixelFormat, mDataspace);
ramindanibab8ba92021-11-18 01:24:11 +0000738 ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
739
740 writeLayers(layers);
Ady Abraham3192f3d2021-12-03 16:08:56 -0800741 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanicdcfcaf2023-11-09 10:00:10 -0800742 mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
743 VtsComposerClient::kNoFrameIntervalNs);
ramindanibab8ba92021-11-18 01:24:11 +0000744 execute();
ramindanidcecfd42022-02-03 23:52:19 +0000745 if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
ramindanibab8ba92021-11-18 01:24:11 +0000746 GTEST_SUCCEED();
747 return;
748 }
Ady Abraham3192f3d2021-12-03 16:08:56 -0800749 ASSERT_TRUE(mReader.takeErrors().empty());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -0400750 mWriter->presentDisplay(getPrimaryDisplayId());
ramindanibab8ba92021-11-18 01:24:11 +0000751 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -0800752 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanibab8ba92021-11-18 01:24:11 +0000753
754 ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
755
756 // update surface damage and recheck
ramindanidcecfd42022-02-03 23:52:19 +0000757 redRect = {getDisplayWidth() / 4, getDisplayHeight() / 4, getDisplayWidth() / 2,
758 getDisplayHeight() / 2};
759 ReadbackHelper::clearColors(expectedColors, getDisplayWidth(), getDisplayHeight(),
760 getDisplayWidth());
761 ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), redRect, RED);
ramindanibab8ba92021-11-18 01:24:11 +0000762
763 ASSERT_NO_FATAL_FAILURE(layer->fillBuffer(expectedColors));
764 layer->setSurfaceDamage(
ramindanidcecfd42022-02-03 23:52:19 +0000765 std::vector<common::Rect>(1, {0, 0, getDisplayWidth() / 2, getDisplayWidth() / 2}));
ramindanibab8ba92021-11-18 01:24:11 +0000766
767 ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
768
769 writeLayers(layers);
Ady Abraham3192f3d2021-12-03 16:08:56 -0800770 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanicdcfcaf2023-11-09 10:00:10 -0800771 mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
772 VtsComposerClient::kNoFrameIntervalNs);
ramindanibab8ba92021-11-18 01:24:11 +0000773 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -0800774 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanidcecfd42022-02-03 23:52:19 +0000775 ASSERT_TRUE(mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -0400776 mWriter->presentDisplay(getPrimaryDisplayId());
ramindanibab8ba92021-11-18 01:24:11 +0000777 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -0800778 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanibab8ba92021-11-18 01:24:11 +0000779
780 ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
781 }
782}
783
784TEST_P(GraphicsCompositionTest, SetLayerPlaneAlpha) {
785 for (ColorMode mode : mTestColorModes) {
ramindanidcecfd42022-02-03 23:52:19 +0000786 EXPECT_TRUE(mComposerClient
787 ->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
788 .isOk());
ramindanibab8ba92021-11-18 01:24:11 +0000789
ramindani44c952f2022-02-28 23:29:29 +0000790 bool isSupported;
791 ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
ramindanidcecfd42022-02-03 23:52:19 +0000792 if (!isSupported) {
ramindanibab8ba92021-11-18 01:24:11 +0000793 GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
794 return;
795 }
796
Ady Abrahama00d2462023-12-26 14:21:20 -0800797 auto layer =
798 std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
ramindanibab8ba92021-11-18 01:24:11 +0000799 layer->setColor(RED);
ramindanidcecfd42022-02-03 23:52:19 +0000800 layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
ramindanibab8ba92021-11-18 01:24:11 +0000801 layer->setZOrder(10);
802 layer->setAlpha(0);
803 layer->setBlendMode(BlendMode::PREMULTIPLIED);
804
805 std::vector<std::shared_ptr<TestLayer>> layers = {layer};
806
ramindanidcecfd42022-02-03 23:52:19 +0000807 ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
Brian Lindahle887a252023-01-17 14:54:19 -0700808 getDisplayHeight(), mPixelFormat, mDataspace);
ramindanibab8ba92021-11-18 01:24:11 +0000809
810 ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
811
812 writeLayers(layers);
Ady Abraham3192f3d2021-12-03 16:08:56 -0800813 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanicdcfcaf2023-11-09 10:00:10 -0800814 mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
815 VtsComposerClient::kNoFrameIntervalNs);
ramindanibab8ba92021-11-18 01:24:11 +0000816 execute();
ramindanidcecfd42022-02-03 23:52:19 +0000817 if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
ramindanibab8ba92021-11-18 01:24:11 +0000818 GTEST_SUCCEED();
819 return;
820 }
Ady Abraham3192f3d2021-12-03 16:08:56 -0800821 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanibab8ba92021-11-18 01:24:11 +0000822
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -0400823 mWriter->presentDisplay(getPrimaryDisplayId());
ramindanibab8ba92021-11-18 01:24:11 +0000824 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -0800825 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanibab8ba92021-11-18 01:24:11 +0000826
ramindanidcecfd42022-02-03 23:52:19 +0000827 std::vector<Color> expectedColors(
828 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
ramindanibab8ba92021-11-18 01:24:11 +0000829
830 ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
831 mTestRenderEngine->setRenderLayers(layers);
832 ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
833 ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
834 }
835}
836
837TEST_P(GraphicsCompositionTest, SetLayerSourceCrop) {
838 for (ColorMode mode : mTestColorModes) {
ramindanidcecfd42022-02-03 23:52:19 +0000839 EXPECT_TRUE(mComposerClient
840 ->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
841 .isOk());
ramindanibab8ba92021-11-18 01:24:11 +0000842
ramindani44c952f2022-02-28 23:29:29 +0000843 bool isSupported;
844 ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
ramindanidcecfd42022-02-03 23:52:19 +0000845 if (!isSupported) {
ramindanibab8ba92021-11-18 01:24:11 +0000846 GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
847 return;
848 }
849
ramindanidcecfd42022-02-03 23:52:19 +0000850 std::vector<Color> expectedColors(
851 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
852 ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(),
853 {0, 0, getDisplayWidth(), getDisplayHeight() / 4}, RED);
854 ReadbackHelper::fillColorsArea(
855 expectedColors, getDisplayWidth(),
856 {0, getDisplayHeight() / 2, getDisplayWidth(), getDisplayHeight()}, BLUE);
ramindanibab8ba92021-11-18 01:24:11 +0000857
Ady Abrahama00d2462023-12-26 14:21:20 -0800858 auto layer = std::make_shared<TestBufferLayer>(
859 mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
860 getDisplayHeight(), PixelFormat::RGBA_8888, *mWriter);
ramindanidcecfd42022-02-03 23:52:19 +0000861 layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
ramindanibab8ba92021-11-18 01:24:11 +0000862 layer->setZOrder(10);
Alec Mourif6c039a2023-10-06 23:02:17 +0000863 layer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
ramindanidcecfd42022-02-03 23:52:19 +0000864 layer->setSourceCrop({0, static_cast<float>(getDisplayHeight() / 2),
865 static_cast<float>(getDisplayWidth()),
866 static_cast<float>(getDisplayHeight())});
ramindanibab8ba92021-11-18 01:24:11 +0000867 ASSERT_NO_FATAL_FAILURE(layer->setBuffer(expectedColors));
868
869 std::vector<std::shared_ptr<TestLayer>> layers = {layer};
870
871 // update expected colors to match crop
ramindanidcecfd42022-02-03 23:52:19 +0000872 ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(),
873 {0, 0, getDisplayWidth(), getDisplayHeight()}, BLUE);
874 ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
Brian Lindahle887a252023-01-17 14:54:19 -0700875 getDisplayHeight(), mPixelFormat, mDataspace);
ramindanibab8ba92021-11-18 01:24:11 +0000876 ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
877 writeLayers(layers);
Ady Abraham3192f3d2021-12-03 16:08:56 -0800878 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanicdcfcaf2023-11-09 10:00:10 -0800879 mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
880 VtsComposerClient::kNoFrameIntervalNs);
ramindanibab8ba92021-11-18 01:24:11 +0000881 execute();
ramindanidcecfd42022-02-03 23:52:19 +0000882 if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
ramindanibab8ba92021-11-18 01:24:11 +0000883 GTEST_SUCCEED();
884 return;
885 }
Ady Abraham3192f3d2021-12-03 16:08:56 -0800886 ASSERT_TRUE(mReader.takeErrors().empty());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -0400887 mWriter->presentDisplay(getPrimaryDisplayId());
ramindanibab8ba92021-11-18 01:24:11 +0000888 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -0800889 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanibab8ba92021-11-18 01:24:11 +0000890 ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
891 mTestRenderEngine->setRenderLayers(layers);
892 ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
893 ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
894 }
895}
896
897TEST_P(GraphicsCompositionTest, SetLayerZOrder) {
898 for (ColorMode mode : mTestColorModes) {
ramindanidcecfd42022-02-03 23:52:19 +0000899 EXPECT_TRUE(mComposerClient
900 ->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
901 .isOk());
ramindanibab8ba92021-11-18 01:24:11 +0000902
ramindani44c952f2022-02-28 23:29:29 +0000903 bool isSupported;
904 ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
ramindanidcecfd42022-02-03 23:52:19 +0000905 if (!isSupported) {
ramindanibab8ba92021-11-18 01:24:11 +0000906 GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
907 return;
908 }
909
ramindanidcecfd42022-02-03 23:52:19 +0000910 common::Rect redRect = {0, 0, getDisplayWidth(), getDisplayHeight() / 2};
911 common::Rect blueRect = {0, getDisplayHeight() / 4, getDisplayWidth(), getDisplayHeight()};
Ady Abrahama00d2462023-12-26 14:21:20 -0800912 auto redLayer =
913 std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
ramindanibab8ba92021-11-18 01:24:11 +0000914 redLayer->setColor(RED);
915 redLayer->setDisplayFrame(redRect);
916
Ady Abrahama00d2462023-12-26 14:21:20 -0800917 auto blueLayer =
918 std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
ramindanibab8ba92021-11-18 01:24:11 +0000919 blueLayer->setColor(BLUE);
920 blueLayer->setDisplayFrame(blueRect);
921 blueLayer->setZOrder(5);
922
923 std::vector<std::shared_ptr<TestLayer>> layers = {redLayer, blueLayer};
ramindanidcecfd42022-02-03 23:52:19 +0000924 std::vector<Color> expectedColors(
925 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
ramindanibab8ba92021-11-18 01:24:11 +0000926
927 // red in front of blue
928 redLayer->setZOrder(10);
929
930 // fill blue first so that red will overwrite on overlap
ramindanidcecfd42022-02-03 23:52:19 +0000931 ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), blueRect, BLUE);
932 ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), redRect, RED);
ramindanibab8ba92021-11-18 01:24:11 +0000933
ramindanidcecfd42022-02-03 23:52:19 +0000934 ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
Brian Lindahle887a252023-01-17 14:54:19 -0700935 getDisplayHeight(), mPixelFormat, mDataspace);
ramindanibab8ba92021-11-18 01:24:11 +0000936 ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
937
938 writeLayers(layers);
Ady Abraham3192f3d2021-12-03 16:08:56 -0800939 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanicdcfcaf2023-11-09 10:00:10 -0800940 mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
941 VtsComposerClient::kNoFrameIntervalNs);
ramindanibab8ba92021-11-18 01:24:11 +0000942 execute();
ramindanidcecfd42022-02-03 23:52:19 +0000943 if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
ramindanibab8ba92021-11-18 01:24:11 +0000944 GTEST_SUCCEED();
945 return;
946 }
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -0400947 mWriter->presentDisplay(getPrimaryDisplayId());
ramindanibab8ba92021-11-18 01:24:11 +0000948 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -0800949 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanibab8ba92021-11-18 01:24:11 +0000950
951 ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
952
953 redLayer->setZOrder(1);
ramindanidcecfd42022-02-03 23:52:19 +0000954 ReadbackHelper::clearColors(expectedColors, getDisplayWidth(), getDisplayHeight(),
955 getDisplayWidth());
956 ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), redRect, RED);
957 ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), blueRect, BLUE);
ramindanibab8ba92021-11-18 01:24:11 +0000958
959 ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
960
961 writeLayers(layers);
Ady Abraham3192f3d2021-12-03 16:08:56 -0800962 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanicdcfcaf2023-11-09 10:00:10 -0800963 mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
964 VtsComposerClient::kNoFrameIntervalNs);
ramindanibab8ba92021-11-18 01:24:11 +0000965 execute();
ramindanidcecfd42022-02-03 23:52:19 +0000966 ASSERT_TRUE(mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty());
Ady Abraham3192f3d2021-12-03 16:08:56 -0800967 ASSERT_TRUE(mReader.takeErrors().empty());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -0400968 mWriter->presentDisplay(getPrimaryDisplayId());
ramindanibab8ba92021-11-18 01:24:11 +0000969 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -0800970 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanibab8ba92021-11-18 01:24:11 +0000971
972 ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
973 mTestRenderEngine->setRenderLayers(layers);
974 ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
975 ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
976 }
977}
978
Alec Mourib1f16722022-02-07 13:03:44 -0800979TEST_P(GraphicsCompositionTest, SetLayerBrightnessDims) {
Alec Mouri51067012022-01-06 17:28:39 -0800980 for (ColorMode mode : mTestColorModes) {
ramindanidcecfd42022-02-03 23:52:19 +0000981 EXPECT_TRUE(mComposerClient
982 ->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
983 .isOk());
Alec Mouri51067012022-01-06 17:28:39 -0800984
ramindani44c952f2022-02-28 23:29:29 +0000985 bool isSupported;
986 ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
ramindanidcecfd42022-02-03 23:52:19 +0000987 if (!isSupported) {
Alec Mouri51067012022-01-06 17:28:39 -0800988 GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace for "
989 "color mode: "
990 << toString(mode);
991 continue;
992 }
ramindanidcecfd42022-02-03 23:52:19 +0000993 const common::Rect redRect = {0, 0, getDisplayWidth(), getDisplayHeight() / 2};
994 const common::Rect dimmerRedRect = {0, getDisplayHeight() / 2, getDisplayWidth(),
995 getDisplayHeight()};
Alec Mouri712b3d92023-09-29 00:21:37 +0000996
997 static constexpr float kMaxBrightnessNits = 300.f;
998
ramindanidcecfd42022-02-03 23:52:19 +0000999 const auto redLayer =
Ady Abrahama00d2462023-12-26 14:21:20 -08001000 std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
Alec Mouri51067012022-01-06 17:28:39 -08001001 redLayer->setColor(RED);
1002 redLayer->setDisplayFrame(redRect);
Alec Mouri712b3d92023-09-29 00:21:37 +00001003 redLayer->setWhitePointNits(kMaxBrightnessNits);
Alec Mourib1f16722022-02-07 13:03:44 -08001004 redLayer->setBrightness(1.f);
Alec Mouri51067012022-01-06 17:28:39 -08001005
1006 const auto dimmerRedLayer =
Ady Abrahama00d2462023-12-26 14:21:20 -08001007 std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
Alec Mouri51067012022-01-06 17:28:39 -08001008 dimmerRedLayer->setColor(RED);
1009 dimmerRedLayer->setDisplayFrame(dimmerRedRect);
1010 // Intentionally use a small dimming ratio as some implementations may be more likely to
1011 // kick into GPU composition to apply dithering when the dimming ratio is high.
1012 static constexpr float kDimmingRatio = 0.9f;
Alec Mouri712b3d92023-09-29 00:21:37 +00001013 dimmerRedLayer->setWhitePointNits(kMaxBrightnessNits * kDimmingRatio);
Alec Mourib1f16722022-02-07 13:03:44 -08001014 dimmerRedLayer->setBrightness(kDimmingRatio);
Alec Mouri51067012022-01-06 17:28:39 -08001015
1016 const std::vector<std::shared_ptr<TestLayer>> layers = {redLayer, dimmerRedLayer};
ramindanidcecfd42022-02-03 23:52:19 +00001017 std::vector<Color> expectedColors(
1018 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
Alec Mouri51067012022-01-06 17:28:39 -08001019
ramindanidcecfd42022-02-03 23:52:19 +00001020 ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), redRect, RED);
1021 ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(), dimmerRedRect, DIM_RED);
Alec Mouri51067012022-01-06 17:28:39 -08001022
ramindanidcecfd42022-02-03 23:52:19 +00001023 ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
Brian Lindahle887a252023-01-17 14:54:19 -07001024 getDisplayHeight(), mPixelFormat, mDataspace);
Alec Mouri51067012022-01-06 17:28:39 -08001025 ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
1026
1027 writeLayers(layers);
1028 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanicdcfcaf2023-11-09 10:00:10 -08001029 mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
1030 VtsComposerClient::kNoFrameIntervalNs);
Alec Mouri51067012022-01-06 17:28:39 -08001031 execute();
ramindanidcecfd42022-02-03 23:52:19 +00001032 if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
Alec Mouri51067012022-01-06 17:28:39 -08001033 GTEST_SUCCEED()
1034 << "Readback verification not supported for GPU composition for color mode: "
1035 << toString(mode);
1036 continue;
1037 }
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001038 mWriter->presentDisplay(getPrimaryDisplayId());
Alec Mouri51067012022-01-06 17:28:39 -08001039 execute();
1040 ASSERT_TRUE(mReader.takeErrors().empty());
1041
1042 ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
1043 mTestRenderEngine->setRenderLayers(layers);
1044 ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
1045 ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
1046 }
1047}
1048
ramindanibab8ba92021-11-18 01:24:11 +00001049class GraphicsBlendModeCompositionTest
1050 : public GraphicsCompositionTestBase,
1051 public testing::WithParamInterface<std::tuple<std::string, std::string>> {
1052 public:
1053 void SetUp() override {
1054 SetUpBase(std::get<0>(GetParam()));
ramindanib636af22022-02-10 02:55:56 +00001055 // TODO(b/219590743) we should remove the below SRGB color mode
1056 // once we have the BlendMode test fix for all the versions of the ColorMode
ramindania4e76362022-03-02 01:48:06 +00001057 mTestColorModes.erase(
1058 std::remove_if(mTestColorModes.begin(), mTestColorModes.end(),
1059 [](ColorMode mode) { return mode != ColorMode::SRGB; }),
1060 mTestColorModes.end());
ramindanibab8ba92021-11-18 01:24:11 +00001061 mBackgroundColor = BLACK;
1062 mTopLayerColor = RED;
1063 }
1064
1065 void setBackgroundColor(Color color) { mBackgroundColor = color; }
1066
1067 void setTopLayerColor(Color color) { mTopLayerColor = color; }
1068
1069 void setUpLayers(BlendMode blendMode) {
1070 mLayers.clear();
ramindanidcecfd42022-02-03 23:52:19 +00001071 std::vector<Color> topLayerPixelColors(
1072 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
1073 ReadbackHelper::fillColorsArea(topLayerPixelColors, getDisplayWidth(),
1074 {0, 0, getDisplayWidth(), getDisplayHeight()},
1075 mTopLayerColor);
ramindanibab8ba92021-11-18 01:24:11 +00001076
ramindanidcecfd42022-02-03 23:52:19 +00001077 auto backgroundLayer =
Ady Abrahama00d2462023-12-26 14:21:20 -08001078 std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
ramindanidcecfd42022-02-03 23:52:19 +00001079 backgroundLayer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
ramindanibab8ba92021-11-18 01:24:11 +00001080 backgroundLayer->setZOrder(0);
1081 backgroundLayer->setColor(mBackgroundColor);
1082
Ady Abrahama00d2462023-12-26 14:21:20 -08001083 auto layer = std::make_shared<TestBufferLayer>(
1084 mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
1085 getDisplayHeight(), PixelFormat::RGBA_8888, *mWriter);
ramindanidcecfd42022-02-03 23:52:19 +00001086 layer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
ramindanibab8ba92021-11-18 01:24:11 +00001087 layer->setZOrder(10);
Alec Mourif6c039a2023-10-06 23:02:17 +00001088 layer->setDataspace(Dataspace::UNKNOWN);
ramindanibab8ba92021-11-18 01:24:11 +00001089 ASSERT_NO_FATAL_FAILURE(layer->setBuffer(topLayerPixelColors));
1090
1091 layer->setBlendMode(blendMode);
1092 layer->setAlpha(std::stof(std::get<1>(GetParam())));
1093
1094 mLayers.push_back(backgroundLayer);
1095 mLayers.push_back(layer);
1096 }
1097
1098 void setExpectedColors(std::vector<Color>& expectedColors) {
1099 ASSERT_EQ(2, mLayers.size());
ramindanidcecfd42022-02-03 23:52:19 +00001100 ReadbackHelper::clearColors(expectedColors, getDisplayWidth(), getDisplayHeight(),
1101 getDisplayWidth());
ramindanibab8ba92021-11-18 01:24:11 +00001102
1103 auto layer = mLayers[1];
1104 BlendMode blendMode = layer->getBlendMode();
Ady Abraham1bee7ab2022-01-06 17:22:08 -08001105 float alpha = mTopLayerColor.a * layer->getAlpha();
ramindanibab8ba92021-11-18 01:24:11 +00001106 if (blendMode == BlendMode::NONE) {
1107 for (auto& expectedColor : expectedColors) {
Ady Abraham1bee7ab2022-01-06 17:22:08 -08001108 expectedColor.r = mTopLayerColor.r * layer->getAlpha();
1109 expectedColor.g = mTopLayerColor.g * layer->getAlpha();
1110 expectedColor.b = mTopLayerColor.b * layer->getAlpha();
1111 expectedColor.a = alpha;
ramindanibab8ba92021-11-18 01:24:11 +00001112 }
1113 } else if (blendMode == BlendMode::PREMULTIPLIED) {
1114 for (auto& expectedColor : expectedColors) {
Ady Abraham1bee7ab2022-01-06 17:22:08 -08001115 expectedColor.r =
1116 mTopLayerColor.r * layer->getAlpha() + mBackgroundColor.r * (1.0f - alpha);
1117 expectedColor.g =
1118 mTopLayerColor.g * layer->getAlpha() + mBackgroundColor.g * (1.0f - alpha);
1119 expectedColor.b =
1120 mTopLayerColor.b * layer->getAlpha() + mBackgroundColor.b * (1.0f - alpha);
1121 expectedColor.a = alpha + mBackgroundColor.a * (1.0f - alpha);
ramindanibab8ba92021-11-18 01:24:11 +00001122 }
1123 } else if (blendMode == BlendMode::COVERAGE) {
1124 for (auto& expectedColor : expectedColors) {
Ady Abraham1bee7ab2022-01-06 17:22:08 -08001125 expectedColor.r = mTopLayerColor.r * alpha + mBackgroundColor.r * (1.0f - alpha);
1126 expectedColor.g = mTopLayerColor.g * alpha + mBackgroundColor.g * (1.0f - alpha);
1127 expectedColor.b = mTopLayerColor.b * alpha + mBackgroundColor.b * (1.0f - alpha);
1128 expectedColor.a = mTopLayerColor.a * alpha + mBackgroundColor.a * (1.0f - alpha);
ramindanibab8ba92021-11-18 01:24:11 +00001129 }
1130 }
1131 }
1132
1133 protected:
1134 std::vector<std::shared_ptr<TestLayer>> mLayers;
1135 Color mBackgroundColor;
1136 Color mTopLayerColor;
1137};
ramindanic7585d92022-04-15 18:30:41 +00001138
1139TEST_P(GraphicsBlendModeCompositionTest, None) {
ramindanibab8ba92021-11-18 01:24:11 +00001140 for (ColorMode mode : mTestColorModes) {
ramindanidcecfd42022-02-03 23:52:19 +00001141 EXPECT_TRUE(mComposerClient
1142 ->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
1143 .isOk());
ramindanibab8ba92021-11-18 01:24:11 +00001144
ramindani44c952f2022-02-28 23:29:29 +00001145 bool isSupported;
1146 ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
ramindanidcecfd42022-02-03 23:52:19 +00001147 if (!isSupported) {
ramindanibab8ba92021-11-18 01:24:11 +00001148 GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
1149 return;
1150 }
1151
ramindanidcecfd42022-02-03 23:52:19 +00001152 std::vector<Color> expectedColors(
1153 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
ramindanibab8ba92021-11-18 01:24:11 +00001154
1155 setBackgroundColor(BLACK);
1156 setTopLayerColor(TRANSLUCENT_RED);
1157 setUpLayers(BlendMode::NONE);
1158 setExpectedColors(expectedColors);
1159
ramindanidcecfd42022-02-03 23:52:19 +00001160 ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
Brian Lindahle887a252023-01-17 14:54:19 -07001161 getDisplayHeight(), mPixelFormat, mDataspace);
ramindanibab8ba92021-11-18 01:24:11 +00001162 ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
1163 writeLayers(mLayers);
Ady Abraham3192f3d2021-12-03 16:08:56 -08001164 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanicdcfcaf2023-11-09 10:00:10 -08001165 mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
1166 VtsComposerClient::kNoFrameIntervalNs);
ramindanibab8ba92021-11-18 01:24:11 +00001167 execute();
ramindanidcecfd42022-02-03 23:52:19 +00001168 if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
ramindanibab8ba92021-11-18 01:24:11 +00001169 GTEST_SUCCEED();
1170 return;
1171 }
Ady Abraham3192f3d2021-12-03 16:08:56 -08001172 ASSERT_TRUE(mReader.takeErrors().empty());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001173 mWriter->presentDisplay(getPrimaryDisplayId());
ramindanibab8ba92021-11-18 01:24:11 +00001174 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08001175 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanibab8ba92021-11-18 01:24:11 +00001176
1177 ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
1178 mTestRenderEngine->setRenderLayers(mLayers);
1179 ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
1180 ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
1181 }
1182}
1183
ramindani07e6f842022-02-15 15:28:33 +00001184TEST_P(GraphicsBlendModeCompositionTest, Coverage) {
ramindanibab8ba92021-11-18 01:24:11 +00001185 for (ColorMode mode : mTestColorModes) {
ramindanidcecfd42022-02-03 23:52:19 +00001186 EXPECT_TRUE(mComposerClient
1187 ->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
1188 .isOk());
ramindanibab8ba92021-11-18 01:24:11 +00001189
ramindani44c952f2022-02-28 23:29:29 +00001190 bool isSupported;
1191 ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
ramindanidcecfd42022-02-03 23:52:19 +00001192 if (!isSupported) {
ramindanibab8ba92021-11-18 01:24:11 +00001193 GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
1194 return;
1195 }
1196
ramindanidcecfd42022-02-03 23:52:19 +00001197 std::vector<Color> expectedColors(
1198 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
ramindanibab8ba92021-11-18 01:24:11 +00001199
1200 setBackgroundColor(BLACK);
1201 setTopLayerColor(TRANSLUCENT_RED);
1202
1203 setUpLayers(BlendMode::COVERAGE);
1204 setExpectedColors(expectedColors);
1205
ramindanidcecfd42022-02-03 23:52:19 +00001206 ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
Brian Lindahle887a252023-01-17 14:54:19 -07001207 getDisplayHeight(), mPixelFormat, mDataspace);
ramindanibab8ba92021-11-18 01:24:11 +00001208 ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
1209 writeLayers(mLayers);
Ady Abraham3192f3d2021-12-03 16:08:56 -08001210 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanicdcfcaf2023-11-09 10:00:10 -08001211 mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
1212 VtsComposerClient::kNoFrameIntervalNs);
ramindanibab8ba92021-11-18 01:24:11 +00001213 execute();
ramindanidcecfd42022-02-03 23:52:19 +00001214 if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
ramindanibab8ba92021-11-18 01:24:11 +00001215 GTEST_SUCCEED();
1216 return;
1217 }
Ady Abraham3192f3d2021-12-03 16:08:56 -08001218 ASSERT_TRUE(mReader.takeErrors().empty());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001219 mWriter->presentDisplay(getPrimaryDisplayId());
ramindanibab8ba92021-11-18 01:24:11 +00001220 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08001221 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanibab8ba92021-11-18 01:24:11 +00001222 ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
1223 }
1224}
1225
1226TEST_P(GraphicsBlendModeCompositionTest, Premultiplied) {
1227 for (ColorMode mode : mTestColorModes) {
ramindanidcecfd42022-02-03 23:52:19 +00001228 EXPECT_TRUE(mComposerClient
1229 ->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
1230 .isOk());
ramindanibab8ba92021-11-18 01:24:11 +00001231
ramindani44c952f2022-02-28 23:29:29 +00001232 bool isSupported;
1233 ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
ramindanidcecfd42022-02-03 23:52:19 +00001234 if (!isSupported) {
ramindanibab8ba92021-11-18 01:24:11 +00001235 GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
1236 return;
1237 }
ramindanibab8ba92021-11-18 01:24:11 +00001238
ramindanidcecfd42022-02-03 23:52:19 +00001239 std::vector<Color> expectedColors(
1240 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
ramindanibab8ba92021-11-18 01:24:11 +00001241
1242 setBackgroundColor(BLACK);
1243 setTopLayerColor(TRANSLUCENT_RED);
1244 setUpLayers(BlendMode::PREMULTIPLIED);
1245 setExpectedColors(expectedColors);
1246
ramindanidcecfd42022-02-03 23:52:19 +00001247 ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
Brian Lindahle887a252023-01-17 14:54:19 -07001248 getDisplayHeight(), mPixelFormat, mDataspace);
ramindanibab8ba92021-11-18 01:24:11 +00001249 ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
1250 writeLayers(mLayers);
Ady Abraham3192f3d2021-12-03 16:08:56 -08001251 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanicdcfcaf2023-11-09 10:00:10 -08001252 mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
1253 VtsComposerClient::kNoFrameIntervalNs);
ramindanibab8ba92021-11-18 01:24:11 +00001254 execute();
ramindanidcecfd42022-02-03 23:52:19 +00001255 if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
ramindanibab8ba92021-11-18 01:24:11 +00001256 GTEST_SUCCEED();
1257 return;
1258 }
Ady Abraham3192f3d2021-12-03 16:08:56 -08001259 ASSERT_TRUE(mReader.takeErrors().empty());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001260 mWriter->presentDisplay(getPrimaryDisplayId());
ramindanibab8ba92021-11-18 01:24:11 +00001261 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08001262 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanibab8ba92021-11-18 01:24:11 +00001263 ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
1264 mTestRenderEngine->setRenderLayers(mLayers);
1265 ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
1266 ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
1267 }
1268}
1269
1270class GraphicsTransformCompositionTest : public GraphicsCompositionTest {
1271 protected:
1272 void SetUp() override {
1273 GraphicsCompositionTest::SetUp();
Ady Abraham3192f3d2021-12-03 16:08:56 -08001274
ramindanidcecfd42022-02-03 23:52:19 +00001275 auto backgroundLayer =
Ady Abrahama00d2462023-12-26 14:21:20 -08001276 std::make_shared<TestColorLayer>(mComposerClient, getPrimaryDisplayId(), *mWriter);
Ady Abraham1bee7ab2022-01-06 17:22:08 -08001277 backgroundLayer->setColor({0.0f, 0.0f, 0.0f, 0.0f});
ramindanidcecfd42022-02-03 23:52:19 +00001278 backgroundLayer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
ramindanibab8ba92021-11-18 01:24:11 +00001279 backgroundLayer->setZOrder(0);
1280
ramindanidcecfd42022-02-03 23:52:19 +00001281 mSideLength =
1282 getDisplayWidth() < getDisplayHeight() ? getDisplayWidth() : getDisplayHeight();
ramindanibab8ba92021-11-18 01:24:11 +00001283 common::Rect redRect = {0, 0, mSideLength / 2, mSideLength / 2};
1284 common::Rect blueRect = {mSideLength / 2, mSideLength / 2, mSideLength, mSideLength};
1285
ramindani0a2bee42022-02-10 01:27:42 +00001286 mLayer = std::make_shared<TestBufferLayer>(mComposerClient, *mTestRenderEngine,
1287 getPrimaryDisplayId(), mSideLength, mSideLength,
Ady Abrahama00d2462023-12-26 14:21:20 -08001288 PixelFormat::RGBA_8888, *mWriter);
ramindanibab8ba92021-11-18 01:24:11 +00001289 mLayer->setDisplayFrame({0, 0, mSideLength, mSideLength});
1290 mLayer->setZOrder(10);
1291
1292 std::vector<Color> baseColors(static_cast<size_t>(mSideLength * mSideLength));
1293 ReadbackHelper::fillColorsArea(baseColors, mSideLength, redRect, RED);
1294 ReadbackHelper::fillColorsArea(baseColors, mSideLength, blueRect, BLUE);
1295 ASSERT_NO_FATAL_FAILURE(mLayer->setBuffer(baseColors));
1296 mLayers = {backgroundLayer, mLayer};
1297 }
1298
1299 protected:
1300 std::shared_ptr<TestBufferLayer> mLayer;
1301 std::vector<std::shared_ptr<TestLayer>> mLayers;
1302 int mSideLength;
1303};
1304
1305TEST_P(GraphicsTransformCompositionTest, FLIP_H) {
1306 for (ColorMode mode : mTestColorModes) {
ramindanidcecfd42022-02-03 23:52:19 +00001307 auto status = mComposerClient->setColorMode(getPrimaryDisplayId(), mode,
1308 RenderIntent::COLORIMETRIC);
ramindanid5751092022-04-22 22:30:20 +00001309 if (!status.isOk() && status.getExceptionCode() == EX_SERVICE_SPECIFIC &&
ramindanidcecfd42022-02-03 23:52:19 +00001310 (status.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED ||
1311 status.getServiceSpecificError() == IComposerClient::EX_BAD_PARAMETER)) {
ramindanibab8ba92021-11-18 01:24:11 +00001312 SUCCEED() << "ColorMode not supported, skip test";
1313 return;
1314 }
1315
ramindani44c952f2022-02-28 23:29:29 +00001316 bool isSupported;
1317 ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
ramindanidcecfd42022-02-03 23:52:19 +00001318 if (!isSupported) {
ramindanibab8ba92021-11-18 01:24:11 +00001319 GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
1320 return;
1321 }
ramindanidcecfd42022-02-03 23:52:19 +00001322 ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
Brian Lindahle887a252023-01-17 14:54:19 -07001323 getDisplayHeight(), mPixelFormat, mDataspace);
ramindanibab8ba92021-11-18 01:24:11 +00001324 ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
1325 mLayer->setTransform(Transform::FLIP_H);
Alec Mourif6c039a2023-10-06 23:02:17 +00001326 mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
ramindanibab8ba92021-11-18 01:24:11 +00001327
ramindanidcecfd42022-02-03 23:52:19 +00001328 std::vector<Color> expectedColors(
1329 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
1330 ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(),
ramindanibab8ba92021-11-18 01:24:11 +00001331 {mSideLength / 2, 0, mSideLength, mSideLength / 2}, RED);
ramindanidcecfd42022-02-03 23:52:19 +00001332 ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(),
ramindanibab8ba92021-11-18 01:24:11 +00001333 {0, mSideLength / 2, mSideLength / 2, mSideLength}, BLUE);
1334
1335 writeLayers(mLayers);
Ady Abraham3192f3d2021-12-03 16:08:56 -08001336 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanicdcfcaf2023-11-09 10:00:10 -08001337 mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
1338 VtsComposerClient::kNoFrameIntervalNs);
ramindanibab8ba92021-11-18 01:24:11 +00001339 execute();
ramindanidcecfd42022-02-03 23:52:19 +00001340 if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
ramindanibab8ba92021-11-18 01:24:11 +00001341 GTEST_SUCCEED();
1342 return;
1343 }
Ady Abraham3192f3d2021-12-03 16:08:56 -08001344 ASSERT_TRUE(mReader.takeErrors().empty());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001345 mWriter->presentDisplay(getPrimaryDisplayId());
ramindanibab8ba92021-11-18 01:24:11 +00001346 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08001347 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanibab8ba92021-11-18 01:24:11 +00001348
1349 ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
1350 mTestRenderEngine->setRenderLayers(mLayers);
1351 ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
1352 ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
1353 }
1354}
1355
1356TEST_P(GraphicsTransformCompositionTest, FLIP_V) {
1357 for (ColorMode mode : mTestColorModes) {
ramindanidcecfd42022-02-03 23:52:19 +00001358 EXPECT_TRUE(mComposerClient
1359 ->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
1360 .isOk());
ramindanibab8ba92021-11-18 01:24:11 +00001361
ramindani44c952f2022-02-28 23:29:29 +00001362 bool isSupported;
1363 ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
ramindanidcecfd42022-02-03 23:52:19 +00001364 if (!isSupported) {
ramindanibab8ba92021-11-18 01:24:11 +00001365 GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
1366 return;
1367 }
ramindanidcecfd42022-02-03 23:52:19 +00001368 ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
Brian Lindahle887a252023-01-17 14:54:19 -07001369 getDisplayHeight(), mPixelFormat, mDataspace);
ramindanibab8ba92021-11-18 01:24:11 +00001370 ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
1371
1372 mLayer->setTransform(Transform::FLIP_V);
Alec Mourif6c039a2023-10-06 23:02:17 +00001373 mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
ramindanibab8ba92021-11-18 01:24:11 +00001374
ramindanidcecfd42022-02-03 23:52:19 +00001375 std::vector<Color> expectedColors(
1376 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
1377 ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(),
ramindanibab8ba92021-11-18 01:24:11 +00001378 {0, mSideLength / 2, mSideLength / 2, mSideLength}, RED);
ramindanidcecfd42022-02-03 23:52:19 +00001379 ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(),
ramindanibab8ba92021-11-18 01:24:11 +00001380 {mSideLength / 2, 0, mSideLength, mSideLength / 2}, BLUE);
1381
1382 writeLayers(mLayers);
Ady Abraham3192f3d2021-12-03 16:08:56 -08001383 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanicdcfcaf2023-11-09 10:00:10 -08001384 mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
1385 VtsComposerClient::kNoFrameIntervalNs);
ramindanibab8ba92021-11-18 01:24:11 +00001386 execute();
ramindanidcecfd42022-02-03 23:52:19 +00001387 if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
ramindanibab8ba92021-11-18 01:24:11 +00001388 GTEST_SUCCEED();
1389 return;
1390 }
Ady Abraham3192f3d2021-12-03 16:08:56 -08001391 ASSERT_TRUE(mReader.takeErrors().empty());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001392 mWriter->presentDisplay(getPrimaryDisplayId());
ramindanibab8ba92021-11-18 01:24:11 +00001393 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08001394 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanibab8ba92021-11-18 01:24:11 +00001395 ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
1396 mTestRenderEngine->setRenderLayers(mLayers);
1397 ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
1398 ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
1399 }
1400}
1401
1402TEST_P(GraphicsTransformCompositionTest, ROT_180) {
1403 for (ColorMode mode : mTestColorModes) {
ramindanidcecfd42022-02-03 23:52:19 +00001404 EXPECT_TRUE(mComposerClient
1405 ->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
1406 .isOk());
ramindanibab8ba92021-11-18 01:24:11 +00001407
ramindani44c952f2022-02-28 23:29:29 +00001408 bool isSupported;
1409 ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
ramindanidcecfd42022-02-03 23:52:19 +00001410 if (!isSupported) {
ramindanibab8ba92021-11-18 01:24:11 +00001411 GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
1412 return;
1413 }
ramindanidcecfd42022-02-03 23:52:19 +00001414 ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
Brian Lindahle887a252023-01-17 14:54:19 -07001415 getDisplayHeight(), mPixelFormat, mDataspace);
ramindanibab8ba92021-11-18 01:24:11 +00001416 ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
1417
1418 mLayer->setTransform(Transform::ROT_180);
Alec Mourif6c039a2023-10-06 23:02:17 +00001419 mLayer->setDataspace(ReadbackHelper::getDataspaceForColorMode(mode));
ramindanibab8ba92021-11-18 01:24:11 +00001420
ramindanidcecfd42022-02-03 23:52:19 +00001421 std::vector<Color> expectedColors(
1422 static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
1423 ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(),
ramindanibab8ba92021-11-18 01:24:11 +00001424 {mSideLength / 2, mSideLength / 2, mSideLength, mSideLength},
1425 RED);
ramindanidcecfd42022-02-03 23:52:19 +00001426 ReadbackHelper::fillColorsArea(expectedColors, getDisplayWidth(),
ramindanibab8ba92021-11-18 01:24:11 +00001427 {0, 0, mSideLength / 2, mSideLength / 2}, BLUE);
1428
1429 writeLayers(mLayers);
Ady Abraham3192f3d2021-12-03 16:08:56 -08001430 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanicdcfcaf2023-11-09 10:00:10 -08001431 mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
1432 VtsComposerClient::kNoFrameIntervalNs);
ramindanibab8ba92021-11-18 01:24:11 +00001433 execute();
ramindanidcecfd42022-02-03 23:52:19 +00001434 if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
ramindanibab8ba92021-11-18 01:24:11 +00001435 GTEST_SUCCEED();
1436 return;
1437 }
Ady Abraham3192f3d2021-12-03 16:08:56 -08001438 ASSERT_TRUE(mReader.takeErrors().empty());
Leon Scroggins IIIc3d695d2022-09-16 15:34:59 -04001439 mWriter->presentDisplay(getPrimaryDisplayId());
ramindanibab8ba92021-11-18 01:24:11 +00001440 execute();
Ady Abraham3192f3d2021-12-03 16:08:56 -08001441 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanibab8ba92021-11-18 01:24:11 +00001442 ASSERT_NO_FATAL_FAILURE(readbackBuffer.checkReadbackBuffer(expectedColors));
1443 mTestRenderEngine->setRenderLayers(mLayers);
1444 ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
1445 ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->checkColorBuffer(expectedColors));
1446 }
1447}
1448
Alec Mourif6c039a2023-10-06 23:02:17 +00001449class GraphicsColorManagementCompositionTest
1450 : public GraphicsCompositionTestBase,
1451 public testing::WithParamInterface<std::tuple<std::string, Dataspace, Dataspace, Dataspace>> {
1452 public:
1453 void SetUp() override {
1454 SetUpBase(std::get<0>(GetParam()));
1455 // for some reason only sRGB reliably works
1456 mTestColorModes.erase(
1457 std::remove_if(mTestColorModes.begin(), mTestColorModes.end(),
1458 [](ColorMode mode) { return mode != ColorMode::SRGB; }),
1459 mTestColorModes.end());
1460 auto standard = std::get<1>(GetParam());
1461 auto transfer = std::get<2>(GetParam());
1462 auto range = std::get<3>(GetParam());
1463
1464 mLayerDataspace = static_cast<Dataspace>(static_cast<int32_t>(standard) |
1465 static_cast<int32_t>(transfer) |
1466 static_cast<int32_t>(range));
1467 ALOGD("Invoking test for dataspace: {%s, %s, %s}", toString(standard).c_str(),
1468 toString(transfer).c_str(), toString(range).c_str());
1469 }
1470
1471 void makeLayer() {
1472 mLayer = std::make_shared<TestBufferLayer>(
1473 mComposerClient, *mTestRenderEngine, getPrimaryDisplayId(), getDisplayWidth(),
Ady Abrahama00d2462023-12-26 14:21:20 -08001474 getDisplayHeight(), common::PixelFormat::RGBA_8888, *mWriter);
Alec Mourif6c039a2023-10-06 23:02:17 +00001475 mLayer->setDisplayFrame({0, 0, getDisplayWidth(), getDisplayHeight()});
1476 mLayer->setZOrder(10);
1477 mLayer->setAlpha(1.f);
1478 mLayer->setDataspace(mLayerDataspace);
1479 }
1480
1481 void fillColor(Color color) {
1482 std::vector<Color> baseColors(static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
1483 ReadbackHelper::fillColorsArea(baseColors, getDisplayWidth(),
1484 common::Rect{.left = 0,
1485 .top = 0,
1486 .right = getDisplayWidth(),
1487 .bottom = getDisplayHeight()},
1488 color);
1489 ASSERT_NO_FATAL_FAILURE(mLayer->setBuffer(baseColors));
1490 }
1491
1492 Dataspace mLayerDataspace;
1493 std::shared_ptr<TestBufferLayer> mLayer;
1494};
1495
1496TEST_P(GraphicsColorManagementCompositionTest, ColorConversion) {
1497 for (ColorMode mode : mTestColorModes) {
1498 EXPECT_TRUE(mComposerClient
1499 ->setColorMode(getPrimaryDisplayId(), mode, RenderIntent::COLORIMETRIC)
1500 .isOk());
1501
1502 bool isSupported;
1503 ASSERT_NO_FATAL_FAILURE(isSupported = getHasReadbackBuffer());
1504 if (!isSupported) {
1505 GTEST_SUCCEED() << "Readback not supported or unsupported pixelFormat/dataspace";
1506 return;
1507 }
1508
1509 mClientCompositionDisplaySettings.outputDataspace =
1510 static_cast<::android::ui::Dataspace>(mDataspace);
1511 mTestRenderEngine->setDisplaySettings(mClientCompositionDisplaySettings);
1512
1513 makeLayer();
1514 for (auto color : {LIGHT_RED, LIGHT_GREEN, LIGHT_BLUE}) {
1515 ALOGD("Testing color: %f, %f, %f, %f with color mode: %d", color.r, color.g, color.b,
1516 color.a, mode);
1517 ReadbackBuffer readbackBuffer(getPrimaryDisplayId(), mComposerClient, getDisplayWidth(),
1518 getDisplayHeight(), mPixelFormat, mDataspace);
1519 ASSERT_NO_FATAL_FAILURE(readbackBuffer.setReadbackBuffer());
1520 fillColor(color);
1521 writeLayers({mLayer});
1522 EXPECT_TRUE(mComposerClient->setPowerMode(getPrimaryDisplayId(), PowerMode::ON).isOk());
1523
1524 ASSERT_TRUE(mReader.takeErrors().empty());
ramindanicdcfcaf2023-11-09 10:00:10 -08001525 mWriter->validateDisplay(getPrimaryDisplayId(), ComposerClientWriter::kNoTimestamp,
1526 VtsComposerClient::kNoFrameIntervalNs);
Alec Mourif6c039a2023-10-06 23:02:17 +00001527 execute();
1528 if (!mReader.takeChangedCompositionTypes(getPrimaryDisplayId()).empty()) {
1529 continue;
1530 }
1531 ASSERT_TRUE(mReader.takeErrors().empty());
1532 mWriter->presentDisplay(getPrimaryDisplayId());
1533 execute();
1534 ASSERT_TRUE(mReader.takeErrors().empty());
1535
1536 mTestRenderEngine->setRenderLayers({mLayer});
1537 ASSERT_NO_FATAL_FAILURE(mTestRenderEngine->drawLayers());
1538 ASSERT_NO_FATAL_FAILURE(
1539 mTestRenderEngine->checkColorBuffer(readbackBuffer.getBuffer()));
1540 }
1541 }
1542}
1543
ramindanibab8ba92021-11-18 01:24:11 +00001544GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsCompositionTest);
1545INSTANTIATE_TEST_SUITE_P(
1546 PerInstance, GraphicsCompositionTest,
1547 testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
1548 ::android::PrintInstanceNameToString);
1549
1550GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsBlendModeCompositionTest);
1551INSTANTIATE_TEST_SUITE_P(BlendMode, GraphicsBlendModeCompositionTest,
1552 testing::Combine(testing::ValuesIn(::android::getAidlHalInstanceNames(
1553 IComposer::descriptor)),
1554 testing::Values("0.2", "1.0")));
1555
1556GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsTransformCompositionTest);
1557INSTANTIATE_TEST_SUITE_P(
1558 PerInstance, GraphicsTransformCompositionTest,
1559 testing::ValuesIn(::android::getAidlHalInstanceNames(IComposer::descriptor)),
1560 ::android::PrintInstanceNameToString);
1561
Alec Mourif6c039a2023-10-06 23:02:17 +00001562GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsColorManagementCompositionTest);
1563INSTANTIATE_TEST_SUITE_P(PerInstance, GraphicsColorManagementCompositionTest,
1564 testing::Combine(testing::ValuesIn(::android::getAidlHalInstanceNames(
1565 IComposer::descriptor)),
1566 // Only check sRGB, but verify that extended range
1567 // doesn't trigger any gamma shifts
1568 testing::Values(Dataspace::STANDARD_BT709),
1569 testing::Values(Dataspace::TRANSFER_SRGB),
1570 // Don't test limited range until we send YUV overlays
1571 testing::Values(Dataspace::RANGE_FULL,
1572 Dataspace::RANGE_EXTENDED)));
1573
ramindanibab8ba92021-11-18 01:24:11 +00001574} // namespace
Ady Abraham3192f3d2021-12-03 16:08:56 -08001575} // namespace aidl::android::hardware::graphics::composer3::vts