blob: b45c8c0bc76142b5a757cbde9c9667ba4959e62e [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
ramindani458e53e2022-02-23 17:30:16 +000017#include "ReadbackVts.h"
ramindanibab8ba92021-11-18 01:24:11 +000018#include <aidl/android/hardware/graphics/common/BufferUsage.h>
Alec Mouri6a000222024-08-16 23:08:09 +000019#include <cmath>
ramindani458e53e2022-02-23 17:30:16 +000020#include "RenderEngineVts.h"
ramindanibab8ba92021-11-18 01:24:11 +000021#include "renderengine/ExternalTexture.h"
Vishnu Nair59329712022-01-13 07:59:37 -080022#include "renderengine/impl/ExternalTexture.h"
ramindanibab8ba92021-11-18 01:24:11 +000023
ramindanibab8ba92021-11-18 01:24:11 +000024namespace aidl::android::hardware::graphics::composer3::vts {
25
26const std::vector<ColorMode> ReadbackHelper::colorModes = {ColorMode::SRGB, ColorMode::DISPLAY_P3};
27const std::vector<Dataspace> ReadbackHelper::dataspaces = {common::Dataspace::SRGB,
28 common::Dataspace::DISPLAY_P3};
29
Ady Abraham91c9d1a2021-12-15 18:14:45 -080030void TestLayer::write(ComposerClientWriter& writer) {
Ady Abraham3192f3d2021-12-03 16:08:56 -080031 writer.setLayerDisplayFrame(mDisplay, mLayer, mDisplayFrame);
32 writer.setLayerSourceCrop(mDisplay, mLayer, mSourceCrop);
33 writer.setLayerZOrder(mDisplay, mLayer, mZOrder);
34 writer.setLayerSurfaceDamage(mDisplay, mLayer, mSurfaceDamage);
35 writer.setLayerTransform(mDisplay, mLayer, mTransform);
36 writer.setLayerPlaneAlpha(mDisplay, mLayer, mAlpha);
37 writer.setLayerBlendMode(mDisplay, mLayer, mBlendMode);
Alec Mourib1f16722022-02-07 13:03:44 -080038 writer.setLayerBrightness(mDisplay, mLayer, mBrightness);
Alec Mourif6c039a2023-10-06 23:02:17 +000039 writer.setLayerDataspace(mDisplay, mLayer, mDataspace);
Sally Qife454362024-12-18 15:44:09 -080040 Luts luts{
41 .pfd = ::ndk::ScopedFileDescriptor(dup(mLuts.pfd.get())),
42 .offsets = mLuts.offsets,
43 .lutProperties = mLuts.lutProperties,
44 };
45 writer.setLayerLuts(mDisplay, mLayer, luts);
ramindanibab8ba92021-11-18 01:24:11 +000046}
47
48std::string ReadbackHelper::getColorModeString(ColorMode mode) {
49 switch (mode) {
50 case ColorMode::SRGB:
51 return {"SRGB"};
52 case ColorMode::DISPLAY_P3:
53 return {"DISPLAY_P3"};
54 default:
55 return {"Unsupported color mode for readback"};
56 }
57}
58
59std::string ReadbackHelper::getDataspaceString(common::Dataspace dataspace) {
60 switch (dataspace) {
61 case common::Dataspace::SRGB:
62 return {"SRGB"};
63 case common::Dataspace::DISPLAY_P3:
64 return {"DISPLAY_P3"};
65 case common::Dataspace::UNKNOWN:
66 return {"UNKNOWN"};
67 default:
68 return {"Unsupported dataspace for readback"};
69 }
70}
71
72Dataspace ReadbackHelper::getDataspaceForColorMode(ColorMode mode) {
73 switch (mode) {
74 case ColorMode::DISPLAY_P3:
75 return Dataspace::DISPLAY_P3;
76 case ColorMode::SRGB:
Sally Qi0ca29272024-02-23 11:07:08 -080077 return Dataspace::SRGB;
ramindanibab8ba92021-11-18 01:24:11 +000078 default:
Sally Qi0ca29272024-02-23 11:07:08 -080079 return Dataspace::UNKNOWN;
ramindanibab8ba92021-11-18 01:24:11 +000080 }
81}
82
83LayerSettings TestLayer::toRenderEngineLayerSettings() {
84 LayerSettings layerSettings;
85
86 layerSettings.alpha = ::android::half(mAlpha);
87 layerSettings.disableBlending = mBlendMode == BlendMode::NONE;
ramindanic7585d92022-04-15 18:30:41 +000088 layerSettings.source.buffer.isOpaque = mBlendMode == BlendMode::NONE;
ramindanibab8ba92021-11-18 01:24:11 +000089 layerSettings.geometry.boundaries = ::android::FloatRect(
90 static_cast<float>(mDisplayFrame.left), static_cast<float>(mDisplayFrame.top),
91 static_cast<float>(mDisplayFrame.right), static_cast<float>(mDisplayFrame.bottom));
92
93 const ::android::mat4 translation = ::android::mat4::translate(::android::vec4(
94 (static_cast<uint64_t>(mTransform) & static_cast<uint64_t>(Transform::FLIP_H)
95 ? static_cast<float>(-mDisplayFrame.right)
96 : 0.0f),
97 (static_cast<uint64_t>(mTransform) & static_cast<uint64_t>(Transform::FLIP_V)
98 ? static_cast<float>(-mDisplayFrame.bottom)
99 : 0.0f),
100 0.0f, 1.0f));
101
102 const ::android::mat4 scale = ::android::mat4::scale(::android::vec4(
103 static_cast<uint64_t>(mTransform) & static_cast<uint64_t>(Transform::FLIP_H) ? -1.0f
104 : 1.0f,
105 static_cast<uint64_t>(mTransform) & static_cast<uint64_t>(Transform::FLIP_V) ? -1.0f
106 : 1.0f,
107 1.0f, 1.0f));
108
109 layerSettings.geometry.positionTransform = scale * translation;
Alec Mouri51067012022-01-06 17:28:39 -0800110 layerSettings.whitePointNits = mWhitePointNits;
Alec Mourif6c039a2023-10-06 23:02:17 +0000111 layerSettings.sourceDataspace = static_cast<::android::ui::Dataspace>(mDataspace);
Sally Qife454362024-12-18 15:44:09 -0800112 if (mLuts.pfd.get() >= 0 && mLuts.offsets) {
113 std::vector<int32_t> dimensions;
114 std::vector<int32_t> sizes;
115 std::vector<int32_t> keys;
116 dimensions.reserve(mLuts.lutProperties.size());
117 sizes.reserve(mLuts.lutProperties.size());
118 keys.reserve(mLuts.lutProperties.size());
119
120 for (auto& l : mLuts.lutProperties) {
121 dimensions.emplace_back(static_cast<int32_t>(l.dimension));
122 sizes.emplace_back(static_cast<int32_t>(l.size));
123 keys.emplace_back(static_cast<int32_t>(l.samplingKeys[0]));
124 }
125
126 layerSettings.luts = std::make_shared<::android::gui::DisplayLuts>(
127 ::android::base::unique_fd(dup(mLuts.pfd.get())), *mLuts.offsets, dimensions, sizes,
128 keys);
129 }
ramindanibab8ba92021-11-18 01:24:11 +0000130
131 return layerSettings;
132}
133
Alec Mouri6a000222024-08-16 23:08:09 +0000134int32_t ReadbackHelper::GetBitsPerChannel(common::PixelFormat pixelFormat) {
ramindanibab8ba92021-11-18 01:24:11 +0000135 switch (pixelFormat) {
Alec Mouri6a000222024-08-16 23:08:09 +0000136 case common::PixelFormat::RGBA_1010102:
137 return 10;
Brian Lindahle887a252023-01-17 14:54:19 -0700138 case common::PixelFormat::RGBA_8888:
Brian Lindahle887a252023-01-17 14:54:19 -0700139 case common::PixelFormat::RGB_888:
Alec Mouri6a000222024-08-16 23:08:09 +0000140 return 8;
ramindanibab8ba92021-11-18 01:24:11 +0000141 default:
142 return -1;
143 }
144}
145
Alec Mouri6a000222024-08-16 23:08:09 +0000146int32_t ReadbackHelper::GetAlphaBits(common::PixelFormat pixelFormat) {
147 switch (pixelFormat) {
148 case common::PixelFormat::RGBA_8888:
149 return 8;
150 case common::PixelFormat::RGBA_1010102:
151 return 2;
152 case common::PixelFormat::RGB_888:
153 return 0;
154 default:
155 return -1;
156 }
157}
158
159void ReadbackHelper::fillBuffer(uint32_t width, uint32_t height, uint32_t stride,
160 int32_t bytesPerPixel, void* bufferData,
ramindanibab8ba92021-11-18 01:24:11 +0000161 common::PixelFormat pixelFormat,
Brian Lindahle887a252023-01-17 14:54:19 -0700162 std::vector<Color> desiredPixelColors) {
ramindanibab8ba92021-11-18 01:24:11 +0000163 ASSERT_TRUE(pixelFormat == common::PixelFormat::RGB_888 ||
Alec Mouri6a000222024-08-16 23:08:09 +0000164 pixelFormat == common::PixelFormat::RGBA_8888 ||
165 pixelFormat == common::PixelFormat::RGBA_1010102);
166 int32_t bitsPerChannel = GetBitsPerChannel(pixelFormat);
167 int32_t alphaBits = GetAlphaBits(pixelFormat);
168 ASSERT_NE(-1, alphaBits);
169 ASSERT_NE(-1, bitsPerChannel);
ramindanibab8ba92021-11-18 01:24:11 +0000170 ASSERT_NE(-1, bytesPerPixel);
Alec Mouri6a000222024-08-16 23:08:09 +0000171
172 uint32_t maxValue = (1 << bitsPerChannel) - 1;
173 uint32_t maxAlphaValue = (1 << alphaBits) - 1;
174 for (uint32_t row = 0; row < height; row++) {
175 for (uint32_t col = 0; col < width; col++) {
176 auto pixel = row * width + col;
Brian Lindahle887a252023-01-17 14:54:19 -0700177 Color srcColor = desiredPixelColors[static_cast<size_t>(pixel)];
ramindanibab8ba92021-11-18 01:24:11 +0000178
Alec Mouri6a000222024-08-16 23:08:09 +0000179 uint32_t offset = (row * stride + col) * static_cast<uint32_t>(bytesPerPixel);
ramindanibab8ba92021-11-18 01:24:11 +0000180
Alec Mouri6a000222024-08-16 23:08:09 +0000181 uint32_t* pixelStart = (uint32_t*)((uint8_t*)bufferData + offset);
182
183 uint32_t red = static_cast<uint32_t>(std::round(maxValue * srcColor.r));
184 uint32_t green = static_cast<uint32_t>(std::round(maxValue * srcColor.g));
185 uint32_t blue = static_cast<uint32_t>(std::round(maxValue * srcColor.b));
186
187 // Boo we're not word aligned so special case this.
188 if (pixelFormat == common::PixelFormat::RGB_888) {
189 uint8_t* pixelColor = (uint8_t*)pixelStart;
190 pixelColor[0] = static_cast<uint8_t>(red);
191 pixelColor[1] = static_cast<uint8_t>(green);
192 pixelColor[2] = static_cast<uint8_t>(blue);
193 } else {
194 uint32_t alpha = static_cast<uint32_t>(std::round(maxAlphaValue * srcColor.a));
195 uint32_t color = (alpha << (32 - alphaBits)) |
196 (blue << (32 - alphaBits - bitsPerChannel)) |
197 (green << (32 - alphaBits - bitsPerChannel * 2)) |
198 (red << (32 - alphaBits - bitsPerChannel * 3));
199 *pixelStart = color;
ramindanibab8ba92021-11-18 01:24:11 +0000200 }
201 }
202 }
203}
204
Brian Lindahle887a252023-01-17 14:54:19 -0700205void ReadbackHelper::clearColors(std::vector<Color>& expectedColors, int32_t width, int32_t height,
ramindanibab8ba92021-11-18 01:24:11 +0000206 int32_t displayWidth) {
207 for (int row = 0; row < height; row++) {
208 for (int col = 0; col < width; col++) {
209 int pixel = row * displayWidth + col;
Brian Lindahle887a252023-01-17 14:54:19 -0700210 expectedColors[static_cast<size_t>(pixel)] = BLACK;
ramindanibab8ba92021-11-18 01:24:11 +0000211 }
212 }
213}
214
Brian Lindahle887a252023-01-17 14:54:19 -0700215void ReadbackHelper::fillColorsArea(std::vector<Color>& expectedColors, int32_t stride, Rect area,
216 Color color) {
ramindanibab8ba92021-11-18 01:24:11 +0000217 for (int row = area.top; row < area.bottom; row++) {
218 for (int col = area.left; col < area.right; col++) {
219 int pixel = row * stride + col;
Brian Lindahle887a252023-01-17 14:54:19 -0700220 expectedColors[static_cast<size_t>(pixel)] = color;
ramindanibab8ba92021-11-18 01:24:11 +0000221 }
222 }
223}
224
Brian Lindahle887a252023-01-17 14:54:19 -0700225bool ReadbackHelper::readbackSupported(const common::PixelFormat& pixelFormat,
226 const common::Dataspace& dataspace) {
227 if (pixelFormat != common::PixelFormat::RGB_888 &&
Alec Mouri6a000222024-08-16 23:08:09 +0000228 pixelFormat != common::PixelFormat::RGBA_8888 &&
229 pixelFormat != common::PixelFormat::RGBA_1010102) {
Brian Lindahle887a252023-01-17 14:54:19 -0700230 return false;
Brian Lindahld103cd62022-12-09 07:26:28 -0700231 }
Brian Lindahle887a252023-01-17 14:54:19 -0700232 if (std::find(dataspaces.begin(), dataspaces.end(), dataspace) == dataspaces.end()) {
233 return false;
234 }
235 return true;
236}
237
238void ReadbackHelper::compareColorBuffers(const std::vector<Color>& expectedColors, void* bufferData,
Alec Mouri6a000222024-08-16 23:08:09 +0000239 const uint32_t stride, int32_t bytesPerPixel,
240 const uint32_t width, const uint32_t height,
241 common::PixelFormat pixelFormat) {
242 int32_t bitsPerChannel = GetBitsPerChannel(pixelFormat);
243 int32_t alphaBits = GetAlphaBits(pixelFormat);
244 ASSERT_GT(bytesPerPixel, 0);
245 ASSERT_NE(-1, alphaBits);
246 ASSERT_NE(-1, bitsPerChannel);
247 uint32_t maxValue = (1 << bitsPerChannel) - 1;
248 uint32_t maxAlphaValue = (1 << alphaBits) - 1;
249 for (uint32_t row = 0; row < height; row++) {
250 for (uint32_t col = 0; col < width; col++) {
251 auto pixel = row * width + col;
Ady Abraham1bee7ab2022-01-06 17:22:08 -0800252 const Color expectedColor = expectedColors[static_cast<size_t>(pixel)];
Alec Mouri6a000222024-08-16 23:08:09 +0000253
254 uint32_t offset = (row * stride + col) * static_cast<uint32_t>(bytesPerPixel);
255 uint32_t* pixelStart = (uint32_t*)((uint8_t*)bufferData + offset);
256
257 uint32_t expectedRed = static_cast<uint32_t>(std::round(maxValue * expectedColor.r));
258 uint32_t expectedGreen = static_cast<uint32_t>(std::round(maxValue * expectedColor.g));
259 uint32_t expectedBlue = static_cast<uint32_t>(std::round(maxValue * expectedColor.b));
260
261 // Boo we're not word aligned so special case this.
262 if (pixelFormat == common::PixelFormat::RGB_888) {
263 uint8_t* pixelColor = (uint8_t*)pixelStart;
264 ASSERT_EQ(pixelColor[0], static_cast<uint8_t>(expectedRed))
265 << "Red channel mismatch at (" << row << ", " << col << ")";
266 ASSERT_EQ(pixelColor[1], static_cast<uint8_t>(expectedGreen))
267 << "Green channel mismatch at (" << row << ", " << col << ")";
268 ASSERT_EQ(pixelColor[2], static_cast<uint8_t>(expectedBlue))
269 << "Blue channel mismatch at (" << row << ", " << col << ")";
270 } else {
271 uint32_t expectedAlpha =
272 static_cast<uint32_t>(std::round(maxAlphaValue * expectedColor.a));
273
274 uint32_t actualRed =
275 (*pixelStart >> (32 - alphaBits - bitsPerChannel * 3)) & maxValue;
276 uint32_t actualGreen =
277 (*pixelStart >> (32 - alphaBits - bitsPerChannel * 2)) & maxValue;
278 uint32_t actualBlue = (*pixelStart >> (32 - alphaBits - bitsPerChannel)) & maxValue;
279 uint32_t actualAlpha = (*pixelStart >> (32 - alphaBits)) & maxAlphaValue;
280
281 ASSERT_EQ(expectedRed, actualRed)
282 << "Red channel mismatch at (" << row << ", " << col << ")";
283 ASSERT_EQ(expectedGreen, actualGreen)
284 << "Green channel mismatch at (" << row << ", " << col << ")";
285 ASSERT_EQ(expectedBlue, actualBlue)
286 << "Blue channel mismatch at (" << row << ", " << col << ")";
287 }
ramindanibab8ba92021-11-18 01:24:11 +0000288 }
289 }
290}
291
Alec Mourif6c039a2023-10-06 23:02:17 +0000292void ReadbackHelper::compareColorBuffers(void* expectedBuffer, void* actualBuffer,
Alec Mouri6a000222024-08-16 23:08:09 +0000293 const uint32_t stride, int32_t bytesPerPixel,
294 const uint32_t width, const uint32_t height,
295 common::PixelFormat pixelFormat) {
296 int32_t bitsPerChannel = GetBitsPerChannel(pixelFormat);
297 int32_t alphaBits = GetAlphaBits(pixelFormat);
298 ASSERT_GT(bytesPerPixel, 0);
299 ASSERT_NE(-1, alphaBits);
300 ASSERT_NE(-1, bitsPerChannel);
301 uint32_t maxValue = (1 << bitsPerChannel) - 1;
302 uint32_t maxAlphaValue = (1 << alphaBits) - 1;
303 for (uint32_t row = 0; row < height; row++) {
304 for (uint32_t col = 0; col < width; col++) {
305 uint32_t offset = (row * stride + col) * static_cast<uint32_t>(bytesPerPixel);
306 uint32_t* expectedStart = (uint32_t*)((uint8_t*)expectedBuffer + offset);
307 uint32_t* actualStart = (uint32_t*)((uint8_t*)actualBuffer + offset);
308
309 // Boo we're not word aligned so special case this.
310 if (pixelFormat == common::PixelFormat::RGB_888) {
311 uint8_t* expectedPixel = (uint8_t*)expectedStart;
312 uint8_t* actualPixel = (uint8_t*)actualStart;
313 ASSERT_EQ(actualPixel[0], expectedPixel[0])
314 << "Red channel mismatch at (" << row << ", " << col << ")";
315 ASSERT_EQ(actualPixel[1], expectedPixel[1])
316 << "Green channel mismatch at (" << row << ", " << col << ")";
317 ASSERT_EQ(actualPixel[2], expectedPixel[2])
318 << "Blue channel mismatch at (" << row << ", " << col << ")";
319 } else {
320 uint32_t expectedRed =
321 (*expectedStart >> (32 - alphaBits - bitsPerChannel * 3)) & maxValue;
322 uint32_t expectedGreen =
323 (*expectedStart >> (32 - alphaBits - bitsPerChannel * 2)) & maxValue;
324 uint32_t expectedBlue =
325 (*expectedStart >> (32 - alphaBits - bitsPerChannel)) & maxValue;
326 uint32_t expectedAlpha = (*expectedStart >> (32 - alphaBits)) & maxAlphaValue;
327
328 uint32_t actualRed =
329 (*actualStart >> (32 - alphaBits - bitsPerChannel * 3)) & maxValue;
330 uint32_t actualGreen =
331 (*actualStart >> (32 - alphaBits - bitsPerChannel * 2)) & maxValue;
332 uint32_t actualBlue =
333 (*actualStart >> (32 - alphaBits - bitsPerChannel)) & maxValue;
334 uint32_t actualAlpha = (*actualStart >> (32 - alphaBits)) & maxAlphaValue;
335
336 ASSERT_EQ(expectedRed, actualRed)
337 << "Red channel mismatch at (" << row << ", " << col << ")";
338 ASSERT_EQ(expectedGreen, actualGreen)
339 << "Green channel mismatch at (" << row << ", " << col << ")";
340 ASSERT_EQ(expectedBlue, actualBlue)
341 << "Blue channel mismatch at (" << row << ", " << col << ")";
342 }
Alec Mourif6c039a2023-10-06 23:02:17 +0000343 }
344 }
345}
346
ramindanidcecfd42022-02-03 23:52:19 +0000347ReadbackBuffer::ReadbackBuffer(int64_t display, const std::shared_ptr<VtsComposerClient>& client,
Brian Lindahle887a252023-01-17 14:54:19 -0700348 int32_t width, int32_t height, common::PixelFormat pixelFormat,
349 common::Dataspace dataspace)
ramindanidcecfd42022-02-03 23:52:19 +0000350 : mComposerClient(client) {
ramindanibab8ba92021-11-18 01:24:11 +0000351 mDisplay = display;
Brian Lindahle887a252023-01-17 14:54:19 -0700352
353 mPixelFormat = pixelFormat;
354 mDataspace = dataspace;
355
ramindanibab8ba92021-11-18 01:24:11 +0000356 mWidth = static_cast<uint32_t>(width);
357 mHeight = static_cast<uint32_t>(height);
358 mLayerCount = 1;
359 mUsage = static_cast<uint64_t>(static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
360 static_cast<uint64_t>(common::BufferUsage::GPU_TEXTURE));
Brian Lindahle887a252023-01-17 14:54:19 -0700361
362 mAccessRegion.top = 0;
363 mAccessRegion.left = 0;
364 mAccessRegion.right = static_cast<int32_t>(width);
365 mAccessRegion.bottom = static_cast<int32_t>(height);
366}
367
368::android::sp<::android::GraphicBuffer> ReadbackBuffer::allocateBuffer() {
369 return ::android::sp<::android::GraphicBuffer>::make(
370 mWidth, mHeight, static_cast<::android::PixelFormat>(mPixelFormat), mLayerCount, mUsage,
371 "ReadbackBuffer");
ramindanibab8ba92021-11-18 01:24:11 +0000372}
373
374void ReadbackBuffer::setReadbackBuffer() {
Brian Lindahle887a252023-01-17 14:54:19 -0700375 mGraphicBuffer = allocateBuffer();
ramindanibab8ba92021-11-18 01:24:11 +0000376 ASSERT_NE(nullptr, mGraphicBuffer);
377 ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
Brian Lindahle887a252023-01-17 14:54:19 -0700378 const auto& bufferHandle = mGraphicBuffer->handle;
379 ::ndk::ScopedFileDescriptor fence = ::ndk::ScopedFileDescriptor(-1);
380 EXPECT_TRUE(mComposerClient->setReadbackBuffer(mDisplay, bufferHandle, fence).isOk());
ramindanibab8ba92021-11-18 01:24:11 +0000381}
382
ramindanidcecfd42022-02-03 23:52:19 +0000383void ReadbackBuffer::checkReadbackBuffer(const std::vector<Color>& expectedColors) {
Brian Lindahle887a252023-01-17 14:54:19 -0700384 ASSERT_NE(nullptr, mGraphicBuffer);
ramindanibab8ba92021-11-18 01:24:11 +0000385 // lock buffer for reading
ramindanidcecfd42022-02-03 23:52:19 +0000386 const auto& [fenceStatus, bufferFence] = mComposerClient->getReadbackBufferFence(mDisplay);
Brian Lindahle887a252023-01-17 14:54:19 -0700387 EXPECT_TRUE(fenceStatus.isOk());
388
389 int bytesPerPixel = -1;
390 int bytesPerStride = -1;
391 void* bufData = nullptr;
392
393 auto status = mGraphicBuffer->lockAsync(mUsage, mAccessRegion, &bufData, dup(bufferFence.get()),
394 &bytesPerPixel, &bytesPerStride);
395 EXPECT_EQ(::android::OK, status);
Alec Mouri6a000222024-08-16 23:08:09 +0000396 ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888 ||
397 mPixelFormat == PixelFormat::RGBA_1010102);
Brian Lindahle887a252023-01-17 14:54:19 -0700398 const uint32_t stride = (bytesPerPixel > 0 && bytesPerStride > 0)
399 ? static_cast<uint32_t>(bytesPerStride / bytesPerPixel)
400 : mGraphicBuffer->getStride();
Alec Mouri6a000222024-08-16 23:08:09 +0000401 ReadbackHelper::compareColorBuffers(expectedColors, bufData, stride, bytesPerPixel, mWidth,
402 mHeight, mPixelFormat);
Brian Lindahle887a252023-01-17 14:54:19 -0700403 status = mGraphicBuffer->unlock();
404 EXPECT_EQ(::android::OK, status);
ramindanibab8ba92021-11-18 01:24:11 +0000405}
406
Alec Mourif6c039a2023-10-06 23:02:17 +0000407::android::sp<::android::GraphicBuffer> ReadbackBuffer::getBuffer() {
408 const auto& [fenceStatus, bufferFence] = mComposerClient->getReadbackBufferFence(mDisplay);
409 EXPECT_TRUE(fenceStatus.isOk());
410 if (bufferFence.get() != -1) {
411 sync_wait(bufferFence.get(), -1);
412 }
413 return mGraphicBuffer;
414}
415
Ady Abraham91c9d1a2021-12-15 18:14:45 -0800416void TestColorLayer::write(ComposerClientWriter& writer) {
ramindanibab8ba92021-11-18 01:24:11 +0000417 TestLayer::write(writer);
Ady Abraham3192f3d2021-12-03 16:08:56 -0800418 writer.setLayerCompositionType(mDisplay, mLayer, Composition::SOLID_COLOR);
419 writer.setLayerColor(mDisplay, mLayer, mColor);
ramindanibab8ba92021-11-18 01:24:11 +0000420}
421
422LayerSettings TestColorLayer::toRenderEngineLayerSettings() {
423 LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
424
Ady Abraham1bee7ab2022-01-06 17:22:08 -0800425 layerSettings.source.solidColor = ::android::half3(mColor.r, mColor.g, mColor.b);
426 layerSettings.alpha = mAlpha * mColor.a;
ramindanibab8ba92021-11-18 01:24:11 +0000427 return layerSettings;
428}
429
ramindanidcecfd42022-02-03 23:52:19 +0000430TestBufferLayer::TestBufferLayer(const std::shared_ptr<VtsComposerClient>& client,
Ady Abraham4aa4ead2021-12-03 16:07:19 -0800431 TestRenderEngine& renderEngine, int64_t display, uint32_t width,
ramindanibab8ba92021-11-18 01:24:11 +0000432 uint32_t height, common::PixelFormat format,
Ady Abrahama00d2462023-12-26 14:21:20 -0800433 ComposerClientWriter& writer, Composition composition)
434 : TestLayer{client, display, writer}, mRenderEngine(renderEngine) {
ramindanibab8ba92021-11-18 01:24:11 +0000435 mComposition = composition;
436 mWidth = width;
437 mHeight = height;
438 mLayerCount = 1;
439 mPixelFormat = format;
440 mUsage = (static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
441 static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
442 static_cast<uint64_t>(common::BufferUsage::COMPOSER_OVERLAY) |
443 static_cast<uint64_t>(common::BufferUsage::GPU_TEXTURE));
444
445 mAccessRegion.top = 0;
446 mAccessRegion.left = 0;
447 mAccessRegion.right = static_cast<int32_t>(width);
448 mAccessRegion.bottom = static_cast<int32_t>(height);
449
450 setSourceCrop({0, 0, (float)width, (float)height});
451}
452
Ady Abraham91c9d1a2021-12-15 18:14:45 -0800453void TestBufferLayer::write(ComposerClientWriter& writer) {
ramindanibab8ba92021-11-18 01:24:11 +0000454 TestLayer::write(writer);
Ady Abraham3192f3d2021-12-03 16:08:56 -0800455 writer.setLayerCompositionType(mDisplay, mLayer, mComposition);
456 writer.setLayerVisibleRegion(mDisplay, mLayer, std::vector<Rect>(1, mDisplayFrame));
ramindani0a2bee42022-02-10 01:27:42 +0000457 if (mGraphicBuffer) {
458 writer.setLayerBuffer(mDisplay, mLayer, /*slot*/ 0, mGraphicBuffer->handle, mFillFence);
459 }
ramindanibab8ba92021-11-18 01:24:11 +0000460}
461
462LayerSettings TestBufferLayer::toRenderEngineLayerSettings() {
463 LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
Vishnu Nair59329712022-01-13 07:59:37 -0800464 layerSettings.source.buffer.buffer =
465 std::make_shared<::android::renderengine::impl::ExternalTexture>(
Alec Mouri3e037cf2022-01-24 08:58:28 -0800466 mGraphicBuffer, mRenderEngine.getInternalRenderEngine(),
Vishnu Nair59329712022-01-13 07:59:37 -0800467 ::android::renderengine::impl::ExternalTexture::Usage::READABLE);
ramindanibab8ba92021-11-18 01:24:11 +0000468
469 layerSettings.source.buffer.usePremultipliedAlpha = mBlendMode == BlendMode::PREMULTIPLIED;
470
471 const float scaleX = (mSourceCrop.right - mSourceCrop.left) / (static_cast<float>(mWidth));
472 const float scaleY = (mSourceCrop.bottom - mSourceCrop.top) / (static_cast<float>(mHeight));
473 const float translateX = mSourceCrop.left / (static_cast<float>(mWidth));
474 const float translateY = mSourceCrop.top / (static_cast<float>(mHeight));
475
476 layerSettings.source.buffer.textureTransform =
ramindanidcecfd42022-02-03 23:52:19 +0000477 ::android::mat4::translate(::android::vec4(translateX, translateY, 0.0f, 1.0f)) *
478 ::android::mat4::scale(::android::vec4(scaleX, scaleY, 1.0f, 1.0f));
ramindanibab8ba92021-11-18 01:24:11 +0000479
480 return layerSettings;
481}
482
483void TestBufferLayer::fillBuffer(std::vector<Color>& expectedColors) {
484 void* bufData;
Alec Mouri3e037cf2022-01-24 08:58:28 -0800485 int32_t bytesPerPixel = -1;
486 int32_t bytesPerStride = -1;
487 auto status = mGraphicBuffer->lock(mUsage, &bufData, &bytesPerPixel, &bytesPerStride);
488 const uint32_t stride = (bytesPerPixel > 0 && bytesPerStride > 0)
489 ? static_cast<uint32_t>(bytesPerStride / bytesPerPixel)
490 : mGraphicBuffer->getStride();
Brian Lindahle887a252023-01-17 14:54:19 -0700491 EXPECT_EQ(::android::OK, status);
Alec Mouri6a000222024-08-16 23:08:09 +0000492 ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(mWidth, mHeight, stride, bytesPerPixel,
493 bufData, mPixelFormat, expectedColors));
ramindani0a2bee42022-02-10 01:27:42 +0000494
495 const auto unlockStatus = mGraphicBuffer->unlockAsync(&mFillFence);
496 ASSERT_EQ(::android::OK, unlockStatus);
ramindanibab8ba92021-11-18 01:24:11 +0000497}
498
499void TestBufferLayer::setBuffer(std::vector<Color> colors) {
ramindani0a2bee42022-02-10 01:27:42 +0000500 mGraphicBuffer = allocateBuffer();
ramindanibab8ba92021-11-18 01:24:11 +0000501 ASSERT_NE(nullptr, mGraphicBuffer);
ramindanibab8ba92021-11-18 01:24:11 +0000502 ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
Brian Lindahle887a252023-01-17 14:54:19 -0700503 ASSERT_NO_FATAL_FAILURE(fillBuffer(colors));
ramindani0a2bee42022-02-10 01:27:42 +0000504}
505
Brian Lindahle887a252023-01-17 14:54:19 -0700506::android::sp<::android::GraphicBuffer> TestBufferLayer::allocateBuffer() {
507 return ::android::sp<::android::GraphicBuffer>::make(
508 mWidth, mHeight, static_cast<::android::PixelFormat>(mPixelFormat), mLayerCount, mUsage,
509 "TestBufferLayer");
ramindanibab8ba92021-11-18 01:24:11 +0000510}
511
Ady Abraham91c9d1a2021-12-15 18:14:45 -0800512void TestBufferLayer::setToClientComposition(ComposerClientWriter& writer) {
Ady Abraham3192f3d2021-12-03 16:08:56 -0800513 writer.setLayerCompositionType(mDisplay, mLayer, Composition::CLIENT);
ramindanibab8ba92021-11-18 01:24:11 +0000514}
515
Ady Abraham3192f3d2021-12-03 16:08:56 -0800516} // namespace aidl::android::hardware::graphics::composer3::vts