blob: 19f5e8c61429df9bee079a7c12e5b34c4524b5cc [file] [log] [blame]
Valerie Haub019fd72019-05-23 12:50:12 -07001/*
2 * Copyright 2019 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#include <composer-vts/2.2/ReadbackVts.h>
Alec Mouri2a6ef4e2021-04-16 16:36:21 +000018#include <composer-vts/2.2/RenderEngineVts.h>
19#include "renderengine/ExternalTexture.h"
Valerie Haub019fd72019-05-23 12:50:12 -070020
21namespace android {
22namespace hardware {
23namespace graphics {
24namespace composer {
25namespace V2_2 {
26namespace vts {
27
28void TestLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
29 writer->selectLayer(mLayer);
30 writer->setLayerDisplayFrame(mDisplayFrame);
31 writer->setLayerSourceCrop(mSourceCrop);
32 writer->setLayerZOrder(mZOrder);
33 writer->setLayerSurfaceDamage(mSurfaceDamage);
34 writer->setLayerTransform(mTransform);
35 writer->setLayerPlaneAlpha(mAlpha);
36 writer->setLayerBlendMode(mBlendMode);
37}
38
Valerie Hau7c8eb682019-06-12 14:24:27 -070039const std::vector<ColorMode> ReadbackHelper::colorModes = {ColorMode::SRGB, ColorMode::DISPLAY_P3};
40const std::vector<Dataspace> ReadbackHelper::dataspaces = {Dataspace::V0_SRGB,
41 Dataspace::DISPLAY_P3};
42
43std::string ReadbackHelper::getColorModeString(ColorMode mode) {
44 switch (mode) {
45 case ColorMode::SRGB:
46 return std::string("SRGB");
47 case ColorMode::DISPLAY_P3:
48 return std::string("DISPLAY_P3");
49 default:
50 return std::string("Unsupported color mode for readback");
51 }
52}
53
54std::string ReadbackHelper::getDataspaceString(Dataspace dataspace) {
55 switch (dataspace) {
56 case Dataspace::V0_SRGB:
57 return std::string("V0_SRGB");
58 case Dataspace::DISPLAY_P3:
59 return std::string("DISPLAY_P3");
Valerie Hau37edd052019-07-11 15:48:38 -070060 case Dataspace::UNKNOWN:
61 return std::string("UNKNOWN");
Valerie Hau7c8eb682019-06-12 14:24:27 -070062 default:
63 return std::string("Unsupported dataspace for readback");
64 }
65}
66
Valerie Hau37edd052019-07-11 15:48:38 -070067Dataspace ReadbackHelper::getDataspaceForColorMode(ColorMode mode) {
68 switch (mode) {
69 case ColorMode::DISPLAY_P3:
70 return Dataspace::DISPLAY_P3;
71 case ColorMode::SRGB:
72 default:
73 return Dataspace::UNKNOWN;
74 }
75}
76
Adam Bodnar5bf9dc62019-05-24 09:20:04 -070077LayerSettings TestLayer::toRenderEngineLayerSettings() {
78 LayerSettings layerSettings;
79
80 layerSettings.alpha = half(mAlpha);
81 layerSettings.disableBlending = mBlendMode == IComposerClient::BlendMode::NONE;
82 layerSettings.geometry.boundaries = FloatRect(
83 static_cast<float>(mDisplayFrame.left), static_cast<float>(mDisplayFrame.top),
84 static_cast<float>(mDisplayFrame.right), static_cast<float>(mDisplayFrame.bottom));
85
Adam Bodnard0aef4d2019-07-11 10:35:42 -070086 const mat4 translation = mat4::translate(
87 vec4((mTransform & Transform::FLIP_H ? -mDisplayFrame.right : 0.0f),
88 (mTransform & Transform::FLIP_V ? -mDisplayFrame.bottom : 0.0f), 0.0f, 1.0f));
Adam Bodnar5bf9dc62019-05-24 09:20:04 -070089
90 const mat4 scale = mat4::scale(vec4(mTransform & Transform::FLIP_H ? -1.0f : 1.0f,
91 mTransform & Transform::FLIP_V ? -1.0f : 1.0f, 1.0f, 1.0f));
92
Adam Bodnard0aef4d2019-07-11 10:35:42 -070093 layerSettings.geometry.positionTransform = scale * translation;
Adam Bodnar5bf9dc62019-05-24 09:20:04 -070094
95 return layerSettings;
96}
97
Valerie Haub019fd72019-05-23 12:50:12 -070098int32_t ReadbackHelper::GetBytesPerPixel(PixelFormat pixelFormat) {
99 switch (pixelFormat) {
100 case PixelFormat::RGBA_8888:
101 return 4;
102 case PixelFormat::RGB_888:
103 return 3;
104 default:
105 return -1;
106 }
107}
108
109void ReadbackHelper::fillBuffer(int32_t width, int32_t height, uint32_t stride, void* bufferData,
110 PixelFormat pixelFormat,
111 std::vector<IComposerClient::Color> desiredPixelColors) {
112 ASSERT_TRUE(pixelFormat == PixelFormat::RGB_888 || pixelFormat == PixelFormat::RGBA_8888);
113 int32_t bytesPerPixel = GetBytesPerPixel(pixelFormat);
114 ASSERT_NE(-1, bytesPerPixel);
115 for (int row = 0; row < height; row++) {
116 for (int col = 0; col < width; col++) {
117 int pixel = row * width + col;
118 IComposerClient::Color srcColor = desiredPixelColors[pixel];
119
120 int offset = (row * stride + col) * bytesPerPixel;
121 uint8_t* pixelColor = (uint8_t*)bufferData + offset;
122 pixelColor[0] = srcColor.r;
123 pixelColor[1] = srcColor.g;
124 pixelColor[2] = srcColor.b;
125
126 if (bytesPerPixel == 4) {
127 pixelColor[3] = srcColor.a;
128 }
129 }
130 }
131}
132
133void ReadbackHelper::clearColors(std::vector<IComposerClient::Color>& expectedColors, int32_t width,
134 int32_t height, int32_t displayWidth) {
135 for (int row = 0; row < height; row++) {
136 for (int col = 0; col < width; col++) {
137 int pixel = row * displayWidth + col;
138 expectedColors[pixel] = BLACK;
139 }
140 }
141}
142
143void ReadbackHelper::fillColorsArea(std::vector<IComposerClient::Color>& expectedColors,
144 int32_t stride, IComposerClient::Rect area,
145 IComposerClient::Color color) {
146 for (int row = area.top; row < area.bottom; row++) {
147 for (int col = area.left; col < area.right; col++) {
148 int pixel = row * stride + col;
149 expectedColors[pixel] = color;
150 }
151 }
152}
153
154bool ReadbackHelper::readbackSupported(const PixelFormat& pixelFormat, const Dataspace& dataspace,
155 const Error error) {
156 if (error != Error::NONE) {
157 return false;
158 }
159 // TODO: add support for RGBA_1010102
160 if (pixelFormat != PixelFormat::RGB_888 && pixelFormat != PixelFormat::RGBA_8888) {
161 return false;
162 }
Valerie Hau7c8eb682019-06-12 14:24:27 -0700163 if (std::find(dataspaces.begin(), dataspaces.end(), dataspace) == dataspaces.end()) {
Valerie Haub019fd72019-05-23 12:50:12 -0700164 return false;
165 }
166 return true;
167}
168
Adam Bodnar5bf9dc62019-05-24 09:20:04 -0700169void ReadbackHelper::compareColorBuffers(std::vector<IComposerClient::Color>& expectedColors,
170 void* bufferData, const uint32_t stride,
171 const uint32_t width, const uint32_t height,
172 const PixelFormat pixelFormat) {
173 const int32_t bytesPerPixel = ReadbackHelper::GetBytesPerPixel(pixelFormat);
174 ASSERT_NE(-1, bytesPerPixel);
175 for (int row = 0; row < height; row++) {
176 for (int col = 0; col < width; col++) {
177 int pixel = row * width + col;
178 int offset = (row * stride + col) * bytesPerPixel;
179 uint8_t* pixelColor = (uint8_t*)bufferData + offset;
180
181 ASSERT_EQ(expectedColors[pixel].r, pixelColor[0]);
182 ASSERT_EQ(expectedColors[pixel].g, pixelColor[1]);
183 ASSERT_EQ(expectedColors[pixel].b, pixelColor[2]);
184 }
185 }
186}
187
Valerie Haub019fd72019-05-23 12:50:12 -0700188ReadbackBuffer::ReadbackBuffer(Display display, const std::shared_ptr<ComposerClient>& client,
189 const std::shared_ptr<Gralloc>& gralloc, uint32_t width,
190 uint32_t height, PixelFormat pixelFormat, Dataspace dataspace) {
191 mDisplay = display;
192
193 mComposerClient = client;
194 mGralloc = gralloc;
195
196 mPixelFormat = pixelFormat;
197 mDataspace = dataspace;
198
Valerie Hauc1dc3132019-06-13 09:49:44 -0700199 mWidth = width;
200 mHeight = height;
201 mLayerCount = 1;
202 mFormat = mPixelFormat;
203 mUsage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::GPU_TEXTURE);
Valerie Haub019fd72019-05-23 12:50:12 -0700204
205 mAccessRegion.top = 0;
206 mAccessRegion.left = 0;
207 mAccessRegion.width = width;
208 mAccessRegion.height = height;
209}
210
211ReadbackBuffer::~ReadbackBuffer() {
212 if (mBufferHandle != nullptr) {
213 mGralloc->freeBuffer(mBufferHandle);
214 }
215}
216
217void ReadbackBuffer::setReadbackBuffer() {
218 if (mBufferHandle != nullptr) {
219 mGralloc->freeBuffer(mBufferHandle);
220 mBufferHandle = nullptr;
221 }
Valerie Hauc1dc3132019-06-13 09:49:44 -0700222 mBufferHandle = mGralloc->allocate(mWidth, mHeight, mLayerCount, mFormat, mUsage,
223 /*import*/ true, &mStride);
224 ASSERT_NE(false, mGralloc->validateBufferSize(mBufferHandle, mWidth, mHeight, mLayerCount,
225 mFormat, mUsage, mStride));
Valerie Haub019fd72019-05-23 12:50:12 -0700226 ASSERT_NO_FATAL_FAILURE(mComposerClient->setReadbackBuffer(mDisplay, mBufferHandle, -1));
227}
228
229void ReadbackBuffer::checkReadbackBuffer(std::vector<IComposerClient::Color> expectedColors) {
230 // lock buffer for reading
231 int32_t fenceHandle;
232 ASSERT_NO_FATAL_FAILURE(mComposerClient->getReadbackBufferFence(mDisplay, &fenceHandle));
233
Valerie Hauc1dc3132019-06-13 09:49:44 -0700234 void* bufData = mGralloc->lock(mBufferHandle, mUsage, mAccessRegion, fenceHandle);
Valerie Haub019fd72019-05-23 12:50:12 -0700235 ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888);
Adam Bodnar5bf9dc62019-05-24 09:20:04 -0700236 ReadbackHelper::compareColorBuffers(expectedColors, bufData, mStride, mWidth, mHeight,
237 mPixelFormat);
Valerie Haub019fd72019-05-23 12:50:12 -0700238 int32_t unlockFence = mGralloc->unlock(mBufferHandle);
239 if (unlockFence != -1) {
240 sync_wait(unlockFence, -1);
241 close(unlockFence);
242 }
243}
244
245void TestColorLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
246 TestLayer::write(writer);
247 writer->setLayerCompositionType(IComposerClient::Composition::SOLID_COLOR);
248 writer->setLayerColor(mColor);
249}
250
Adam Bodnar5bf9dc62019-05-24 09:20:04 -0700251LayerSettings TestColorLayer::toRenderEngineLayerSettings() {
252 LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
253
254 layerSettings.source.solidColor =
255 half3(static_cast<half>(mColor.r) / 255.0, static_cast<half>(mColor.g) / 255.0,
256 static_cast<half>(mColor.b) / 255.0);
257 layerSettings.alpha = mAlpha * (static_cast<half>(mColor.a) / 255.0);
258 return layerSettings;
259}
260
Valerie Haub019fd72019-05-23 12:50:12 -0700261TestBufferLayer::TestBufferLayer(const std::shared_ptr<ComposerClient>& client,
Alec Mouri2a6ef4e2021-04-16 16:36:21 +0000262 const std::shared_ptr<Gralloc>& gralloc,
263 TestRenderEngine& renderEngine, Display display, int32_t width,
264 int32_t height, PixelFormat format,
Valerie Haub019fd72019-05-23 12:50:12 -0700265 IComposerClient::Composition composition)
Alec Mouri2a6ef4e2021-04-16 16:36:21 +0000266 : TestLayer{client, display}, mRenderEngine(renderEngine) {
Valerie Haub019fd72019-05-23 12:50:12 -0700267 mGralloc = gralloc;
268 mComposition = composition;
Valerie Hauc1dc3132019-06-13 09:49:44 -0700269 mWidth = width;
270 mHeight = height;
271 mLayerCount = 1;
272 mFormat = format;
273 mUsage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
Ady Abraham203bdee2021-03-16 23:59:45 +0000274 BufferUsage::COMPOSER_OVERLAY | BufferUsage::GPU_TEXTURE);
Valerie Haub019fd72019-05-23 12:50:12 -0700275
276 mAccessRegion.top = 0;
277 mAccessRegion.left = 0;
278 mAccessRegion.width = width;
279 mAccessRegion.height = height;
280
281 setSourceCrop({0, 0, (float)width, (float)height});
282}
283
284TestBufferLayer::~TestBufferLayer() {
285 if (mBufferHandle != nullptr) {
286 mGralloc->freeBuffer(mBufferHandle);
287 }
288}
289
290void TestBufferLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
291 TestLayer::write(writer);
292 writer->setLayerCompositionType(mComposition);
Valerie Haub019fd72019-05-23 12:50:12 -0700293 writer->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, mDisplayFrame));
294 if (mBufferHandle != nullptr) writer->setLayerBuffer(0, mBufferHandle, mFillFence);
295}
296
Adam Bodnar5bf9dc62019-05-24 09:20:04 -0700297LayerSettings TestBufferLayer::toRenderEngineLayerSettings() {
298 LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
Alec Mouri2a6ef4e2021-04-16 16:36:21 +0000299 layerSettings.source.buffer.buffer = std::make_shared<renderengine::ExternalTexture>(
Adam Bodnar5bf9dc62019-05-24 09:20:04 -0700300 new GraphicBuffer(mBufferHandle, GraphicBuffer::CLONE_HANDLE, mWidth, mHeight,
Alec Mouri2a6ef4e2021-04-16 16:36:21 +0000301 static_cast<int32_t>(mFormat), 1, mUsage, mStride),
302 mRenderEngine.getInternalRenderEngine(),
303 renderengine::ExternalTexture::Usage::READABLE);
Adam Bodnard0aef4d2019-07-11 10:35:42 -0700304
305 layerSettings.source.buffer.usePremultipliedAlpha =
306 mBlendMode == IComposerClient::BlendMode::PREMULTIPLIED;
Adam Bodnar5bf9dc62019-05-24 09:20:04 -0700307
308 const float scaleX = (mSourceCrop.right - mSourceCrop.left) / (mWidth);
309 const float scaleY = (mSourceCrop.bottom - mSourceCrop.top) / (mHeight);
310 const float translateX = mSourceCrop.left / (mWidth);
311 const float translateY = mSourceCrop.top / (mHeight);
312
313 layerSettings.source.buffer.textureTransform =
314 mat4::translate(vec4(translateX, translateY, 0, 1)) *
315 mat4::scale(vec4(scaleX, scaleY, 1.0, 1.0));
316
317 return layerSettings;
318}
319
Valerie Haub019fd72019-05-23 12:50:12 -0700320void TestBufferLayer::fillBuffer(std::vector<IComposerClient::Color> expectedColors) {
Valerie Hauc1dc3132019-06-13 09:49:44 -0700321 void* bufData = mGralloc->lock(mBufferHandle, mUsage, mAccessRegion, -1);
322 ASSERT_NO_FATAL_FAILURE(
323 ReadbackHelper::fillBuffer(mWidth, mHeight, mStride, bufData, mFormat, expectedColors));
Valerie Haub019fd72019-05-23 12:50:12 -0700324 mFillFence = mGralloc->unlock(mBufferHandle);
325 if (mFillFence != -1) {
326 sync_wait(mFillFence, -1);
327 close(mFillFence);
328 }
329}
Adam Bodnar5bf9dc62019-05-24 09:20:04 -0700330
Valerie Haub019fd72019-05-23 12:50:12 -0700331void TestBufferLayer::setBuffer(std::vector<IComposerClient::Color> colors) {
332 if (mBufferHandle != nullptr) {
333 mGralloc->freeBuffer(mBufferHandle);
334 mBufferHandle = nullptr;
335 }
Valerie Hauc1dc3132019-06-13 09:49:44 -0700336 mBufferHandle = mGralloc->allocate(mWidth, mHeight, mLayerCount, mFormat, mUsage,
337 /*import*/ true, &mStride);
Valerie Haub019fd72019-05-23 12:50:12 -0700338 ASSERT_NE(nullptr, mBufferHandle);
339 ASSERT_NO_FATAL_FAILURE(fillBuffer(colors));
Valerie Hauc1dc3132019-06-13 09:49:44 -0700340 ASSERT_NE(false, mGralloc->validateBufferSize(mBufferHandle, mWidth, mHeight, mLayerCount,
341 mFormat, mUsage, mStride));
Valerie Haub019fd72019-05-23 12:50:12 -0700342}
343
Valerie Hau92d12262019-07-22 10:18:34 -0700344void TestBufferLayer::setDataspace(Dataspace dataspace,
345 const std::shared_ptr<CommandWriterBase>& writer) {
346 writer->selectLayer(mLayer);
347 writer->setLayerDataspace(dataspace);
348}
349
Valerie Haub019fd72019-05-23 12:50:12 -0700350void TestBufferLayer::setToClientComposition(const std::shared_ptr<CommandWriterBase>& writer) {
351 writer->selectLayer(mLayer);
352 writer->setLayerCompositionType(IComposerClient::Composition::CLIENT);
353}
354
355} // namespace vts
356} // namespace V2_2
357} // namespace composer
358} // namespace graphics
359} // namespace hardware
360} // namespace android