blob: 515dda3f7b48c217ec08b41c0101979f6c10e1b8 [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
Valerie Haub019fd72019-05-23 12:50:12 -070063int32_t ReadbackHelper::GetBytesPerPixel(PixelFormat pixelFormat) {
64 switch (pixelFormat) {
65 case PixelFormat::RGBA_8888:
66 return 4;
67 case PixelFormat::RGB_888:
68 return 3;
69 default:
70 return -1;
71 }
72}
73
74void ReadbackHelper::fillBuffer(int32_t width, int32_t height, uint32_t stride, void* bufferData,
75 PixelFormat pixelFormat,
76 std::vector<IComposerClient::Color> desiredPixelColors) {
77 ASSERT_TRUE(pixelFormat == PixelFormat::RGB_888 || pixelFormat == PixelFormat::RGBA_8888);
78 int32_t bytesPerPixel = GetBytesPerPixel(pixelFormat);
79 ASSERT_NE(-1, bytesPerPixel);
80 for (int row = 0; row < height; row++) {
81 for (int col = 0; col < width; col++) {
82 int pixel = row * width + col;
83 IComposerClient::Color srcColor = desiredPixelColors[pixel];
84
85 int offset = (row * stride + col) * bytesPerPixel;
86 uint8_t* pixelColor = (uint8_t*)bufferData + offset;
87 pixelColor[0] = srcColor.r;
88 pixelColor[1] = srcColor.g;
89 pixelColor[2] = srcColor.b;
90
91 if (bytesPerPixel == 4) {
92 pixelColor[3] = srcColor.a;
93 }
94 }
95 }
96}
97
98void ReadbackHelper::clearColors(std::vector<IComposerClient::Color>& expectedColors, int32_t width,
99 int32_t height, int32_t displayWidth) {
100 for (int row = 0; row < height; row++) {
101 for (int col = 0; col < width; col++) {
102 int pixel = row * displayWidth + col;
103 expectedColors[pixel] = BLACK;
104 }
105 }
106}
107
108void ReadbackHelper::fillColorsArea(std::vector<IComposerClient::Color>& expectedColors,
109 int32_t stride, IComposerClient::Rect area,
110 IComposerClient::Color color) {
111 for (int row = area.top; row < area.bottom; row++) {
112 for (int col = area.left; col < area.right; col++) {
113 int pixel = row * stride + col;
114 expectedColors[pixel] = color;
115 }
116 }
117}
118
119bool ReadbackHelper::readbackSupported(const PixelFormat& pixelFormat, const Dataspace& dataspace,
120 const Error error) {
121 if (error != Error::NONE) {
122 return false;
123 }
124 // TODO: add support for RGBA_1010102
125 if (pixelFormat != PixelFormat::RGB_888 && pixelFormat != PixelFormat::RGBA_8888) {
126 return false;
127 }
Valerie Hau7c8eb682019-06-12 14:24:27 -0700128 if (std::find(dataspaces.begin(), dataspaces.end(), dataspace) == dataspaces.end()) {
Valerie Haub019fd72019-05-23 12:50:12 -0700129 return false;
130 }
131 return true;
132}
133
134ReadbackBuffer::ReadbackBuffer(Display display, const std::shared_ptr<ComposerClient>& client,
135 const std::shared_ptr<Gralloc>& gralloc, uint32_t width,
136 uint32_t height, PixelFormat pixelFormat, Dataspace dataspace) {
137 mDisplay = display;
138
139 mComposerClient = client;
140 mGralloc = gralloc;
141
142 mPixelFormat = pixelFormat;
143 mDataspace = dataspace;
144
Valerie Hauc1dc3132019-06-13 09:49:44 -0700145 mWidth = width;
146 mHeight = height;
147 mLayerCount = 1;
148 mFormat = mPixelFormat;
149 mUsage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::GPU_TEXTURE);
Valerie Haub019fd72019-05-23 12:50:12 -0700150
151 mAccessRegion.top = 0;
152 mAccessRegion.left = 0;
153 mAccessRegion.width = width;
154 mAccessRegion.height = height;
155}
156
157ReadbackBuffer::~ReadbackBuffer() {
158 if (mBufferHandle != nullptr) {
159 mGralloc->freeBuffer(mBufferHandle);
160 }
161}
162
163void ReadbackBuffer::setReadbackBuffer() {
164 if (mBufferHandle != nullptr) {
165 mGralloc->freeBuffer(mBufferHandle);
166 mBufferHandle = nullptr;
167 }
Valerie Hauc1dc3132019-06-13 09:49:44 -0700168 mBufferHandle = mGralloc->allocate(mWidth, mHeight, mLayerCount, mFormat, mUsage,
169 /*import*/ true, &mStride);
170 ASSERT_NE(false, mGralloc->validateBufferSize(mBufferHandle, mWidth, mHeight, mLayerCount,
171 mFormat, mUsage, mStride));
Valerie Haub019fd72019-05-23 12:50:12 -0700172 ASSERT_NO_FATAL_FAILURE(mComposerClient->setReadbackBuffer(mDisplay, mBufferHandle, -1));
173}
174
175void ReadbackBuffer::checkReadbackBuffer(std::vector<IComposerClient::Color> expectedColors) {
176 // lock buffer for reading
177 int32_t fenceHandle;
178 ASSERT_NO_FATAL_FAILURE(mComposerClient->getReadbackBufferFence(mDisplay, &fenceHandle));
179
Valerie Hauc1dc3132019-06-13 09:49:44 -0700180 void* bufData = mGralloc->lock(mBufferHandle, mUsage, mAccessRegion, fenceHandle);
Valerie Haub019fd72019-05-23 12:50:12 -0700181 ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888);
182 int32_t bytesPerPixel = ReadbackHelper::GetBytesPerPixel(mPixelFormat);
183 ASSERT_NE(-1, bytesPerPixel);
Valerie Hauc1dc3132019-06-13 09:49:44 -0700184 for (int row = 0; row < mHeight; row++) {
185 for (int col = 0; col < mWidth; col++) {
186 int pixel = row * mWidth + col;
Valerie Haub019fd72019-05-23 12:50:12 -0700187 int offset = (row * mStride + col) * bytesPerPixel;
188 uint8_t* pixelColor = (uint8_t*)bufData + offset;
189
190 ASSERT_EQ(expectedColors[pixel].r, pixelColor[0]);
191 ASSERT_EQ(expectedColors[pixel].g, pixelColor[1]);
192 ASSERT_EQ(expectedColors[pixel].b, pixelColor[2]);
193 }
194 }
195 int32_t unlockFence = mGralloc->unlock(mBufferHandle);
196 if (unlockFence != -1) {
197 sync_wait(unlockFence, -1);
198 close(unlockFence);
199 }
200}
201
202void TestColorLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
203 TestLayer::write(writer);
204 writer->setLayerCompositionType(IComposerClient::Composition::SOLID_COLOR);
205 writer->setLayerColor(mColor);
206}
207
208TestBufferLayer::TestBufferLayer(const std::shared_ptr<ComposerClient>& client,
209 const std::shared_ptr<Gralloc>& gralloc, Display display,
210 int32_t width, int32_t height, PixelFormat format,
211 IComposerClient::Composition composition)
212 : TestLayer{client, display} {
213 mGralloc = gralloc;
214 mComposition = composition;
Valerie Hauc1dc3132019-06-13 09:49:44 -0700215 mWidth = width;
216 mHeight = height;
217 mLayerCount = 1;
218 mFormat = format;
219 mUsage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
220 BufferUsage::COMPOSER_OVERLAY);
Valerie Haub019fd72019-05-23 12:50:12 -0700221
222 mAccessRegion.top = 0;
223 mAccessRegion.left = 0;
224 mAccessRegion.width = width;
225 mAccessRegion.height = height;
226
227 setSourceCrop({0, 0, (float)width, (float)height});
228}
229
230TestBufferLayer::~TestBufferLayer() {
231 if (mBufferHandle != nullptr) {
232 mGralloc->freeBuffer(mBufferHandle);
233 }
234}
235
236void TestBufferLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
237 TestLayer::write(writer);
238 writer->setLayerCompositionType(mComposition);
239 writer->setLayerDataspace(Dataspace::UNKNOWN);
240 writer->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, mDisplayFrame));
241 if (mBufferHandle != nullptr) writer->setLayerBuffer(0, mBufferHandle, mFillFence);
242}
243
244void TestBufferLayer::fillBuffer(std::vector<IComposerClient::Color> expectedColors) {
Valerie Hauc1dc3132019-06-13 09:49:44 -0700245 void* bufData = mGralloc->lock(mBufferHandle, mUsage, mAccessRegion, -1);
246 ASSERT_NO_FATAL_FAILURE(
247 ReadbackHelper::fillBuffer(mWidth, mHeight, mStride, bufData, mFormat, expectedColors));
Valerie Haub019fd72019-05-23 12:50:12 -0700248 mFillFence = mGralloc->unlock(mBufferHandle);
249 if (mFillFence != -1) {
250 sync_wait(mFillFence, -1);
251 close(mFillFence);
252 }
253}
254void TestBufferLayer::setBuffer(std::vector<IComposerClient::Color> colors) {
255 if (mBufferHandle != nullptr) {
256 mGralloc->freeBuffer(mBufferHandle);
257 mBufferHandle = nullptr;
258 }
Valerie Hauc1dc3132019-06-13 09:49:44 -0700259 mBufferHandle = mGralloc->allocate(mWidth, mHeight, mLayerCount, mFormat, mUsage,
260 /*import*/ true, &mStride);
Valerie Haub019fd72019-05-23 12:50:12 -0700261 ASSERT_NE(nullptr, mBufferHandle);
262 ASSERT_NO_FATAL_FAILURE(fillBuffer(colors));
Valerie Hauc1dc3132019-06-13 09:49:44 -0700263 ASSERT_NE(false, mGralloc->validateBufferSize(mBufferHandle, mWidth, mHeight, mLayerCount,
264 mFormat, mUsage, mStride));
Valerie Haub019fd72019-05-23 12:50:12 -0700265}
266
267void TestBufferLayer::setToClientComposition(const std::shared_ptr<CommandWriterBase>& writer) {
268 writer->selectLayer(mLayer);
269 writer->setLayerCompositionType(IComposerClient::Composition::CLIENT);
270}
271
272} // namespace vts
273} // namespace V2_2
274} // namespace composer
275} // namespace graphics
276} // namespace hardware
277} // namespace android