blob: 91efc6ff07fe66ec18dc9dec093827034dcce823 [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>
18
19namespace android {
20namespace hardware {
21namespace graphics {
22namespace composer {
23namespace V2_2 {
24namespace vts {
25
26void TestLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
27 writer->selectLayer(mLayer);
28 writer->setLayerDisplayFrame(mDisplayFrame);
29 writer->setLayerSourceCrop(mSourceCrop);
30 writer->setLayerZOrder(mZOrder);
31 writer->setLayerSurfaceDamage(mSurfaceDamage);
32 writer->setLayerTransform(mTransform);
33 writer->setLayerPlaneAlpha(mAlpha);
34 writer->setLayerBlendMode(mBlendMode);
35}
36
Valerie Hau7c8eb682019-06-12 14:24:27 -070037const std::vector<ColorMode> ReadbackHelper::colorModes = {ColorMode::SRGB, ColorMode::DISPLAY_P3};
38const std::vector<Dataspace> ReadbackHelper::dataspaces = {Dataspace::V0_SRGB,
39 Dataspace::DISPLAY_P3};
40
41std::string ReadbackHelper::getColorModeString(ColorMode mode) {
42 switch (mode) {
43 case ColorMode::SRGB:
44 return std::string("SRGB");
45 case ColorMode::DISPLAY_P3:
46 return std::string("DISPLAY_P3");
47 default:
48 return std::string("Unsupported color mode for readback");
49 }
50}
51
52std::string ReadbackHelper::getDataspaceString(Dataspace dataspace) {
53 switch (dataspace) {
54 case Dataspace::V0_SRGB:
55 return std::string("V0_SRGB");
56 case Dataspace::DISPLAY_P3:
57 return std::string("DISPLAY_P3");
58 default:
59 return std::string("Unsupported dataspace for readback");
60 }
61}
62
Adam Bodnar5bf9dc62019-05-24 09:20:04 -070063LayerSettings TestLayer::toRenderEngineLayerSettings() {
64 LayerSettings layerSettings;
65
66 layerSettings.alpha = half(mAlpha);
67 layerSettings.disableBlending = mBlendMode == IComposerClient::BlendMode::NONE;
68 layerSettings.geometry.boundaries = FloatRect(
69 static_cast<float>(mDisplayFrame.left), static_cast<float>(mDisplayFrame.top),
70 static_cast<float>(mDisplayFrame.right), static_cast<float>(mDisplayFrame.bottom));
71
72 const mat4 translation = mat4::translate(vec4(
73 (mTransform & Transform::FLIP_H ? -1.0f : 0.0f) * mDisplayFrame.right,
74 (mTransform & Transform::FLIP_V ? -1.0f : 0.0f) * mDisplayFrame.bottom, 0.0f, 1.0f));
75
76 const mat4 scale = mat4::scale(vec4(mTransform & Transform::FLIP_H ? -1.0f : 1.0f,
77 mTransform & Transform::FLIP_V ? -1.0f : 1.0f, 1.0f, 1.0f));
78
79 layerSettings.geometry.positionTransform = translation * scale;
80
81 return layerSettings;
82}
83
Valerie Haub019fd72019-05-23 12:50:12 -070084int32_t ReadbackHelper::GetBytesPerPixel(PixelFormat pixelFormat) {
85 switch (pixelFormat) {
86 case PixelFormat::RGBA_8888:
87 return 4;
88 case PixelFormat::RGB_888:
89 return 3;
90 default:
91 return -1;
92 }
93}
94
95void ReadbackHelper::fillBuffer(int32_t width, int32_t height, uint32_t stride, void* bufferData,
96 PixelFormat pixelFormat,
97 std::vector<IComposerClient::Color> desiredPixelColors) {
98 ASSERT_TRUE(pixelFormat == PixelFormat::RGB_888 || pixelFormat == PixelFormat::RGBA_8888);
99 int32_t bytesPerPixel = GetBytesPerPixel(pixelFormat);
100 ASSERT_NE(-1, bytesPerPixel);
101 for (int row = 0; row < height; row++) {
102 for (int col = 0; col < width; col++) {
103 int pixel = row * width + col;
104 IComposerClient::Color srcColor = desiredPixelColors[pixel];
105
106 int offset = (row * stride + col) * bytesPerPixel;
107 uint8_t* pixelColor = (uint8_t*)bufferData + offset;
108 pixelColor[0] = srcColor.r;
109 pixelColor[1] = srcColor.g;
110 pixelColor[2] = srcColor.b;
111
112 if (bytesPerPixel == 4) {
113 pixelColor[3] = srcColor.a;
114 }
115 }
116 }
117}
118
119void ReadbackHelper::clearColors(std::vector<IComposerClient::Color>& expectedColors, int32_t width,
120 int32_t height, int32_t displayWidth) {
121 for (int row = 0; row < height; row++) {
122 for (int col = 0; col < width; col++) {
123 int pixel = row * displayWidth + col;
124 expectedColors[pixel] = BLACK;
125 }
126 }
127}
128
129void ReadbackHelper::fillColorsArea(std::vector<IComposerClient::Color>& expectedColors,
130 int32_t stride, IComposerClient::Rect area,
131 IComposerClient::Color color) {
132 for (int row = area.top; row < area.bottom; row++) {
133 for (int col = area.left; col < area.right; col++) {
134 int pixel = row * stride + col;
135 expectedColors[pixel] = color;
136 }
137 }
138}
139
140bool ReadbackHelper::readbackSupported(const PixelFormat& pixelFormat, const Dataspace& dataspace,
141 const Error error) {
142 if (error != Error::NONE) {
143 return false;
144 }
145 // TODO: add support for RGBA_1010102
146 if (pixelFormat != PixelFormat::RGB_888 && pixelFormat != PixelFormat::RGBA_8888) {
147 return false;
148 }
Valerie Hau7c8eb682019-06-12 14:24:27 -0700149 if (std::find(dataspaces.begin(), dataspaces.end(), dataspace) == dataspaces.end()) {
Valerie Haub019fd72019-05-23 12:50:12 -0700150 return false;
151 }
152 return true;
153}
154
Adam Bodnar5bf9dc62019-05-24 09:20:04 -0700155void ReadbackHelper::compareColorBuffers(std::vector<IComposerClient::Color>& expectedColors,
156 void* bufferData, const uint32_t stride,
157 const uint32_t width, const uint32_t height,
158 const PixelFormat pixelFormat) {
159 const int32_t bytesPerPixel = ReadbackHelper::GetBytesPerPixel(pixelFormat);
160 ASSERT_NE(-1, bytesPerPixel);
161 for (int row = 0; row < height; row++) {
162 for (int col = 0; col < width; col++) {
163 int pixel = row * width + col;
164 int offset = (row * stride + col) * bytesPerPixel;
165 uint8_t* pixelColor = (uint8_t*)bufferData + offset;
166
167 ASSERT_EQ(expectedColors[pixel].r, pixelColor[0]);
168 ASSERT_EQ(expectedColors[pixel].g, pixelColor[1]);
169 ASSERT_EQ(expectedColors[pixel].b, pixelColor[2]);
170 }
171 }
172}
173
Valerie Haub019fd72019-05-23 12:50:12 -0700174ReadbackBuffer::ReadbackBuffer(Display display, const std::shared_ptr<ComposerClient>& client,
175 const std::shared_ptr<Gralloc>& gralloc, uint32_t width,
176 uint32_t height, PixelFormat pixelFormat, Dataspace dataspace) {
177 mDisplay = display;
178
179 mComposerClient = client;
180 mGralloc = gralloc;
181
182 mPixelFormat = pixelFormat;
183 mDataspace = dataspace;
184
Valerie Hauc1dc3132019-06-13 09:49:44 -0700185 mWidth = width;
186 mHeight = height;
187 mLayerCount = 1;
188 mFormat = mPixelFormat;
189 mUsage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::GPU_TEXTURE);
Valerie Haub019fd72019-05-23 12:50:12 -0700190
191 mAccessRegion.top = 0;
192 mAccessRegion.left = 0;
193 mAccessRegion.width = width;
194 mAccessRegion.height = height;
195}
196
197ReadbackBuffer::~ReadbackBuffer() {
198 if (mBufferHandle != nullptr) {
199 mGralloc->freeBuffer(mBufferHandle);
200 }
201}
202
203void ReadbackBuffer::setReadbackBuffer() {
204 if (mBufferHandle != nullptr) {
205 mGralloc->freeBuffer(mBufferHandle);
206 mBufferHandle = nullptr;
207 }
Valerie Hauc1dc3132019-06-13 09:49:44 -0700208 mBufferHandle = mGralloc->allocate(mWidth, mHeight, mLayerCount, mFormat, mUsage,
209 /*import*/ true, &mStride);
210 ASSERT_NE(false, mGralloc->validateBufferSize(mBufferHandle, mWidth, mHeight, mLayerCount,
211 mFormat, mUsage, mStride));
Valerie Haub019fd72019-05-23 12:50:12 -0700212 ASSERT_NO_FATAL_FAILURE(mComposerClient->setReadbackBuffer(mDisplay, mBufferHandle, -1));
213}
214
215void ReadbackBuffer::checkReadbackBuffer(std::vector<IComposerClient::Color> expectedColors) {
216 // lock buffer for reading
217 int32_t fenceHandle;
218 ASSERT_NO_FATAL_FAILURE(mComposerClient->getReadbackBufferFence(mDisplay, &fenceHandle));
219
Valerie Hauc1dc3132019-06-13 09:49:44 -0700220 void* bufData = mGralloc->lock(mBufferHandle, mUsage, mAccessRegion, fenceHandle);
Valerie Haub019fd72019-05-23 12:50:12 -0700221 ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888);
Adam Bodnar5bf9dc62019-05-24 09:20:04 -0700222 ReadbackHelper::compareColorBuffers(expectedColors, bufData, mStride, mWidth, mHeight,
223 mPixelFormat);
Valerie Haub019fd72019-05-23 12:50:12 -0700224 int32_t unlockFence = mGralloc->unlock(mBufferHandle);
225 if (unlockFence != -1) {
226 sync_wait(unlockFence, -1);
227 close(unlockFence);
228 }
229}
230
231void TestColorLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
232 TestLayer::write(writer);
233 writer->setLayerCompositionType(IComposerClient::Composition::SOLID_COLOR);
234 writer->setLayerColor(mColor);
235}
236
Adam Bodnar5bf9dc62019-05-24 09:20:04 -0700237LayerSettings TestColorLayer::toRenderEngineLayerSettings() {
238 LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
239
240 layerSettings.source.solidColor =
241 half3(static_cast<half>(mColor.r) / 255.0, static_cast<half>(mColor.g) / 255.0,
242 static_cast<half>(mColor.b) / 255.0);
243 layerSettings.alpha = mAlpha * (static_cast<half>(mColor.a) / 255.0);
244 return layerSettings;
245}
246
Valerie Haub019fd72019-05-23 12:50:12 -0700247TestBufferLayer::TestBufferLayer(const std::shared_ptr<ComposerClient>& client,
248 const std::shared_ptr<Gralloc>& gralloc, Display display,
249 int32_t width, int32_t height, PixelFormat format,
250 IComposerClient::Composition composition)
251 : TestLayer{client, display} {
252 mGralloc = gralloc;
253 mComposition = composition;
Valerie Hauc1dc3132019-06-13 09:49:44 -0700254 mWidth = width;
255 mHeight = height;
256 mLayerCount = 1;
257 mFormat = format;
258 mUsage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
259 BufferUsage::COMPOSER_OVERLAY);
Valerie Haub019fd72019-05-23 12:50:12 -0700260
261 mAccessRegion.top = 0;
262 mAccessRegion.left = 0;
263 mAccessRegion.width = width;
264 mAccessRegion.height = height;
265
266 setSourceCrop({0, 0, (float)width, (float)height});
267}
268
269TestBufferLayer::~TestBufferLayer() {
270 if (mBufferHandle != nullptr) {
271 mGralloc->freeBuffer(mBufferHandle);
272 }
273}
274
275void TestBufferLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
276 TestLayer::write(writer);
277 writer->setLayerCompositionType(mComposition);
278 writer->setLayerDataspace(Dataspace::UNKNOWN);
279 writer->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, mDisplayFrame));
280 if (mBufferHandle != nullptr) writer->setLayerBuffer(0, mBufferHandle, mFillFence);
281}
282
Adam Bodnar5bf9dc62019-05-24 09:20:04 -0700283LayerSettings TestBufferLayer::toRenderEngineLayerSettings() {
284 LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
285 layerSettings.source.buffer.buffer =
286 new GraphicBuffer(mBufferHandle, GraphicBuffer::CLONE_HANDLE, mWidth, mHeight,
287 static_cast<int32_t>(mFormat), 1, mUsage, mStride);
288 // TODO(b/136483187): Why does this break the premultiply test
289 // layerSettings.source.buffer.usePremultipliedAlpha =
290 // mBlendMode == IComposerClient::BlendMode::PREMULTIPLIED;
291
292 const float scaleX = (mSourceCrop.right - mSourceCrop.left) / (mWidth);
293 const float scaleY = (mSourceCrop.bottom - mSourceCrop.top) / (mHeight);
294 const float translateX = mSourceCrop.left / (mWidth);
295 const float translateY = mSourceCrop.top / (mHeight);
296
297 layerSettings.source.buffer.textureTransform =
298 mat4::translate(vec4(translateX, translateY, 0, 1)) *
299 mat4::scale(vec4(scaleX, scaleY, 1.0, 1.0));
300
301 return layerSettings;
302}
303
Valerie Haub019fd72019-05-23 12:50:12 -0700304void TestBufferLayer::fillBuffer(std::vector<IComposerClient::Color> expectedColors) {
Valerie Hauc1dc3132019-06-13 09:49:44 -0700305 void* bufData = mGralloc->lock(mBufferHandle, mUsage, mAccessRegion, -1);
306 ASSERT_NO_FATAL_FAILURE(
307 ReadbackHelper::fillBuffer(mWidth, mHeight, mStride, bufData, mFormat, expectedColors));
Valerie Haub019fd72019-05-23 12:50:12 -0700308 mFillFence = mGralloc->unlock(mBufferHandle);
309 if (mFillFence != -1) {
310 sync_wait(mFillFence, -1);
311 close(mFillFence);
312 }
313}
Adam Bodnar5bf9dc62019-05-24 09:20:04 -0700314
Valerie Haub019fd72019-05-23 12:50:12 -0700315void TestBufferLayer::setBuffer(std::vector<IComposerClient::Color> colors) {
316 if (mBufferHandle != nullptr) {
317 mGralloc->freeBuffer(mBufferHandle);
318 mBufferHandle = nullptr;
319 }
Valerie Hauc1dc3132019-06-13 09:49:44 -0700320 mBufferHandle = mGralloc->allocate(mWidth, mHeight, mLayerCount, mFormat, mUsage,
321 /*import*/ true, &mStride);
Valerie Haub019fd72019-05-23 12:50:12 -0700322 ASSERT_NE(nullptr, mBufferHandle);
323 ASSERT_NO_FATAL_FAILURE(fillBuffer(colors));
Valerie Hauc1dc3132019-06-13 09:49:44 -0700324 ASSERT_NE(false, mGralloc->validateBufferSize(mBufferHandle, mWidth, mHeight, mLayerCount,
325 mFormat, mUsage, mStride));
Valerie Haub019fd72019-05-23 12:50:12 -0700326}
327
328void TestBufferLayer::setToClientComposition(const std::shared_ptr<CommandWriterBase>& writer) {
329 writer->selectLayer(mLayer);
330 writer->setLayerCompositionType(IComposerClient::Composition::CLIENT);
331}
332
333} // namespace vts
334} // namespace V2_2
335} // namespace composer
336} // namespace graphics
337} // namespace hardware
338} // namespace android