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