blob: abb58e25dde0a2ad342785c6733fe13502b7b0d0 [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>
ramindani458e53e2022-02-23 17:30:16 +000019#include "RenderEngineVts.h"
ramindanibab8ba92021-11-18 01:24:11 +000020#include "renderengine/ExternalTexture.h"
Vishnu Nair59329712022-01-13 07:59:37 -080021#include "renderengine/impl/ExternalTexture.h"
ramindanibab8ba92021-11-18 01:24:11 +000022
ramindanibab8ba92021-11-18 01:24:11 +000023namespace aidl::android::hardware::graphics::composer3::vts {
24
25const std::vector<ColorMode> ReadbackHelper::colorModes = {ColorMode::SRGB, ColorMode::DISPLAY_P3};
26const std::vector<Dataspace> ReadbackHelper::dataspaces = {common::Dataspace::SRGB,
27 common::Dataspace::DISPLAY_P3};
28
Ady Abraham91c9d1a2021-12-15 18:14:45 -080029void TestLayer::write(ComposerClientWriter& writer) {
Ady Abraham3192f3d2021-12-03 16:08:56 -080030 writer.setLayerDisplayFrame(mDisplay, mLayer, mDisplayFrame);
31 writer.setLayerSourceCrop(mDisplay, mLayer, mSourceCrop);
32 writer.setLayerZOrder(mDisplay, mLayer, mZOrder);
33 writer.setLayerSurfaceDamage(mDisplay, mLayer, mSurfaceDamage);
34 writer.setLayerTransform(mDisplay, mLayer, mTransform);
35 writer.setLayerPlaneAlpha(mDisplay, mLayer, mAlpha);
36 writer.setLayerBlendMode(mDisplay, mLayer, mBlendMode);
Alec Mourib1f16722022-02-07 13:03:44 -080037 writer.setLayerBrightness(mDisplay, mLayer, mBrightness);
ramindanibab8ba92021-11-18 01:24:11 +000038}
39
40std::string ReadbackHelper::getColorModeString(ColorMode mode) {
41 switch (mode) {
42 case ColorMode::SRGB:
43 return {"SRGB"};
44 case ColorMode::DISPLAY_P3:
45 return {"DISPLAY_P3"};
46 default:
47 return {"Unsupported color mode for readback"};
48 }
49}
50
51std::string ReadbackHelper::getDataspaceString(common::Dataspace dataspace) {
52 switch (dataspace) {
53 case common::Dataspace::SRGB:
54 return {"SRGB"};
55 case common::Dataspace::DISPLAY_P3:
56 return {"DISPLAY_P3"};
57 case common::Dataspace::UNKNOWN:
58 return {"UNKNOWN"};
59 default:
60 return {"Unsupported dataspace for readback"};
61 }
62}
63
64Dataspace ReadbackHelper::getDataspaceForColorMode(ColorMode mode) {
65 switch (mode) {
66 case ColorMode::DISPLAY_P3:
67 return Dataspace::DISPLAY_P3;
68 case ColorMode::SRGB:
69 default:
70 return common::Dataspace::UNKNOWN;
71 }
72}
73
74LayerSettings TestLayer::toRenderEngineLayerSettings() {
75 LayerSettings layerSettings;
76
77 layerSettings.alpha = ::android::half(mAlpha);
78 layerSettings.disableBlending = mBlendMode == BlendMode::NONE;
ramindanic7585d92022-04-15 18:30:41 +000079 layerSettings.source.buffer.isOpaque = mBlendMode == BlendMode::NONE;
ramindanibab8ba92021-11-18 01:24:11 +000080 layerSettings.geometry.boundaries = ::android::FloatRect(
81 static_cast<float>(mDisplayFrame.left), static_cast<float>(mDisplayFrame.top),
82 static_cast<float>(mDisplayFrame.right), static_cast<float>(mDisplayFrame.bottom));
83
84 const ::android::mat4 translation = ::android::mat4::translate(::android::vec4(
85 (static_cast<uint64_t>(mTransform) & static_cast<uint64_t>(Transform::FLIP_H)
86 ? static_cast<float>(-mDisplayFrame.right)
87 : 0.0f),
88 (static_cast<uint64_t>(mTransform) & static_cast<uint64_t>(Transform::FLIP_V)
89 ? static_cast<float>(-mDisplayFrame.bottom)
90 : 0.0f),
91 0.0f, 1.0f));
92
93 const ::android::mat4 scale = ::android::mat4::scale(::android::vec4(
94 static_cast<uint64_t>(mTransform) & static_cast<uint64_t>(Transform::FLIP_H) ? -1.0f
95 : 1.0f,
96 static_cast<uint64_t>(mTransform) & static_cast<uint64_t>(Transform::FLIP_V) ? -1.0f
97 : 1.0f,
98 1.0f, 1.0f));
99
100 layerSettings.geometry.positionTransform = scale * translation;
Alec Mouri51067012022-01-06 17:28:39 -0800101 layerSettings.whitePointNits = mWhitePointNits;
ramindanibab8ba92021-11-18 01:24:11 +0000102
103 return layerSettings;
104}
105
106int32_t ReadbackHelper::GetBytesPerPixel(common::PixelFormat pixelFormat) {
107 switch (pixelFormat) {
108 case common::PixelFormat::RGBA_8888:
109 return 4;
110 case common::PixelFormat::RGB_888:
111 return 3;
112 default:
113 return -1;
114 }
115}
116
117void ReadbackHelper::fillBuffer(uint32_t width, uint32_t height, uint32_t stride, void* bufferData,
118 common::PixelFormat pixelFormat,
119 std::vector<Color> desiredPixelColors) {
120 ASSERT_TRUE(pixelFormat == common::PixelFormat::RGB_888 ||
121 pixelFormat == common::PixelFormat::RGBA_8888);
122 int32_t bytesPerPixel = GetBytesPerPixel(pixelFormat);
123 ASSERT_NE(-1, bytesPerPixel);
124 for (int row = 0; row < height; row++) {
125 for (int col = 0; col < width; col++) {
126 auto pixel = row * static_cast<int32_t>(width) + col;
127 Color srcColor = desiredPixelColors[static_cast<size_t>(pixel)];
128
129 int offset = (row * static_cast<int32_t>(stride) + col) * bytesPerPixel;
130 uint8_t* pixelColor = (uint8_t*)bufferData + offset;
Ady Abraham1bee7ab2022-01-06 17:22:08 -0800131 pixelColor[0] = static_cast<uint8_t>(std::round(255.0f * srcColor.r));
132 pixelColor[1] = static_cast<uint8_t>(std::round(255.0f * srcColor.g));
133 pixelColor[2] = static_cast<uint8_t>(std::round(255.0f * srcColor.b));
ramindanibab8ba92021-11-18 01:24:11 +0000134
135 if (bytesPerPixel == 4) {
Ady Abraham1bee7ab2022-01-06 17:22:08 -0800136 pixelColor[3] = static_cast<uint8_t>(std::round(255.0f * srcColor.a));
ramindanibab8ba92021-11-18 01:24:11 +0000137 }
138 }
139 }
140}
141
142void ReadbackHelper::clearColors(std::vector<Color>& expectedColors, int32_t width, int32_t height,
143 int32_t displayWidth) {
144 for (int row = 0; row < height; row++) {
145 for (int col = 0; col < width; col++) {
146 int pixel = row * displayWidth + col;
147 expectedColors[static_cast<size_t>(pixel)] = BLACK;
148 }
149 }
150}
151
152void ReadbackHelper::fillColorsArea(std::vector<Color>& expectedColors, int32_t stride, Rect area,
153 Color color) {
154 for (int row = area.top; row < area.bottom; row++) {
155 for (int col = area.left; col < area.right; col++) {
156 int pixel = row * stride + col;
157 expectedColors[static_cast<size_t>(pixel)] = color;
158 }
159 }
160}
161
162bool ReadbackHelper::readbackSupported(const common::PixelFormat& pixelFormat,
163 const common::Dataspace& dataspace) {
164 if (pixelFormat != common::PixelFormat::RGB_888 &&
165 pixelFormat != common::PixelFormat::RGBA_8888) {
166 return false;
167 }
168 if (std::find(dataspaces.begin(), dataspaces.end(), dataspace) == dataspaces.end()) {
169 return false;
170 }
171 return true;
172}
173
Alec Mouri3e037cf2022-01-24 08:58:28 -0800174void ReadbackHelper::compareColorBuffers(const std::vector<Color>& expectedColors, void* bufferData,
175 const uint32_t stride, const uint32_t width,
ramindanibab8ba92021-11-18 01:24:11 +0000176 const uint32_t height, common::PixelFormat pixelFormat) {
177 const int32_t bytesPerPixel = ReadbackHelper::GetBytesPerPixel(pixelFormat);
178 ASSERT_NE(-1, bytesPerPixel);
179 for (int row = 0; row < height; row++) {
180 for (int col = 0; col < width; col++) {
181 auto pixel = row * static_cast<int32_t>(width) + col;
Alec Mouri3e037cf2022-01-24 08:58:28 -0800182 int offset = (row * static_cast<int32_t>(stride) + col) * bytesPerPixel;
ramindanibab8ba92021-11-18 01:24:11 +0000183 uint8_t* pixelColor = (uint8_t*)bufferData + offset;
Ady Abraham1bee7ab2022-01-06 17:22:08 -0800184 const Color expectedColor = expectedColors[static_cast<size_t>(pixel)];
Ady Abraham1bee7ab2022-01-06 17:22:08 -0800185 ASSERT_EQ(std::round(255.0f * expectedColor.r), pixelColor[0]);
186 ASSERT_EQ(std::round(255.0f * expectedColor.g), pixelColor[1]);
187 ASSERT_EQ(std::round(255.0f * expectedColor.b), pixelColor[2]);
ramindanibab8ba92021-11-18 01:24:11 +0000188 }
189 }
190}
191
ramindanidcecfd42022-02-03 23:52:19 +0000192ReadbackBuffer::ReadbackBuffer(int64_t display, const std::shared_ptr<VtsComposerClient>& client,
ramindanibab8ba92021-11-18 01:24:11 +0000193 int32_t width, int32_t height, common::PixelFormat pixelFormat,
ramindanidcecfd42022-02-03 23:52:19 +0000194 common::Dataspace dataspace)
195 : mComposerClient(client) {
ramindanibab8ba92021-11-18 01:24:11 +0000196 mDisplay = display;
197
ramindanibab8ba92021-11-18 01:24:11 +0000198 mPixelFormat = pixelFormat;
199 mDataspace = dataspace;
200
201 mWidth = static_cast<uint32_t>(width);
202 mHeight = static_cast<uint32_t>(height);
203 mLayerCount = 1;
204 mUsage = static_cast<uint64_t>(static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
205 static_cast<uint64_t>(common::BufferUsage::GPU_TEXTURE));
206
207 mAccessRegion.top = 0;
208 mAccessRegion.left = 0;
209 mAccessRegion.right = static_cast<int32_t>(width);
210 mAccessRegion.bottom = static_cast<int32_t>(height);
211}
212
ramindani0a2bee42022-02-10 01:27:42 +0000213::android::sp<::android::GraphicBuffer> ReadbackBuffer::allocateBuffer() {
ramindanibab8ba92021-11-18 01:24:11 +0000214 return ::android::sp<::android::GraphicBuffer>::make(
215 mWidth, mHeight, static_cast<::android::PixelFormat>(mPixelFormat), mLayerCount, mUsage,
ramindani0a2bee42022-02-10 01:27:42 +0000216 "ReadbackBuffer");
ramindanibab8ba92021-11-18 01:24:11 +0000217}
218
219void ReadbackBuffer::setReadbackBuffer() {
ramindani0a2bee42022-02-10 01:27:42 +0000220 mGraphicBuffer = allocateBuffer();
ramindanibab8ba92021-11-18 01:24:11 +0000221 ASSERT_NE(nullptr, mGraphicBuffer);
222 ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
ramindanidcecfd42022-02-03 23:52:19 +0000223 const auto& bufferHandle = mGraphicBuffer->handle;
ramindanibab8ba92021-11-18 01:24:11 +0000224 ::ndk::ScopedFileDescriptor fence = ::ndk::ScopedFileDescriptor(-1);
225 EXPECT_TRUE(mComposerClient->setReadbackBuffer(mDisplay, bufferHandle, fence).isOk());
226}
227
ramindanidcecfd42022-02-03 23:52:19 +0000228void ReadbackBuffer::checkReadbackBuffer(const std::vector<Color>& expectedColors) {
Alec Mouri7b4d5ee2022-01-20 12:10:39 -0800229 ASSERT_NE(nullptr, mGraphicBuffer);
ramindanibab8ba92021-11-18 01:24:11 +0000230 // lock buffer for reading
ramindanidcecfd42022-02-03 23:52:19 +0000231 const auto& [fenceStatus, bufferFence] = mComposerClient->getReadbackBufferFence(mDisplay);
232 EXPECT_TRUE(fenceStatus.isOk());
ramindanibab8ba92021-11-18 01:24:11 +0000233
Alec Mouri3e037cf2022-01-24 08:58:28 -0800234 int bytesPerPixel = -1;
235 int bytesPerStride = -1;
Ady Abraham435fd2f2021-12-23 16:22:44 -0800236 void* bufData = nullptr;
Alec Mouri7b4d5ee2022-01-20 12:10:39 -0800237
ramindanidcecfd42022-02-03 23:52:19 +0000238 auto status = mGraphicBuffer->lockAsync(mUsage, mAccessRegion, &bufData, dup(bufferFence.get()),
Alec Mouri3e037cf2022-01-24 08:58:28 -0800239 &bytesPerPixel, &bytesPerStride);
ramindanibab8ba92021-11-18 01:24:11 +0000240 EXPECT_EQ(::android::OK, status);
241 ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888);
Alec Mouri3e037cf2022-01-24 08:58:28 -0800242 const uint32_t stride = (bytesPerPixel > 0 && bytesPerStride > 0)
243 ? static_cast<uint32_t>(bytesPerStride / bytesPerPixel)
244 : mGraphicBuffer->getStride();
245 ReadbackHelper::compareColorBuffers(expectedColors, bufData, stride, mWidth, mHeight,
246 mPixelFormat);
ramindanibab8ba92021-11-18 01:24:11 +0000247 status = mGraphicBuffer->unlock();
248 EXPECT_EQ(::android::OK, status);
249}
250
Ady Abraham91c9d1a2021-12-15 18:14:45 -0800251void TestColorLayer::write(ComposerClientWriter& writer) {
ramindanibab8ba92021-11-18 01:24:11 +0000252 TestLayer::write(writer);
Ady Abraham3192f3d2021-12-03 16:08:56 -0800253 writer.setLayerCompositionType(mDisplay, mLayer, Composition::SOLID_COLOR);
254 writer.setLayerColor(mDisplay, mLayer, mColor);
ramindanibab8ba92021-11-18 01:24:11 +0000255}
256
257LayerSettings TestColorLayer::toRenderEngineLayerSettings() {
258 LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
259
Ady Abraham1bee7ab2022-01-06 17:22:08 -0800260 layerSettings.source.solidColor = ::android::half3(mColor.r, mColor.g, mColor.b);
261 layerSettings.alpha = mAlpha * mColor.a;
ramindanibab8ba92021-11-18 01:24:11 +0000262 return layerSettings;
263}
264
ramindanidcecfd42022-02-03 23:52:19 +0000265TestBufferLayer::TestBufferLayer(const std::shared_ptr<VtsComposerClient>& client,
Ady Abraham4aa4ead2021-12-03 16:07:19 -0800266 TestRenderEngine& renderEngine, int64_t display, uint32_t width,
ramindanibab8ba92021-11-18 01:24:11 +0000267 uint32_t height, common::PixelFormat format,
268 Composition composition)
269 : TestLayer{client, display}, mRenderEngine(renderEngine) {
ramindanibab8ba92021-11-18 01:24:11 +0000270 mComposition = composition;
271 mWidth = width;
272 mHeight = height;
273 mLayerCount = 1;
274 mPixelFormat = format;
275 mUsage = (static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
276 static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
277 static_cast<uint64_t>(common::BufferUsage::COMPOSER_OVERLAY) |
278 static_cast<uint64_t>(common::BufferUsage::GPU_TEXTURE));
279
280 mAccessRegion.top = 0;
281 mAccessRegion.left = 0;
282 mAccessRegion.right = static_cast<int32_t>(width);
283 mAccessRegion.bottom = static_cast<int32_t>(height);
284
285 setSourceCrop({0, 0, (float)width, (float)height});
286}
287
Ady Abraham91c9d1a2021-12-15 18:14:45 -0800288void TestBufferLayer::write(ComposerClientWriter& writer) {
ramindanibab8ba92021-11-18 01:24:11 +0000289 TestLayer::write(writer);
Ady Abraham3192f3d2021-12-03 16:08:56 -0800290 writer.setLayerCompositionType(mDisplay, mLayer, mComposition);
291 writer.setLayerVisibleRegion(mDisplay, mLayer, std::vector<Rect>(1, mDisplayFrame));
ramindani0a2bee42022-02-10 01:27:42 +0000292 if (mGraphicBuffer) {
293 writer.setLayerBuffer(mDisplay, mLayer, /*slot*/ 0, mGraphicBuffer->handle, mFillFence);
294 }
ramindanibab8ba92021-11-18 01:24:11 +0000295}
296
297LayerSettings TestBufferLayer::toRenderEngineLayerSettings() {
298 LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
Vishnu Nair59329712022-01-13 07:59:37 -0800299 layerSettings.source.buffer.buffer =
300 std::make_shared<::android::renderengine::impl::ExternalTexture>(
Alec Mouri3e037cf2022-01-24 08:58:28 -0800301 mGraphicBuffer, mRenderEngine.getInternalRenderEngine(),
Vishnu Nair59329712022-01-13 07:59:37 -0800302 ::android::renderengine::impl::ExternalTexture::Usage::READABLE);
ramindanibab8ba92021-11-18 01:24:11 +0000303
304 layerSettings.source.buffer.usePremultipliedAlpha = mBlendMode == BlendMode::PREMULTIPLIED;
305
306 const float scaleX = (mSourceCrop.right - mSourceCrop.left) / (static_cast<float>(mWidth));
307 const float scaleY = (mSourceCrop.bottom - mSourceCrop.top) / (static_cast<float>(mHeight));
308 const float translateX = mSourceCrop.left / (static_cast<float>(mWidth));
309 const float translateY = mSourceCrop.top / (static_cast<float>(mHeight));
310
311 layerSettings.source.buffer.textureTransform =
ramindanidcecfd42022-02-03 23:52:19 +0000312 ::android::mat4::translate(::android::vec4(translateX, translateY, 0.0f, 1.0f)) *
313 ::android::mat4::scale(::android::vec4(scaleX, scaleY, 1.0f, 1.0f));
ramindanibab8ba92021-11-18 01:24:11 +0000314
315 return layerSettings;
316}
317
318void TestBufferLayer::fillBuffer(std::vector<Color>& expectedColors) {
319 void* bufData;
Alec Mouri3e037cf2022-01-24 08:58:28 -0800320 int32_t bytesPerPixel = -1;
321 int32_t bytesPerStride = -1;
322 auto status = mGraphicBuffer->lock(mUsage, &bufData, &bytesPerPixel, &bytesPerStride);
323 const uint32_t stride = (bytesPerPixel > 0 && bytesPerStride > 0)
324 ? static_cast<uint32_t>(bytesPerStride / bytesPerPixel)
325 : mGraphicBuffer->getStride();
ramindanibab8ba92021-11-18 01:24:11 +0000326 EXPECT_EQ(::android::OK, status);
Alec Mouri3e037cf2022-01-24 08:58:28 -0800327 ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(mWidth, mHeight, stride, bufData,
ramindanibab8ba92021-11-18 01:24:11 +0000328 mPixelFormat, expectedColors));
ramindani0a2bee42022-02-10 01:27:42 +0000329
330 const auto unlockStatus = mGraphicBuffer->unlockAsync(&mFillFence);
331 ASSERT_EQ(::android::OK, unlockStatus);
ramindanibab8ba92021-11-18 01:24:11 +0000332}
333
334void TestBufferLayer::setBuffer(std::vector<Color> colors) {
ramindani0a2bee42022-02-10 01:27:42 +0000335 mGraphicBuffer = allocateBuffer();
ramindanibab8ba92021-11-18 01:24:11 +0000336 ASSERT_NE(nullptr, mGraphicBuffer);
ramindanibab8ba92021-11-18 01:24:11 +0000337 ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
ramindani0a2bee42022-02-10 01:27:42 +0000338 ASSERT_NO_FATAL_FAILURE(fillBuffer(colors));
339}
340
341::android::sp<::android::GraphicBuffer> TestBufferLayer::allocateBuffer() {
342 return ::android::sp<::android::GraphicBuffer>::make(
343 mWidth, mHeight, static_cast<::android::PixelFormat>(mPixelFormat), mLayerCount, mUsage,
344 "TestBufferLayer");
ramindanibab8ba92021-11-18 01:24:11 +0000345}
346
Ady Abraham91c9d1a2021-12-15 18:14:45 -0800347void TestBufferLayer::setDataspace(common::Dataspace dataspace, ComposerClientWriter& writer) {
Ady Abraham3192f3d2021-12-03 16:08:56 -0800348 writer.setLayerDataspace(mDisplay, mLayer, dataspace);
ramindanibab8ba92021-11-18 01:24:11 +0000349}
350
Ady Abraham91c9d1a2021-12-15 18:14:45 -0800351void TestBufferLayer::setToClientComposition(ComposerClientWriter& writer) {
Ady Abraham3192f3d2021-12-03 16:08:56 -0800352 writer.setLayerCompositionType(mDisplay, mLayer, Composition::CLIENT);
ramindanibab8ba92021-11-18 01:24:11 +0000353}
354
Ady Abraham3192f3d2021-12-03 16:08:56 -0800355} // namespace aidl::android::hardware::graphics::composer3::vts