1 /*
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
19 namespace android {
20 namespace hardware {
21 namespace graphics {
22 namespace composer {
23 namespace V2_2 {
24 namespace vts {
25
write(const std::shared_ptr<CommandWriterBase> & writer)26 void 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
37 const std::vector<ColorMode> ReadbackHelper::colorModes = {ColorMode::SRGB, ColorMode::DISPLAY_P3};
38 const std::vector<Dataspace> ReadbackHelper::dataspaces = {Dataspace::V0_SRGB,
39 Dataspace::DISPLAY_P3};
40
getColorModeString(ColorMode mode)41 std::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
getDataspaceString(Dataspace dataspace)52 std::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 case Dataspace::UNKNOWN:
59 return std::string("UNKNOWN");
60 default:
61 return std::string("Unsupported dataspace for readback");
62 }
63 }
64
getDataspaceForColorMode(ColorMode mode)65 Dataspace ReadbackHelper::getDataspaceForColorMode(ColorMode mode) {
66 switch (mode) {
67 case ColorMode::DISPLAY_P3:
68 return Dataspace::DISPLAY_P3;
69 case ColorMode::SRGB:
70 default:
71 return Dataspace::UNKNOWN;
72 }
73 }
74
toRenderEngineLayerSettings()75 LayerSettings TestLayer::toRenderEngineLayerSettings() {
76 LayerSettings layerSettings;
77
78 layerSettings.alpha = half(mAlpha);
79 layerSettings.disableBlending = mBlendMode == IComposerClient::BlendMode::NONE;
80 layerSettings.geometry.boundaries = 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 mat4 translation = mat4::translate(
85 vec4((mTransform & Transform::FLIP_H ? -mDisplayFrame.right : 0.0f),
86 (mTransform & Transform::FLIP_V ? -mDisplayFrame.bottom : 0.0f), 0.0f, 1.0f));
87
88 const mat4 scale = mat4::scale(vec4(mTransform & Transform::FLIP_H ? -1.0f : 1.0f,
89 mTransform & Transform::FLIP_V ? -1.0f : 1.0f, 1.0f, 1.0f));
90
91 layerSettings.geometry.positionTransform = scale * translation;
92
93 return layerSettings;
94 }
95
GetBytesPerPixel(PixelFormat pixelFormat)96 int32_t ReadbackHelper::GetBytesPerPixel(PixelFormat pixelFormat) {
97 switch (pixelFormat) {
98 case PixelFormat::RGBA_8888:
99 return 4;
100 case PixelFormat::RGB_888:
101 return 3;
102 default:
103 return -1;
104 }
105 }
106
fillBuffer(int32_t width,int32_t height,uint32_t stride,void * bufferData,PixelFormat pixelFormat,std::vector<IComposerClient::Color> desiredPixelColors)107 void ReadbackHelper::fillBuffer(int32_t width, int32_t height, uint32_t stride, void* bufferData,
108 PixelFormat pixelFormat,
109 std::vector<IComposerClient::Color> desiredPixelColors) {
110 ASSERT_TRUE(pixelFormat == PixelFormat::RGB_888 || pixelFormat == PixelFormat::RGBA_8888);
111 int32_t bytesPerPixel = GetBytesPerPixel(pixelFormat);
112 ASSERT_NE(-1, bytesPerPixel);
113 for (int row = 0; row < height; row++) {
114 for (int col = 0; col < width; col++) {
115 int pixel = row * width + col;
116 IComposerClient::Color srcColor = desiredPixelColors[pixel];
117
118 int offset = (row * stride + col) * bytesPerPixel;
119 uint8_t* pixelColor = (uint8_t*)bufferData + offset;
120 pixelColor[0] = srcColor.r;
121 pixelColor[1] = srcColor.g;
122 pixelColor[2] = srcColor.b;
123
124 if (bytesPerPixel == 4) {
125 pixelColor[3] = srcColor.a;
126 }
127 }
128 }
129 }
130
clearColors(std::vector<IComposerClient::Color> & expectedColors,int32_t width,int32_t height,int32_t displayWidth)131 void ReadbackHelper::clearColors(std::vector<IComposerClient::Color>& expectedColors, int32_t width,
132 int32_t height, int32_t displayWidth) {
133 for (int row = 0; row < height; row++) {
134 for (int col = 0; col < width; col++) {
135 int pixel = row * displayWidth + col;
136 expectedColors[pixel] = BLACK;
137 }
138 }
139 }
140
fillColorsArea(std::vector<IComposerClient::Color> & expectedColors,int32_t stride,IComposerClient::Rect area,IComposerClient::Color color)141 void ReadbackHelper::fillColorsArea(std::vector<IComposerClient::Color>& expectedColors,
142 int32_t stride, IComposerClient::Rect area,
143 IComposerClient::Color color) {
144 for (int row = area.top; row < area.bottom; row++) {
145 for (int col = area.left; col < area.right; col++) {
146 int pixel = row * stride + col;
147 expectedColors[pixel] = color;
148 }
149 }
150 }
151
readbackSupported(const PixelFormat & pixelFormat,const Dataspace & dataspace,const Error error)152 bool ReadbackHelper::readbackSupported(const PixelFormat& pixelFormat, const Dataspace& dataspace,
153 const Error error) {
154 if (error != Error::NONE) {
155 return false;
156 }
157 // TODO: add support for RGBA_1010102
158 if (pixelFormat != PixelFormat::RGB_888 && pixelFormat != PixelFormat::RGBA_8888) {
159 return false;
160 }
161 if (std::find(dataspaces.begin(), dataspaces.end(), dataspace) == dataspaces.end()) {
162 return false;
163 }
164 return true;
165 }
166
compareColorBuffers(std::vector<IComposerClient::Color> & expectedColors,void * bufferData,const uint32_t stride,const uint32_t width,const uint32_t height,const PixelFormat pixelFormat)167 void ReadbackHelper::compareColorBuffers(std::vector<IComposerClient::Color>& expectedColors,
168 void* bufferData, const uint32_t stride,
169 const uint32_t width, const uint32_t height,
170 const PixelFormat pixelFormat) {
171 const int32_t bytesPerPixel = ReadbackHelper::GetBytesPerPixel(pixelFormat);
172 ASSERT_NE(-1, bytesPerPixel);
173 for (int row = 0; row < height; row++) {
174 for (int col = 0; col < width; col++) {
175 int pixel = row * width + col;
176 int offset = (row * stride + col) * bytesPerPixel;
177 uint8_t* pixelColor = (uint8_t*)bufferData + offset;
178
179 ASSERT_EQ(expectedColors[pixel].r, pixelColor[0]);
180 ASSERT_EQ(expectedColors[pixel].g, pixelColor[1]);
181 ASSERT_EQ(expectedColors[pixel].b, pixelColor[2]);
182 }
183 }
184 }
185
ReadbackBuffer(Display display,const std::shared_ptr<ComposerClient> & client,const std::shared_ptr<Gralloc> & gralloc,uint32_t width,uint32_t height,PixelFormat pixelFormat,Dataspace dataspace)186 ReadbackBuffer::ReadbackBuffer(Display display, const std::shared_ptr<ComposerClient>& client,
187 const std::shared_ptr<Gralloc>& gralloc, uint32_t width,
188 uint32_t height, PixelFormat pixelFormat, Dataspace dataspace) {
189 mDisplay = display;
190
191 mComposerClient = client;
192 mGralloc = gralloc;
193
194 mPixelFormat = pixelFormat;
195 mDataspace = dataspace;
196
197 mWidth = width;
198 mHeight = height;
199 mLayerCount = 1;
200 mFormat = mPixelFormat;
201 mUsage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::GPU_TEXTURE);
202
203 mAccessRegion.top = 0;
204 mAccessRegion.left = 0;
205 mAccessRegion.width = width;
206 mAccessRegion.height = height;
207 }
208
~ReadbackBuffer()209 ReadbackBuffer::~ReadbackBuffer() {
210 if (mBufferHandle != nullptr) {
211 mGralloc->freeBuffer(mBufferHandle);
212 }
213 }
214
setReadbackBuffer()215 void ReadbackBuffer::setReadbackBuffer() {
216 if (mBufferHandle != nullptr) {
217 mGralloc->freeBuffer(mBufferHandle);
218 mBufferHandle = nullptr;
219 }
220 mBufferHandle = mGralloc->allocate(mWidth, mHeight, mLayerCount, mFormat, mUsage,
221 /*import*/ true, &mStride);
222 ASSERT_NE(false, mGralloc->validateBufferSize(mBufferHandle, mWidth, mHeight, mLayerCount,
223 mFormat, mUsage, mStride));
224 ASSERT_NO_FATAL_FAILURE(mComposerClient->setReadbackBuffer(mDisplay, mBufferHandle, -1));
225 }
226
checkReadbackBuffer(std::vector<IComposerClient::Color> expectedColors)227 void ReadbackBuffer::checkReadbackBuffer(std::vector<IComposerClient::Color> expectedColors) {
228 // lock buffer for reading
229 int32_t fenceHandle;
230 ASSERT_NO_FATAL_FAILURE(mComposerClient->getReadbackBufferFence(mDisplay, &fenceHandle));
231
232 void* bufData = mGralloc->lock(mBufferHandle, mUsage, mAccessRegion, fenceHandle);
233 ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888);
234 ReadbackHelper::compareColorBuffers(expectedColors, bufData, mStride, mWidth, mHeight,
235 mPixelFormat);
236 int32_t unlockFence = mGralloc->unlock(mBufferHandle);
237 if (unlockFence != -1) {
238 sync_wait(unlockFence, -1);
239 close(unlockFence);
240 }
241 }
242
write(const std::shared_ptr<CommandWriterBase> & writer)243 void TestColorLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
244 TestLayer::write(writer);
245 writer->setLayerCompositionType(IComposerClient::Composition::SOLID_COLOR);
246 writer->setLayerColor(mColor);
247 }
248
toRenderEngineLayerSettings()249 LayerSettings TestColorLayer::toRenderEngineLayerSettings() {
250 LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
251
252 layerSettings.source.solidColor =
253 half3(static_cast<half>(mColor.r) / 255.0, static_cast<half>(mColor.g) / 255.0,
254 static_cast<half>(mColor.b) / 255.0);
255 layerSettings.alpha = mAlpha * (static_cast<half>(mColor.a) / 255.0);
256 return layerSettings;
257 }
258
TestBufferLayer(const std::shared_ptr<ComposerClient> & client,const std::shared_ptr<Gralloc> & gralloc,Display display,int32_t width,int32_t height,PixelFormat format,IComposerClient::Composition composition)259 TestBufferLayer::TestBufferLayer(const std::shared_ptr<ComposerClient>& client,
260 const std::shared_ptr<Gralloc>& gralloc, Display display,
261 int32_t width, int32_t height, PixelFormat format,
262 IComposerClient::Composition composition)
263 : TestLayer{client, display} {
264 mGralloc = gralloc;
265 mComposition = composition;
266 mWidth = width;
267 mHeight = height;
268 mLayerCount = 1;
269 mFormat = format;
270 mUsage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
271 BufferUsage::COMPOSER_OVERLAY);
272
273 mAccessRegion.top = 0;
274 mAccessRegion.left = 0;
275 mAccessRegion.width = width;
276 mAccessRegion.height = height;
277
278 setSourceCrop({0, 0, (float)width, (float)height});
279 }
280
~TestBufferLayer()281 TestBufferLayer::~TestBufferLayer() {
282 if (mBufferHandle != nullptr) {
283 mGralloc->freeBuffer(mBufferHandle);
284 }
285 }
286
write(const std::shared_ptr<CommandWriterBase> & writer)287 void TestBufferLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
288 TestLayer::write(writer);
289 writer->setLayerCompositionType(mComposition);
290 writer->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, mDisplayFrame));
291 if (mBufferHandle != nullptr) writer->setLayerBuffer(0, mBufferHandle, mFillFence);
292 }
293
toRenderEngineLayerSettings()294 LayerSettings TestBufferLayer::toRenderEngineLayerSettings() {
295 LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
296 layerSettings.source.buffer.buffer =
297 new GraphicBuffer(mBufferHandle, GraphicBuffer::CLONE_HANDLE, mWidth, mHeight,
298 static_cast<int32_t>(mFormat), 1, mUsage, mStride);
299
300 layerSettings.source.buffer.usePremultipliedAlpha =
301 mBlendMode == IComposerClient::BlendMode::PREMULTIPLIED;
302
303 const float scaleX = (mSourceCrop.right - mSourceCrop.left) / (mWidth);
304 const float scaleY = (mSourceCrop.bottom - mSourceCrop.top) / (mHeight);
305 const float translateX = mSourceCrop.left / (mWidth);
306 const float translateY = mSourceCrop.top / (mHeight);
307
308 layerSettings.source.buffer.textureTransform =
309 mat4::translate(vec4(translateX, translateY, 0, 1)) *
310 mat4::scale(vec4(scaleX, scaleY, 1.0, 1.0));
311
312 return layerSettings;
313 }
314
fillBuffer(std::vector<IComposerClient::Color> expectedColors)315 void TestBufferLayer::fillBuffer(std::vector<IComposerClient::Color> expectedColors) {
316 void* bufData = mGralloc->lock(mBufferHandle, mUsage, mAccessRegion, -1);
317 ASSERT_NO_FATAL_FAILURE(
318 ReadbackHelper::fillBuffer(mWidth, mHeight, mStride, bufData, mFormat, expectedColors));
319 mFillFence = mGralloc->unlock(mBufferHandle);
320 if (mFillFence != -1) {
321 sync_wait(mFillFence, -1);
322 close(mFillFence);
323 }
324 }
325
setBuffer(std::vector<IComposerClient::Color> colors)326 void TestBufferLayer::setBuffer(std::vector<IComposerClient::Color> colors) {
327 if (mBufferHandle != nullptr) {
328 mGralloc->freeBuffer(mBufferHandle);
329 mBufferHandle = nullptr;
330 }
331 mBufferHandle = mGralloc->allocate(mWidth, mHeight, mLayerCount, mFormat, mUsage,
332 /*import*/ true, &mStride);
333 ASSERT_NE(nullptr, mBufferHandle);
334 ASSERT_NO_FATAL_FAILURE(fillBuffer(colors));
335 ASSERT_NE(false, mGralloc->validateBufferSize(mBufferHandle, mWidth, mHeight, mLayerCount,
336 mFormat, mUsage, mStride));
337 }
338
setDataspace(Dataspace dataspace,const std::shared_ptr<CommandWriterBase> & writer)339 void TestBufferLayer::setDataspace(Dataspace dataspace,
340 const std::shared_ptr<CommandWriterBase>& writer) {
341 writer->selectLayer(mLayer);
342 writer->setLayerDataspace(dataspace);
343 }
344
setToClientComposition(const std::shared_ptr<CommandWriterBase> & writer)345 void TestBufferLayer::setToClientComposition(const std::shared_ptr<CommandWriterBase>& writer) {
346 writer->selectLayer(mLayer);
347 writer->setLayerCompositionType(IComposerClient::Composition::CLIENT);
348 }
349
350 } // namespace vts
351 } // namespace V2_2
352 } // namespace composer
353 } // namespace graphics
354 } // namespace hardware
355 } // namespace android
356