blob: 9ba34f17c57420787c37e568295b62fd3e740aa9 [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>
Alec Mouri2a6ef4e2021-04-16 16:36:21 +000018#include <composer-vts/2.2/RenderEngineVts.h>
19#include "renderengine/ExternalTexture.h"
Vishnu Nair59329712022-01-13 07:59:37 -080020#include "renderengine/impl/ExternalTexture.h"
Valerie Haub019fd72019-05-23 12:50:12 -070021
22namespace android {
23namespace hardware {
24namespace graphics {
25namespace composer {
26namespace V2_2 {
27namespace vts {
28
29void 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
Valerie Hau7c8eb682019-06-12 14:24:27 -070040const std::vector<ColorMode> ReadbackHelper::colorModes = {ColorMode::SRGB, ColorMode::DISPLAY_P3};
41const std::vector<Dataspace> ReadbackHelper::dataspaces = {Dataspace::V0_SRGB,
42 Dataspace::DISPLAY_P3};
43
44std::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
55std::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");
Valerie Hau37edd052019-07-11 15:48:38 -070061 case Dataspace::UNKNOWN:
62 return std::string("UNKNOWN");
Valerie Hau7c8eb682019-06-12 14:24:27 -070063 default:
64 return std::string("Unsupported dataspace for readback");
65 }
66}
67
Valerie Hau37edd052019-07-11 15:48:38 -070068Dataspace 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
Adam Bodnar5bf9dc62019-05-24 09:20:04 -070078LayerSettings 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
Adam Bodnard0aef4d2019-07-11 10:35:42 -070087 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));
Adam Bodnar5bf9dc62019-05-24 09:20:04 -070090
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
Adam Bodnard0aef4d2019-07-11 10:35:42 -070094 layerSettings.geometry.positionTransform = scale * translation;
Adam Bodnar5bf9dc62019-05-24 09:20:04 -070095
96 return layerSettings;
97}
98
Valerie Haub019fd72019-05-23 12:50:12 -070099int32_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
110void 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;
Brian Lindahle887a252023-01-17 14:54:19 -0700119 IComposerClient::Color srcColor = desiredPixelColors[pixel];
Valerie Haub019fd72019-05-23 12:50:12 -0700120
121 int offset = (row * stride + col) * bytesPerPixel;
122 uint8_t* pixelColor = (uint8_t*)bufferData + offset;
Brian Lindahle887a252023-01-17 14:54:19 -0700123 pixelColor[0] = srcColor.r;
124 pixelColor[1] = srcColor.g;
125 pixelColor[2] = srcColor.b;
Valerie Haub019fd72019-05-23 12:50:12 -0700126
127 if (bytesPerPixel == 4) {
Brian Lindahle887a252023-01-17 14:54:19 -0700128 pixelColor[3] = srcColor.a;
Valerie Haub019fd72019-05-23 12:50:12 -0700129 }
130 }
131 }
132}
133
134void 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
144void 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
Brian Lindahle887a252023-01-17 14:54:19 -0700155bool ReadbackHelper::readbackSupported(const PixelFormat& pixelFormat, const Dataspace& dataspace,
156 const Error error) {
Valerie Haub019fd72019-05-23 12:50:12 -0700157 if (error != Error::NONE) {
158 return false;
159 }
Brian Lindahle887a252023-01-17 14:54:19 -0700160 // TODO: add support for RGBA_1010102
Valerie Haub019fd72019-05-23 12:50:12 -0700161 if (pixelFormat != PixelFormat::RGB_888 && pixelFormat != PixelFormat::RGBA_8888) {
162 return false;
163 }
Valerie Hau7c8eb682019-06-12 14:24:27 -0700164 if (std::find(dataspaces.begin(), dataspaces.end(), dataspace) == dataspaces.end()) {
Valerie Haub019fd72019-05-23 12:50:12 -0700165 return false;
166 }
167 return true;
168}
169
Brian Lindahle887a252023-01-17 14:54:19 -0700170void 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);
Brian Lindahld103cd62022-12-09 07:26:28 -0700175 ASSERT_NE(-1, bytesPerPixel);
Brian Lindahle887a252023-01-17 14:54:19 -0700176 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]);
Adam Bodnar5bf9dc62019-05-24 09:20:04 -0700185 }
186 }
187}
188
Valerie Haub019fd72019-05-23 12:50:12 -0700189ReadbackBuffer::ReadbackBuffer(Display display, const std::shared_ptr<ComposerClient>& client,
John Reck82c666b2023-07-25 22:03:27 -0400190 uint32_t width, uint32_t height, PixelFormat pixelFormat,
191 Dataspace dataspace) {
Valerie Haub019fd72019-05-23 12:50:12 -0700192 mDisplay = display;
Brian Lindahle887a252023-01-17 14:54:19 -0700193
Valerie Haub019fd72019-05-23 12:50:12 -0700194 mComposerClient = client;
Brian Lindahle887a252023-01-17 14:54:19 -0700195
196 mPixelFormat = pixelFormat;
197 mDataspace = dataspace;
198
Valerie Hauc1dc3132019-06-13 09:49:44 -0700199 mWidth = width;
200 mHeight = height;
201 mLayerCount = 1;
Brian Lindahle887a252023-01-17 14:54:19 -0700202 mFormat = mPixelFormat;
Valerie Hauc1dc3132019-06-13 09:49:44 -0700203 mUsage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN | BufferUsage::GPU_TEXTURE);
Valerie Haub019fd72019-05-23 12:50:12 -0700204}
205
Valerie Haub019fd72019-05-23 12:50:12 -0700206void ReadbackBuffer::setReadbackBuffer() {
John Reck82c666b2023-07-25 22:03:27 -0400207 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));
Valerie Haub019fd72019-05-23 12:50:12 -0700210}
211
212void 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));
Brian Lindahle887a252023-01-17 14:54:19 -0700216
John Reck82c666b2023-07-25 22:03:27 -0400217 void* bufData = nullptr;
218 int32_t stride = mBuffer->stride;
219 status_t status = mBuffer->lockAsync(mUsage, &bufData, fenceHandle);
220 ASSERT_EQ(STATUS_OK, status);
Brian Lindahle887a252023-01-17 14:54:19 -0700221 ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888);
John Reck82c666b2023-07-25 22:03:27 -0400222 ReadbackHelper::compareColorBuffers(expectedColors, bufData, stride, mWidth, mHeight,
Brian Lindahle887a252023-01-17 14:54:19 -0700223 mPixelFormat);
John Reck82c666b2023-07-25 22:03:27 -0400224 EXPECT_EQ(STATUS_OK, mBuffer->unlock());
Valerie Haub019fd72019-05-23 12:50:12 -0700225}
226
227void 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
Adam Bodnar5bf9dc62019-05-24 09:20:04 -0700233LayerSettings 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
Valerie Haub019fd72019-05-23 12:50:12 -0700243TestBufferLayer::TestBufferLayer(const std::shared_ptr<ComposerClient>& client,
Alec Mouri2a6ef4e2021-04-16 16:36:21 +0000244 TestRenderEngine& renderEngine, Display display, int32_t width,
245 int32_t height, PixelFormat format,
Valerie Haub019fd72019-05-23 12:50:12 -0700246 IComposerClient::Composition composition)
Alec Mouri2a6ef4e2021-04-16 16:36:21 +0000247 : TestLayer{client, display}, mRenderEngine(renderEngine) {
Valerie Haub019fd72019-05-23 12:50:12 -0700248 mComposition = composition;
Valerie Hauc1dc3132019-06-13 09:49:44 -0700249 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 |
Ady Abraham203bdee2021-03-16 23:59:45 +0000254 BufferUsage::COMPOSER_OVERLAY | BufferUsage::GPU_TEXTURE);
Valerie Haub019fd72019-05-23 12:50:12 -0700255
Valerie Haub019fd72019-05-23 12:50:12 -0700256 setSourceCrop({0, 0, (float)width, (float)height});
257}
258
Valerie Haub019fd72019-05-23 12:50:12 -0700259void TestBufferLayer::write(const std::shared_ptr<CommandWriterBase>& writer) {
260 TestLayer::write(writer);
261 writer->setLayerCompositionType(mComposition);
Valerie Haub019fd72019-05-23 12:50:12 -0700262 writer->setLayerVisibleRegion(std::vector<IComposerClient::Rect>(1, mDisplayFrame));
John Reck82c666b2023-07-25 22:03:27 -0400263 if (mBuffer) writer->setLayerBuffer(0, mBuffer->handle, -1);
Valerie Haub019fd72019-05-23 12:50:12 -0700264}
265
Adam Bodnar5bf9dc62019-05-24 09:20:04 -0700266LayerSettings TestBufferLayer::toRenderEngineLayerSettings() {
267 LayerSettings layerSettings = TestLayer::toRenderEngineLayerSettings();
Vishnu Nair59329712022-01-13 07:59:37 -0800268 layerSettings.source.buffer.buffer = std::make_shared<renderengine::impl::ExternalTexture>(
John Reck82c666b2023-07-25 22:03:27 -0400269 mBuffer, mRenderEngine.getInternalRenderEngine(),
Vishnu Nair59329712022-01-13 07:59:37 -0800270 renderengine::impl::ExternalTexture::Usage::READABLE);
Adam Bodnard0aef4d2019-07-11 10:35:42 -0700271
272 layerSettings.source.buffer.usePremultipliedAlpha =
273 mBlendMode == IComposerClient::BlendMode::PREMULTIPLIED;
Adam Bodnar5bf9dc62019-05-24 09:20:04 -0700274
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
Valerie Haub019fd72019-05-23 12:50:12 -0700287void TestBufferLayer::fillBuffer(std::vector<IComposerClient::Color> expectedColors) {
John Reck82c666b2023-07-25 22:03:27 -0400288 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());
Valerie Haub019fd72019-05-23 12:50:12 -0700294}
Adam Bodnar5bf9dc62019-05-24 09:20:04 -0700295
Valerie Haub019fd72019-05-23 12:50:12 -0700296void TestBufferLayer::setBuffer(std::vector<IComposerClient::Color> colors) {
John Reck82c666b2023-07-25 22:03:27 -0400297 mBuffer = sp<GraphicBuffer>::make(mWidth, mHeight, (int32_t)mFormat, mLayerCount, mUsage);
298 ASSERT_EQ(STATUS_OK, mBuffer->initCheck());
Valerie Haub019fd72019-05-23 12:50:12 -0700299 ASSERT_NO_FATAL_FAILURE(fillBuffer(colors));
Valerie Haub019fd72019-05-23 12:50:12 -0700300}
301
Valerie Hau92d12262019-07-22 10:18:34 -0700302void TestBufferLayer::setDataspace(Dataspace dataspace,
303 const std::shared_ptr<CommandWriterBase>& writer) {
304 writer->selectLayer(mLayer);
305 writer->setLayerDataspace(dataspace);
306}
307
Valerie Haub019fd72019-05-23 12:50:12 -0700308void 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