blob: 81a64529489b66e82b0075fb9e059d082cb6cda9 [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
37int32_t ReadbackHelper::GetBytesPerPixel(PixelFormat pixelFormat) {
38 switch (pixelFormat) {
39 case PixelFormat::RGBA_8888:
40 return 4;
41 case PixelFormat::RGB_888:
42 return 3;
43 default:
44 return -1;
45 }
46}
47
48void ReadbackHelper::fillBuffer(int32_t width, int32_t height, uint32_t stride, void* bufferData,
49 PixelFormat pixelFormat,
50 std::vector<IComposerClient::Color> desiredPixelColors) {
51 ASSERT_TRUE(pixelFormat == PixelFormat::RGB_888 || pixelFormat == PixelFormat::RGBA_8888);
52 int32_t bytesPerPixel = GetBytesPerPixel(pixelFormat);
53 ASSERT_NE(-1, bytesPerPixel);
54 for (int row = 0; row < height; row++) {
55 for (int col = 0; col < width; col++) {
56 int pixel = row * width + col;
57 IComposerClient::Color srcColor = desiredPixelColors[pixel];
58
59 int offset = (row * stride + col) * bytesPerPixel;
60 uint8_t* pixelColor = (uint8_t*)bufferData + offset;
61 pixelColor[0] = srcColor.r;
62 pixelColor[1] = srcColor.g;
63 pixelColor[2] = srcColor.b;
64
65 if (bytesPerPixel == 4) {
66 pixelColor[3] = srcColor.a;
67 }
68 }
69 }
70}
71
72void ReadbackHelper::clearColors(std::vector<IComposerClient::Color>& expectedColors, int32_t width,
73 int32_t height, int32_t displayWidth) {
74 for (int row = 0; row < height; row++) {
75 for (int col = 0; col < width; col++) {
76 int pixel = row * displayWidth + col;
77 expectedColors[pixel] = BLACK;
78 }
79 }
80}
81
82void ReadbackHelper::fillColorsArea(std::vector<IComposerClient::Color>& expectedColors,
83 int32_t stride, IComposerClient::Rect area,
84 IComposerClient::Color color) {
85 for (int row = area.top; row < area.bottom; row++) {
86 for (int col = area.left; col < area.right; col++) {
87 int pixel = row * stride + col;
88 expectedColors[pixel] = color;
89 }
90 }
91}
92
93bool ReadbackHelper::readbackSupported(const PixelFormat& pixelFormat, const Dataspace& dataspace,
94 const Error error) {
95 if (error != Error::NONE) {
96 return false;
97 }
98 // TODO: add support for RGBA_1010102
99 if (pixelFormat != PixelFormat::RGB_888 && pixelFormat != PixelFormat::RGBA_8888) {
100 return false;
101 }
102 if (dataspace != Dataspace::V0_SRGB) {
103 return false;
104 }
105 return true;
106}
107
108ReadbackBuffer::ReadbackBuffer(Display display, const std::shared_ptr<ComposerClient>& client,
109 const std::shared_ptr<Gralloc>& gralloc, uint32_t width,
110 uint32_t height, PixelFormat pixelFormat, Dataspace dataspace) {
111 mDisplay = display;
112
113 mComposerClient = client;
114 mGralloc = gralloc;
115
116 mPixelFormat = pixelFormat;
117 mDataspace = dataspace;
118
Valerie Hauc1dc3132019-06-13 09:49:44 -0700119 mWidth = width;
120 mHeight = height;
121 mLayerCount = 1;
122 mFormat = mPixelFormat;
123 mUsage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::GPU_TEXTURE);
Valerie Haub019fd72019-05-23 12:50:12 -0700124
125 mAccessRegion.top = 0;
126 mAccessRegion.left = 0;
127 mAccessRegion.width = width;
128 mAccessRegion.height = height;
129}
130
131ReadbackBuffer::~ReadbackBuffer() {
132 if (mBufferHandle != nullptr) {
133 mGralloc->freeBuffer(mBufferHandle);
134 }
135}
136
137void ReadbackBuffer::setReadbackBuffer() {
138 if (mBufferHandle != nullptr) {
139 mGralloc->freeBuffer(mBufferHandle);
140 mBufferHandle = nullptr;
141 }
Valerie Hauc1dc3132019-06-13 09:49:44 -0700142 mBufferHandle = mGralloc->allocate(mWidth, mHeight, mLayerCount, mFormat, mUsage,
143 /*import*/ true, &mStride);
144 ASSERT_NE(false, mGralloc->validateBufferSize(mBufferHandle, mWidth, mHeight, mLayerCount,
145 mFormat, mUsage, mStride));
Valerie Haub019fd72019-05-23 12:50:12 -0700146 ASSERT_NO_FATAL_FAILURE(mComposerClient->setReadbackBuffer(mDisplay, mBufferHandle, -1));
147}
148
149void ReadbackBuffer::checkReadbackBuffer(std::vector<IComposerClient::Color> expectedColors) {
150 // lock buffer for reading
151 int32_t fenceHandle;
152 ASSERT_NO_FATAL_FAILURE(mComposerClient->getReadbackBufferFence(mDisplay, &fenceHandle));
153
Valerie Hauc1dc3132019-06-13 09:49:44 -0700154 void* bufData = mGralloc->lock(mBufferHandle, mUsage, mAccessRegion, fenceHandle);
Valerie Haub019fd72019-05-23 12:50:12 -0700155 ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888);
156 int32_t bytesPerPixel = ReadbackHelper::GetBytesPerPixel(mPixelFormat);
157 ASSERT_NE(-1, bytesPerPixel);
Valerie Hauc1dc3132019-06-13 09:49:44 -0700158 for (int row = 0; row < mHeight; row++) {
159 for (int col = 0; col < mWidth; col++) {
160 int pixel = row * mWidth + col;
Valerie Haub019fd72019-05-23 12:50:12 -0700161 int offset = (row * mStride + col) * bytesPerPixel;
162 uint8_t* pixelColor = (uint8_t*)bufData + offset;
163
164 ASSERT_EQ(expectedColors[pixel].r, pixelColor[0]);
165 ASSERT_EQ(expectedColors[pixel].g, pixelColor[1]);
166 ASSERT_EQ(expectedColors[pixel].b, pixelColor[2]);
167 }
168 }
169 int32_t unlockFence = mGralloc->unlock(mBufferHandle);
170 if (unlockFence != -1) {
171 sync_wait(unlockFence, -1);
172 close(unlockFence);
173 }
174}
175
176void TestColorLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
177 TestLayer::write(writer);
178 writer->setLayerCompositionType(IComposerClient::Composition::SOLID_COLOR);
179 writer->setLayerColor(mColor);
180}
181
182TestBufferLayer::TestBufferLayer(const std::shared_ptr<ComposerClient>& client,
183 const std::shared_ptr<Gralloc>& gralloc, Display display,
184 int32_t width, int32_t height, PixelFormat format,
185 IComposerClient::Composition composition)
186 : TestLayer{client, display} {
187 mGralloc = gralloc;
188 mComposition = composition;
Valerie Hauc1dc3132019-06-13 09:49:44 -0700189 mWidth = width;
190 mHeight = height;
191 mLayerCount = 1;
192 mFormat = format;
193 mUsage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
194 BufferUsage::COMPOSER_OVERLAY);
Valerie Haub019fd72019-05-23 12:50:12 -0700195
196 mAccessRegion.top = 0;
197 mAccessRegion.left = 0;
198 mAccessRegion.width = width;
199 mAccessRegion.height = height;
200
201 setSourceCrop({0, 0, (float)width, (float)height});
202}
203
204TestBufferLayer::~TestBufferLayer() {
205 if (mBufferHandle != nullptr) {
206 mGralloc->freeBuffer(mBufferHandle);
207 }
208}
209
210void TestBufferLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
211 TestLayer::write(writer);
212 writer->setLayerCompositionType(mComposition);
213 writer->setLayerDataspace(Dataspace::UNKNOWN);
214 writer->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, mDisplayFrame));
215 if (mBufferHandle != nullptr) writer->setLayerBuffer(0, mBufferHandle, mFillFence);
216}
217
218void TestBufferLayer::fillBuffer(std::vector<IComposerClient::Color> expectedColors) {
Valerie Hauc1dc3132019-06-13 09:49:44 -0700219 void* bufData = mGralloc->lock(mBufferHandle, mUsage, mAccessRegion, -1);
220 ASSERT_NO_FATAL_FAILURE(
221 ReadbackHelper::fillBuffer(mWidth, mHeight, mStride, bufData, mFormat, expectedColors));
Valerie Haub019fd72019-05-23 12:50:12 -0700222 mFillFence = mGralloc->unlock(mBufferHandle);
223 if (mFillFence != -1) {
224 sync_wait(mFillFence, -1);
225 close(mFillFence);
226 }
227}
228void TestBufferLayer::setBuffer(std::vector<IComposerClient::Color> colors) {
229 if (mBufferHandle != nullptr) {
230 mGralloc->freeBuffer(mBufferHandle);
231 mBufferHandle = nullptr;
232 }
Valerie Hauc1dc3132019-06-13 09:49:44 -0700233 mBufferHandle = mGralloc->allocate(mWidth, mHeight, mLayerCount, mFormat, mUsage,
234 /*import*/ true, &mStride);
Valerie Haub019fd72019-05-23 12:50:12 -0700235 ASSERT_NE(nullptr, mBufferHandle);
236 ASSERT_NO_FATAL_FAILURE(fillBuffer(colors));
Valerie Hauc1dc3132019-06-13 09:49:44 -0700237 ASSERT_NE(false, mGralloc->validateBufferSize(mBufferHandle, mWidth, mHeight, mLayerCount,
238 mFormat, mUsage, mStride));
Valerie Haub019fd72019-05-23 12:50:12 -0700239}
240
241void TestBufferLayer::setToClientComposition(const std::shared_ptr<CommandWriterBase>& writer) {
242 writer->selectLayer(mLayer);
243 writer->setLayerCompositionType(IComposerClient::Composition::CLIENT);
244}
245
246} // namespace vts
247} // namespace V2_2
248} // namespace composer
249} // namespace graphics
250} // namespace hardware
251} // namespace android