• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <composer-vts/2.2/RenderEngineVts.h>
19 #include "renderengine/ExternalTexture.h"
20 #include "renderengine/impl/ExternalTexture.h"
21 
22 namespace android {
23 namespace hardware {
24 namespace graphics {
25 namespace composer {
26 namespace V2_2 {
27 namespace vts {
28 
write(const std::shared_ptr<CommandWriterBase> & writer)29 void TestLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
30     writer->selectLayer(mLayer);
31     writer->setLayerDisplayFrame(mDisplayFrame);
32     writer->setLayerSourceCrop(mSourceCrop);
33     writer->setLayerZOrder(mZOrder);
34     writer->setLayerSurfaceDamage(mSurfaceDamage);
35     writer->setLayerTransform(mTransform);
36     writer->setLayerPlaneAlpha(mAlpha);
37     writer->setLayerBlendMode(mBlendMode);
38 }
39 
40 const std::vector<ColorMode> ReadbackHelper::colorModes = {ColorMode::SRGB, ColorMode::DISPLAY_P3};
41 const std::vector<Dataspace> ReadbackHelper::dataspaces = {Dataspace::V0_SRGB,
42                                                            Dataspace::DISPLAY_P3};
43 
getColorModeString(ColorMode mode)44 std::string ReadbackHelper::getColorModeString(ColorMode mode) {
45     switch (mode) {
46         case ColorMode::SRGB:
47             return std::string("SRGB");
48         case ColorMode::DISPLAY_P3:
49             return std::string("DISPLAY_P3");
50         default:
51             return std::string("Unsupported color mode for readback");
52     }
53 }
54 
getDataspaceString(Dataspace dataspace)55 std::string ReadbackHelper::getDataspaceString(Dataspace dataspace) {
56     switch (dataspace) {
57         case Dataspace::V0_SRGB:
58             return std::string("V0_SRGB");
59         case Dataspace::DISPLAY_P3:
60             return std::string("DISPLAY_P3");
61         case Dataspace::UNKNOWN:
62             return std::string("UNKNOWN");
63         default:
64             return std::string("Unsupported dataspace for readback");
65     }
66 }
67 
getDataspaceForColorMode(ColorMode mode)68 Dataspace ReadbackHelper::getDataspaceForColorMode(ColorMode mode) {
69     switch (mode) {
70         case ColorMode::DISPLAY_P3:
71             return Dataspace::DISPLAY_P3;
72         case ColorMode::SRGB:
73         default:
74             return Dataspace::UNKNOWN;
75     }
76 }
77 
toRenderEngineLayerSettings()78 LayerSettings TestLayer::toRenderEngineLayerSettings() {
79     LayerSettings layerSettings;
80 
81     layerSettings.alpha = half(mAlpha);
82     layerSettings.disableBlending = mBlendMode == IComposerClient::BlendMode::NONE;
83     layerSettings.geometry.boundaries = FloatRect(
84             static_cast<float>(mDisplayFrame.left), static_cast<float>(mDisplayFrame.top),
85             static_cast<float>(mDisplayFrame.right), static_cast<float>(mDisplayFrame.bottom));
86 
87     const mat4 translation = mat4::translate(
88             vec4((mTransform & Transform::FLIP_H ? -mDisplayFrame.right : 0.0f),
89                  (mTransform & Transform::FLIP_V ? -mDisplayFrame.bottom : 0.0f), 0.0f, 1.0f));
90 
91     const mat4 scale = mat4::scale(vec4(mTransform & Transform::FLIP_H ? -1.0f : 1.0f,
92                                         mTransform & Transform::FLIP_V ? -1.0f : 1.0f, 1.0f, 1.0f));
93 
94     layerSettings.geometry.positionTransform = scale * translation;
95 
96     return layerSettings;
97 }
98 
GetBytesPerPixel(PixelFormat pixelFormat)99 int32_t ReadbackHelper::GetBytesPerPixel(PixelFormat pixelFormat) {
100     switch (pixelFormat) {
101         case PixelFormat::RGBA_8888:
102             return 4;
103         case PixelFormat::RGB_888:
104             return 3;
105         default:
106             return -1;
107     }
108 }
109 
fillBuffer(int32_t width,int32_t height,uint32_t stride,void * bufferData,PixelFormat pixelFormat,std::vector<IComposerClient::Color> desiredPixelColors)110 void ReadbackHelper::fillBuffer(int32_t width, int32_t height, uint32_t stride, void* bufferData,
111                                 PixelFormat pixelFormat,
112                                 std::vector<IComposerClient::Color> desiredPixelColors) {
113     ASSERT_TRUE(pixelFormat == PixelFormat::RGB_888 || pixelFormat == PixelFormat::RGBA_8888);
114     int32_t bytesPerPixel = GetBytesPerPixel(pixelFormat);
115     ASSERT_NE(-1, bytesPerPixel);
116     for (int row = 0; row < height; row++) {
117         for (int col = 0; col < width; col++) {
118             int pixel = row * width + col;
119             IComposerClient::Color srcColor = desiredPixelColors[pixel];
120 
121             int offset = (row * stride + col) * bytesPerPixel;
122             uint8_t* pixelColor = (uint8_t*)bufferData + offset;
123             pixelColor[0] = srcColor.r;
124             pixelColor[1] = srcColor.g;
125             pixelColor[2] = srcColor.b;
126 
127             if (bytesPerPixel == 4) {
128                 pixelColor[3] = srcColor.a;
129             }
130         }
131     }
132 }
133 
clearColors(std::vector<IComposerClient::Color> & expectedColors,int32_t width,int32_t height,int32_t displayWidth)134 void ReadbackHelper::clearColors(std::vector<IComposerClient::Color>& expectedColors, int32_t width,
135                                  int32_t height, int32_t displayWidth) {
136     for (int row = 0; row < height; row++) {
137         for (int col = 0; col < width; col++) {
138             int pixel = row * displayWidth + col;
139             expectedColors[pixel] = BLACK;
140         }
141     }
142 }
143 
fillColorsArea(std::vector<IComposerClient::Color> & expectedColors,int32_t stride,IComposerClient::Rect area,IComposerClient::Color color)144 void ReadbackHelper::fillColorsArea(std::vector<IComposerClient::Color>& expectedColors,
145                                     int32_t stride, IComposerClient::Rect area,
146                                     IComposerClient::Color color) {
147     for (int row = area.top; row < area.bottom; row++) {
148         for (int col = area.left; col < area.right; col++) {
149             int pixel = row * stride + col;
150             expectedColors[pixel] = color;
151         }
152     }
153 }
154 
readbackSupported(const PixelFormat & pixelFormat,const Dataspace & dataspace,const Error error)155 bool ReadbackHelper::readbackSupported(const PixelFormat& pixelFormat, const Dataspace& dataspace,
156                                        const Error error) {
157     if (error != Error::NONE) {
158         return false;
159     }
160     // TODO: add support for RGBA_1010102
161     if (pixelFormat != PixelFormat::RGB_888 && pixelFormat != PixelFormat::RGBA_8888) {
162         return false;
163     }
164     if (std::find(dataspaces.begin(), dataspaces.end(), dataspace) == dataspaces.end()) {
165         return false;
166     }
167     return true;
168 }
169 
compareColorBuffers(std::vector<IComposerClient::Color> & expectedColors,void * bufferData,const uint32_t stride,const uint32_t width,const uint32_t height,const PixelFormat pixelFormat)170 void ReadbackHelper::compareColorBuffers(std::vector<IComposerClient::Color>& expectedColors,
171                                          void* bufferData, const uint32_t stride,
172                                          const uint32_t width, const uint32_t height,
173                                          const PixelFormat pixelFormat) {
174     const int32_t bytesPerPixel = ReadbackHelper::GetBytesPerPixel(pixelFormat);
175     ASSERT_NE(-1, bytesPerPixel);
176     for (int row = 0; row < height; row++) {
177         for (int col = 0; col < width; col++) {
178             int pixel = row * width + col;
179             int offset = (row * stride + col) * bytesPerPixel;
180             uint8_t* pixelColor = (uint8_t*)bufferData + offset;
181 
182             ASSERT_EQ(expectedColors[pixel].r, pixelColor[0]);
183             ASSERT_EQ(expectedColors[pixel].g, pixelColor[1]);
184             ASSERT_EQ(expectedColors[pixel].b, pixelColor[2]);
185         }
186     }
187 }
188 
ReadbackBuffer(Display display,const std::shared_ptr<ComposerClient> & client,uint32_t width,uint32_t height,PixelFormat pixelFormat,Dataspace dataspace)189 ReadbackBuffer::ReadbackBuffer(Display display, const std::shared_ptr<ComposerClient>& client,
190                                uint32_t width, uint32_t height, PixelFormat pixelFormat,
191                                Dataspace dataspace) {
192     mDisplay = display;
193 
194     mComposerClient = client;
195 
196     mPixelFormat = pixelFormat;
197     mDataspace = dataspace;
198 
199     mWidth = width;
200     mHeight = height;
201     mLayerCount = 1;
202     mFormat = mPixelFormat;
203     mUsage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::GPU_TEXTURE);
204 }
205 
setReadbackBuffer()206 void ReadbackBuffer::setReadbackBuffer() {
207     mBuffer = sp<GraphicBuffer>::make(mWidth, mHeight, (int32_t)mFormat, mLayerCount, mUsage);
208     ASSERT_EQ(STATUS_OK, mBuffer->initCheck());
209     ASSERT_NO_FATAL_FAILURE(mComposerClient->setReadbackBuffer(mDisplay, mBuffer->handle, -1));
210 }
211 
checkReadbackBuffer(std::vector<IComposerClient::Color> expectedColors)212 void ReadbackBuffer::checkReadbackBuffer(std::vector<IComposerClient::Color> expectedColors) {
213     // lock buffer for reading
214     int32_t fenceHandle;
215     ASSERT_NO_FATAL_FAILURE(mComposerClient->getReadbackBufferFence(mDisplay, &fenceHandle));
216 
217     void* bufData = nullptr;
218     int32_t stride = mBuffer->stride;
219     status_t status = mBuffer->lockAsync(mUsage, &bufData, fenceHandle);
220     ASSERT_EQ(STATUS_OK, status);
221     ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888);
222     ReadbackHelper::compareColorBuffers(expectedColors, bufData, stride, mWidth, mHeight,
223                                         mPixelFormat);
224     EXPECT_EQ(STATUS_OK, mBuffer->unlock());
225 }
226 
write(const std::shared_ptr<CommandWriterBase> & writer)227 void TestColorLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
228     TestLayer::write(writer);
229     writer->setLayerCompositionType(IComposerClient::Composition::SOLID_COLOR);
230     writer->setLayerColor(mColor);
231 }
232 
toRenderEngineLayerSettings()233 LayerSettings TestColorLayer::toRenderEngineLayerSettings() {
234     LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
235 
236     layerSettings.source.solidColor =
237             half3(static_cast<half>(mColor.r) / 255.0, static_cast<half>(mColor.g) / 255.0,
238                   static_cast<half>(mColor.b) / 255.0);
239     layerSettings.alpha = mAlpha * (static_cast<half>(mColor.a) / 255.0);
240     return layerSettings;
241 }
242 
TestBufferLayer(const std::shared_ptr<ComposerClient> & client,TestRenderEngine & renderEngine,Display display,int32_t width,int32_t height,PixelFormat format,IComposerClient::Composition composition)243 TestBufferLayer::TestBufferLayer(const std::shared_ptr<ComposerClient>& client,
244                                  TestRenderEngine& renderEngine, Display display, int32_t width,
245                                  int32_t height, PixelFormat format,
246                                  IComposerClient::Composition composition)
247     : TestLayer{client, display}, mRenderEngine(renderEngine) {
248     mComposition = composition;
249     mWidth = width;
250     mHeight = height;
251     mLayerCount = 1;
252     mFormat = format;
253     mUsage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
254                                    BufferUsage::COMPOSER_OVERLAY | BufferUsage::GPU_TEXTURE);
255 
256     setSourceCrop({0, 0, (float)width, (float)height});
257 }
258 
write(const std::shared_ptr<CommandWriterBase> & writer)259 void TestBufferLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
260     TestLayer::write(writer);
261     writer->setLayerCompositionType(mComposition);
262     writer->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, mDisplayFrame));
263     if (mBuffer) writer->setLayerBuffer(0, mBuffer->handle, -1);
264 }
265 
toRenderEngineLayerSettings()266 LayerSettings TestBufferLayer::toRenderEngineLayerSettings() {
267     LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
268     layerSettings.source.buffer.buffer = std::make_shared<renderengine::impl::ExternalTexture>(
269             mBuffer, mRenderEngine.getInternalRenderEngine(),
270             renderengine::impl::ExternalTexture::Usage::READABLE);
271 
272     layerSettings.source.buffer.usePremultipliedAlpha =
273             mBlendMode == IComposerClient::BlendMode::PREMULTIPLIED;
274 
275     const float scaleX = (mSourceCrop.right - mSourceCrop.left) / (mWidth);
276     const float scaleY = (mSourceCrop.bottom - mSourceCrop.top) / (mHeight);
277     const float translateX = mSourceCrop.left / (mWidth);
278     const float translateY = mSourceCrop.top / (mHeight);
279 
280     layerSettings.source.buffer.textureTransform =
281             mat4::translate(vec4(translateX, translateY, 0, 1)) *
282             mat4::scale(vec4(scaleX, scaleY, 1.0, 1.0));
283 
284     return layerSettings;
285 }
286 
fillBuffer(std::vector<IComposerClient::Color> expectedColors)287 void TestBufferLayer::fillBuffer(std::vector<IComposerClient::Color> expectedColors) {
288     void* bufData = nullptr;
289     status_t status = mBuffer->lock(mUsage, &bufData);
290     ASSERT_EQ(STATUS_OK, status);
291     ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(mWidth, mHeight, mBuffer->stride, bufData,
292                                                        mFormat, expectedColors));
293     EXPECT_EQ(STATUS_OK, mBuffer->unlock());
294 }
295 
setBuffer(std::vector<IComposerClient::Color> colors)296 void TestBufferLayer::setBuffer(std::vector<IComposerClient::Color> colors) {
297     mBuffer = sp<GraphicBuffer>::make(mWidth, mHeight, (int32_t)mFormat, mLayerCount, mUsage);
298     ASSERT_EQ(STATUS_OK, mBuffer->initCheck());
299     ASSERT_NO_FATAL_FAILURE(fillBuffer(colors));
300 }
301 
setDataspace(Dataspace dataspace,const std::shared_ptr<CommandWriterBase> & writer)302 void TestBufferLayer::setDataspace(Dataspace dataspace,
303                                    const std::shared_ptr<CommandWriterBase>& writer) {
304     writer->selectLayer(mLayer);
305     writer->setLayerDataspace(dataspace);
306 }
307 
setToClientComposition(const std::shared_ptr<CommandWriterBase> & writer)308 void TestBufferLayer::setToClientComposition(const std::shared_ptr<CommandWriterBase>& writer) {
309     writer->selectLayer(mLayer);
310     writer->setLayerCompositionType(IComposerClient::Composition::CLIENT);
311 }
312 
313 }  // namespace vts
314 }  // namespace V2_2
315 }  // namespace composer
316 }  // namespace graphics
317 }  // namespace hardware
318 }  // namespace android
319