blob: 03b1b6ca12affe17ff7168ada8889444632526a6 [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;
79 layerSettings.geometry.boundaries = ::android::FloatRect(
80 static_cast<float>(mDisplayFrame.left), static_cast<float>(mDisplayFrame.top),
81 static_cast<float>(mDisplayFrame.right), static_cast<float>(mDisplayFrame.bottom));
82
83 const ::android::mat4 translation = ::android::mat4::translate(::android::vec4(
84 (static_cast<uint64_t>(mTransform) & static_cast<uint64_t>(Transform::FLIP_H)
85 ? static_cast<float>(-mDisplayFrame.right)
86 : 0.0f),
87 (static_cast<uint64_t>(mTransform) & static_cast<uint64_t>(Transform::FLIP_V)
88 ? static_cast<float>(-mDisplayFrame.bottom)
89 : 0.0f),
90 0.0f, 1.0f));
91
92 const ::android::mat4 scale = ::android::mat4::scale(::android::vec4(
93 static_cast<uint64_t>(mTransform) & static_cast<uint64_t>(Transform::FLIP_H) ? -1.0f
94 : 1.0f,
95 static_cast<uint64_t>(mTransform) & static_cast<uint64_t>(Transform::FLIP_V) ? -1.0f
96 : 1.0f,
97 1.0f, 1.0f));
98
99 layerSettings.geometry.positionTransform = scale * translation;
Alec Mouri51067012022-01-06 17:28:39 -0800100 layerSettings.whitePointNits = mWhitePointNits;
ramindanibab8ba92021-11-18 01:24:11 +0000101
102 return layerSettings;
103}
104
105int32_t ReadbackHelper::GetBytesPerPixel(common::PixelFormat pixelFormat) {
106 switch (pixelFormat) {
107 case common::PixelFormat::RGBA_8888:
108 return 4;
109 case common::PixelFormat::RGB_888:
110 return 3;
111 default:
112 return -1;
113 }
114}
115
116void ReadbackHelper::fillBuffer(uint32_t width, uint32_t height, uint32_t stride, void* bufferData,
117 common::PixelFormat pixelFormat,
118 std::vector<Color> desiredPixelColors) {
119 ASSERT_TRUE(pixelFormat == common::PixelFormat::RGB_888 ||
120 pixelFormat == common::PixelFormat::RGBA_8888);
121 int32_t bytesPerPixel = GetBytesPerPixel(pixelFormat);
122 ASSERT_NE(-1, bytesPerPixel);
123 for (int row = 0; row < height; row++) {
124 for (int col = 0; col < width; col++) {
125 auto pixel = row * static_cast<int32_t>(width) + col;
126 Color srcColor = desiredPixelColors[static_cast<size_t>(pixel)];
127
128 int offset = (row * static_cast<int32_t>(stride) + col) * bytesPerPixel;
129 uint8_t* pixelColor = (uint8_t*)bufferData + offset;
Ady Abraham1bee7ab2022-01-06 17:22:08 -0800130 pixelColor[0] = static_cast<uint8_t>(std::round(255.0f * srcColor.r));
131 pixelColor[1] = static_cast<uint8_t>(std::round(255.0f * srcColor.g));
132 pixelColor[2] = static_cast<uint8_t>(std::round(255.0f * srcColor.b));
ramindanibab8ba92021-11-18 01:24:11 +0000133
134 if (bytesPerPixel == 4) {
Ady Abraham1bee7ab2022-01-06 17:22:08 -0800135 pixelColor[3] = static_cast<uint8_t>(std::round(255.0f * srcColor.a));
ramindanibab8ba92021-11-18 01:24:11 +0000136 }
137 }
138 }
139}
140
141void ReadbackHelper::clearColors(std::vector<Color>& expectedColors, int32_t width, int32_t height,
142 int32_t displayWidth) {
143 for (int row = 0; row < height; row++) {
144 for (int col = 0; col < width; col++) {
145 int pixel = row * displayWidth + col;
146 expectedColors[static_cast<size_t>(pixel)] = BLACK;
147 }
148 }
149}
150
151void ReadbackHelper::fillColorsArea(std::vector<Color>& expectedColors, int32_t stride, Rect area,
152 Color color) {
153 for (int row = area.top; row < area.bottom; row++) {
154 for (int col = area.left; col < area.right; col++) {
155 int pixel = row * stride + col;
156 expectedColors[static_cast<size_t>(pixel)] = color;
157 }
158 }
159}
160
161bool ReadbackHelper::readbackSupported(const common::PixelFormat& pixelFormat,
162 const common::Dataspace& dataspace) {
163 if (pixelFormat != common::PixelFormat::RGB_888 &&
164 pixelFormat != common::PixelFormat::RGBA_8888) {
165 return false;
166 }
167 if (std::find(dataspaces.begin(), dataspaces.end(), dataspace) == dataspaces.end()) {
168 return false;
169 }
170 return true;
171}
172
Alec Mouri3e037cf2022-01-24 08:58:28 -0800173void ReadbackHelper::compareColorBuffers(const std::vector<Color>& expectedColors, void* bufferData,
174 const uint32_t stride, const uint32_t width,
ramindanibab8ba92021-11-18 01:24:11 +0000175 const uint32_t height, common::PixelFormat pixelFormat) {
176 const int32_t bytesPerPixel = ReadbackHelper::GetBytesPerPixel(pixelFormat);
177 ASSERT_NE(-1, bytesPerPixel);
178 for (int row = 0; row < height; row++) {
179 for (int col = 0; col < width; col++) {
180 auto pixel = row * static_cast<int32_t>(width) + col;
Alec Mouri3e037cf2022-01-24 08:58:28 -0800181 int offset = (row * static_cast<int32_t>(stride) + col) * bytesPerPixel;
ramindanibab8ba92021-11-18 01:24:11 +0000182 uint8_t* pixelColor = (uint8_t*)bufferData + offset;
Ady Abraham1bee7ab2022-01-06 17:22:08 -0800183 const Color expectedColor = expectedColors[static_cast<size_t>(pixel)];
Ady Abraham1bee7ab2022-01-06 17:22:08 -0800184 ASSERT_EQ(std::round(255.0f * expectedColor.r), pixelColor[0]);
185 ASSERT_EQ(std::round(255.0f * expectedColor.g), pixelColor[1]);
186 ASSERT_EQ(std::round(255.0f * expectedColor.b), pixelColor[2]);
ramindanibab8ba92021-11-18 01:24:11 +0000187 }
188 }
189}
190
ramindanidcecfd42022-02-03 23:52:19 +0000191ReadbackBuffer::ReadbackBuffer(int64_t display, const std::shared_ptr<VtsComposerClient>& client,
ramindanibab8ba92021-11-18 01:24:11 +0000192 int32_t width, int32_t height, common::PixelFormat pixelFormat,
ramindanidcecfd42022-02-03 23:52:19 +0000193 common::Dataspace dataspace)
194 : mComposerClient(client) {
ramindanibab8ba92021-11-18 01:24:11 +0000195 mDisplay = display;
196
ramindanibab8ba92021-11-18 01:24:11 +0000197 mPixelFormat = pixelFormat;
198 mDataspace = dataspace;
199
200 mWidth = static_cast<uint32_t>(width);
201 mHeight = static_cast<uint32_t>(height);
202 mLayerCount = 1;
203 mUsage = static_cast<uint64_t>(static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
204 static_cast<uint64_t>(common::BufferUsage::GPU_TEXTURE));
205
206 mAccessRegion.top = 0;
207 mAccessRegion.left = 0;
208 mAccessRegion.right = static_cast<int32_t>(width);
209 mAccessRegion.bottom = static_cast<int32_t>(height);
210}
211
ramindani0a2bee42022-02-10 01:27:42 +0000212::android::sp<::android::GraphicBuffer> ReadbackBuffer::allocateBuffer() {
ramindanibab8ba92021-11-18 01:24:11 +0000213 return ::android::sp<::android::GraphicBuffer>::make(
214 mWidth, mHeight, static_cast<::android::PixelFormat>(mPixelFormat), mLayerCount, mUsage,
ramindani0a2bee42022-02-10 01:27:42 +0000215 "ReadbackBuffer");
ramindanibab8ba92021-11-18 01:24:11 +0000216}
217
218void ReadbackBuffer::setReadbackBuffer() {
ramindani0a2bee42022-02-10 01:27:42 +0000219 mGraphicBuffer = allocateBuffer();
ramindanibab8ba92021-11-18 01:24:11 +0000220 ASSERT_NE(nullptr, mGraphicBuffer);
221 ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
ramindanidcecfd42022-02-03 23:52:19 +0000222 const auto& bufferHandle = mGraphicBuffer->handle;
ramindanibab8ba92021-11-18 01:24:11 +0000223 ::ndk::ScopedFileDescriptor fence = ::ndk::ScopedFileDescriptor(-1);
224 EXPECT_TRUE(mComposerClient->setReadbackBuffer(mDisplay, bufferHandle, fence).isOk());
225}
226
ramindanidcecfd42022-02-03 23:52:19 +0000227void ReadbackBuffer::checkReadbackBuffer(const std::vector<Color>& expectedColors) {
Alec Mouri7b4d5ee2022-01-20 12:10:39 -0800228 ASSERT_NE(nullptr, mGraphicBuffer);
ramindanibab8ba92021-11-18 01:24:11 +0000229 // lock buffer for reading
ramindanidcecfd42022-02-03 23:52:19 +0000230 const auto& [fenceStatus, bufferFence] = mComposerClient->getReadbackBufferFence(mDisplay);
231 EXPECT_TRUE(fenceStatus.isOk());
ramindanibab8ba92021-11-18 01:24:11 +0000232
Alec Mouri3e037cf2022-01-24 08:58:28 -0800233 int bytesPerPixel = -1;
234 int bytesPerStride = -1;
Ady Abraham435fd2f2021-12-23 16:22:44 -0800235 void* bufData = nullptr;
Alec Mouri7b4d5ee2022-01-20 12:10:39 -0800236
ramindanidcecfd42022-02-03 23:52:19 +0000237 auto status = mGraphicBuffer->lockAsync(mUsage, mAccessRegion, &bufData, dup(bufferFence.get()),
Alec Mouri3e037cf2022-01-24 08:58:28 -0800238 &bytesPerPixel, &bytesPerStride);
ramindanibab8ba92021-11-18 01:24:11 +0000239 EXPECT_EQ(::android::OK, status);
240 ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888);
Alec Mouri3e037cf2022-01-24 08:58:28 -0800241 const uint32_t stride = (bytesPerPixel > 0 && bytesPerStride > 0)
242 ? static_cast<uint32_t>(bytesPerStride / bytesPerPixel)
243 : mGraphicBuffer->getStride();
244 ReadbackHelper::compareColorBuffers(expectedColors, bufData, stride, mWidth, mHeight,
245 mPixelFormat);
ramindanibab8ba92021-11-18 01:24:11 +0000246 status = mGraphicBuffer->unlock();
247 EXPECT_EQ(::android::OK, status);
248}
249
Ady Abraham91c9d1a2021-12-15 18:14:45 -0800250void TestColorLayer::write(ComposerClientWriter& writer) {
ramindanibab8ba92021-11-18 01:24:11 +0000251 TestLayer::write(writer);
Ady Abraham3192f3d2021-12-03 16:08:56 -0800252 writer.setLayerCompositionType(mDisplay, mLayer, Composition::SOLID_COLOR);
253 writer.setLayerColor(mDisplay, mLayer, mColor);
ramindanibab8ba92021-11-18 01:24:11 +0000254}
255
256LayerSettings TestColorLayer::toRenderEngineLayerSettings() {
257 LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
258
Ady Abraham1bee7ab2022-01-06 17:22:08 -0800259 layerSettings.source.solidColor = ::android::half3(mColor.r, mColor.g, mColor.b);
260 layerSettings.alpha = mAlpha * mColor.a;
ramindanibab8ba92021-11-18 01:24:11 +0000261 return layerSettings;
262}
263
ramindanidcecfd42022-02-03 23:52:19 +0000264TestBufferLayer::TestBufferLayer(const std::shared_ptr<VtsComposerClient>& client,
Ady Abraham4aa4ead2021-12-03 16:07:19 -0800265 TestRenderEngine& renderEngine, int64_t display, uint32_t width,
ramindanibab8ba92021-11-18 01:24:11 +0000266 uint32_t height, common::PixelFormat format,
267 Composition composition)
268 : TestLayer{client, display}, mRenderEngine(renderEngine) {
ramindanibab8ba92021-11-18 01:24:11 +0000269 mComposition = composition;
270 mWidth = width;
271 mHeight = height;
272 mLayerCount = 1;
273 mPixelFormat = format;
274 mUsage = (static_cast<uint64_t>(common::BufferUsage::CPU_READ_OFTEN) |
275 static_cast<uint64_t>(common::BufferUsage::CPU_WRITE_OFTEN) |
276 static_cast<uint64_t>(common::BufferUsage::COMPOSER_OVERLAY) |
277 static_cast<uint64_t>(common::BufferUsage::GPU_TEXTURE));
278
279 mAccessRegion.top = 0;
280 mAccessRegion.left = 0;
281 mAccessRegion.right = static_cast<int32_t>(width);
282 mAccessRegion.bottom = static_cast<int32_t>(height);
283
284 setSourceCrop({0, 0, (float)width, (float)height});
285}
286
Ady Abraham91c9d1a2021-12-15 18:14:45 -0800287void TestBufferLayer::write(ComposerClientWriter& writer) {
ramindanibab8ba92021-11-18 01:24:11 +0000288 TestLayer::write(writer);
Ady Abraham3192f3d2021-12-03 16:08:56 -0800289 writer.setLayerCompositionType(mDisplay, mLayer, mComposition);
290 writer.setLayerVisibleRegion(mDisplay, mLayer, std::vector<Rect>(1, mDisplayFrame));
ramindani0a2bee42022-02-10 01:27:42 +0000291 if (mGraphicBuffer) {
292 writer.setLayerBuffer(mDisplay, mLayer, /*slot*/ 0, mGraphicBuffer->handle, mFillFence);
293 }
ramindanibab8ba92021-11-18 01:24:11 +0000294}
295
296LayerSettings TestBufferLayer::toRenderEngineLayerSettings() {
297 LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
Vishnu Nair59329712022-01-13 07:59:37 -0800298 layerSettings.source.buffer.buffer =
299 std::make_shared<::android::renderengine::impl::ExternalTexture>(
Alec Mouri3e037cf2022-01-24 08:58:28 -0800300 mGraphicBuffer, mRenderEngine.getInternalRenderEngine(),
Vishnu Nair59329712022-01-13 07:59:37 -0800301 ::android::renderengine::impl::ExternalTexture::Usage::READABLE);
ramindanibab8ba92021-11-18 01:24:11 +0000302
303 layerSettings.source.buffer.usePremultipliedAlpha = mBlendMode == BlendMode::PREMULTIPLIED;
304
305 const float scaleX = (mSourceCrop.right - mSourceCrop.left) / (static_cast<float>(mWidth));
306 const float scaleY = (mSourceCrop.bottom - mSourceCrop.top) / (static_cast<float>(mHeight));
307 const float translateX = mSourceCrop.left / (static_cast<float>(mWidth));
308 const float translateY = mSourceCrop.top / (static_cast<float>(mHeight));
309
310 layerSettings.source.buffer.textureTransform =
ramindanidcecfd42022-02-03 23:52:19 +0000311 ::android::mat4::translate(::android::vec4(translateX, translateY, 0.0f, 1.0f)) *
312 ::android::mat4::scale(::android::vec4(scaleX, scaleY, 1.0f, 1.0f));
ramindanibab8ba92021-11-18 01:24:11 +0000313
314 return layerSettings;
315}
316
317void TestBufferLayer::fillBuffer(std::vector<Color>& expectedColors) {
318 void* bufData;
Alec Mouri3e037cf2022-01-24 08:58:28 -0800319 int32_t bytesPerPixel = -1;
320 int32_t bytesPerStride = -1;
321 auto status = mGraphicBuffer->lock(mUsage, &bufData, &bytesPerPixel, &bytesPerStride);
322 const uint32_t stride = (bytesPerPixel > 0 && bytesPerStride > 0)
323 ? static_cast<uint32_t>(bytesPerStride / bytesPerPixel)
324 : mGraphicBuffer->getStride();
ramindanibab8ba92021-11-18 01:24:11 +0000325 EXPECT_EQ(::android::OK, status);
Alec Mouri3e037cf2022-01-24 08:58:28 -0800326 ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(mWidth, mHeight, stride, bufData,
ramindanibab8ba92021-11-18 01:24:11 +0000327 mPixelFormat, expectedColors));
ramindani0a2bee42022-02-10 01:27:42 +0000328
329 const auto unlockStatus = mGraphicBuffer->unlockAsync(&mFillFence);
330 ASSERT_EQ(::android::OK, unlockStatus);
ramindanibab8ba92021-11-18 01:24:11 +0000331}
332
333void TestBufferLayer::setBuffer(std::vector<Color> colors) {
ramindani0a2bee42022-02-10 01:27:42 +0000334 mGraphicBuffer = allocateBuffer();
ramindanibab8ba92021-11-18 01:24:11 +0000335 ASSERT_NE(nullptr, mGraphicBuffer);
ramindanibab8ba92021-11-18 01:24:11 +0000336 ASSERT_EQ(::android::OK, mGraphicBuffer->initCheck());
ramindani0a2bee42022-02-10 01:27:42 +0000337 ASSERT_NO_FATAL_FAILURE(fillBuffer(colors));
338}
339
340::android::sp<::android::GraphicBuffer> TestBufferLayer::allocateBuffer() {
341 return ::android::sp<::android::GraphicBuffer>::make(
342 mWidth, mHeight, static_cast<::android::PixelFormat>(mPixelFormat), mLayerCount, mUsage,
343 "TestBufferLayer");
ramindanibab8ba92021-11-18 01:24:11 +0000344}
345
Ady Abraham91c9d1a2021-12-15 18:14:45 -0800346void TestBufferLayer::setDataspace(common::Dataspace dataspace, ComposerClientWriter& writer) {
Ady Abraham3192f3d2021-12-03 16:08:56 -0800347 writer.setLayerDataspace(mDisplay, mLayer, dataspace);
ramindanibab8ba92021-11-18 01:24:11 +0000348}
349
Ady Abraham91c9d1a2021-12-15 18:14:45 -0800350void TestBufferLayer::setToClientComposition(ComposerClientWriter& writer) {
Ady Abraham3192f3d2021-12-03 16:08:56 -0800351 writer.setLayerCompositionType(mDisplay, mLayer, Composition::CLIENT);
ramindanibab8ba92021-11-18 01:24:11 +0000352}
353
Ady Abraham3192f3d2021-12-03 16:08:56 -0800354} // namespace aidl::android::hardware::graphics::composer3::vts