blob: 777d02f415696bbef9d95c58f3b7313c7fe4d465 [file] [log] [blame]
Alec Mouri6e57f682018-09-29 20:45:08 -07001/*
2 * Copyright 2018 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
Ana Krulec82ba2ec2020-11-21 13:33:20 -080017#undef LOG_TAG
18#define LOG_TAG "RenderEngineTest"
19
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080020// TODO(b/129481165): remove the #pragma below and fix conversion issues
21#pragma clang diagnostic push
22#pragma clang diagnostic ignored "-Wconversion"
Marin Shalamanovbed7fd32020-12-21 20:02:20 +010023#pragma clang diagnostic ignored "-Wextra"
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080024
Lucas Dupin19c8f0e2019-11-25 17:55:44 -080025#include <cutils/properties.h>
Ana Krulec9bc9dc62020-02-26 12:16:40 -080026#include <gtest/gtest.h>
Alec Mouria90a5702021-04-16 16:36:21 +000027#include <renderengine/ExternalTexture.h>
Alec Mouri6e57f682018-09-29 20:45:08 -070028#include <renderengine/RenderEngine.h>
Vishnu Nairdbbe3852022-01-12 20:22:11 -080029#include <renderengine/impl/ExternalTexture.h>
Alec Mouri1089aed2018-10-25 21:33:57 -070030#include <sync/sync.h>
Alec Mouri4049b532021-10-15 20:59:33 -070031#include <system/graphics-base-v1.0.h>
32#include <tonemap/tonemap.h>
33#include <ui/ColorSpace.h>
Alec Mouri6e57f682018-09-29 20:45:08 -070034#include <ui/PixelFormat.h>
Alec Mouric0aae732021-01-12 13:32:18 -080035
36#include <chrono>
37#include <condition_variable>
38#include <fstream>
39
Alec Mouric0aae732021-01-12 13:32:18 -080040#include "../skia/SkiaGLRenderEngine.h"
Ana Krulec9bc9dc62020-02-26 12:16:40 -080041#include "../threaded/RenderEngineThreaded.h"
Alec Mouri6e57f682018-09-29 20:45:08 -070042
Alec Mouri1089aed2018-10-25 21:33:57 -070043constexpr int DEFAULT_DISPLAY_WIDTH = 128;
44constexpr int DEFAULT_DISPLAY_HEIGHT = 256;
45constexpr int DEFAULT_DISPLAY_OFFSET = 64;
Vishnu Nair16efdbf2019-12-10 11:55:42 -080046constexpr bool WRITE_BUFFER_TO_FILE_ON_FAILURE = false;
Alec Mouri1089aed2018-10-25 21:33:57 -070047
Alec Mouri6e57f682018-09-29 20:45:08 -070048namespace android {
Derek Sollenbergerd3f60652021-06-11 15:34:36 -040049namespace renderengine {
Alec Mouri6e57f682018-09-29 20:45:08 -070050
Alec Mouri5a493722022-01-26 16:43:02 -080051namespace {
52
53double EOTF_PQ(double channel) {
54 float m1 = (2610.0 / 4096.0) / 4.0;
55 float m2 = (2523.0 / 4096.0) * 128.0;
56 float c1 = (3424.0 / 4096.0);
57 float c2 = (2413.0 / 4096.0) * 32.0;
58 float c3 = (2392.0 / 4096.0) * 32.0;
59
60 float tmp = std::pow(std::clamp(channel, 0.0, 1.0), 1.0 / m2);
61 tmp = std::fmax(tmp - c1, 0.0) / (c2 - c3 * tmp);
62 return std::pow(tmp, 1.0 / m1);
63}
64
65vec3 EOTF_PQ(vec3 color) {
66 return vec3(EOTF_PQ(color.r), EOTF_PQ(color.g), EOTF_PQ(color.b));
67}
68
69double EOTF_HLG(double channel) {
70 const float a = 0.17883277;
71 const float b = 0.28466892;
72 const float c = 0.55991073;
73 return channel <= 0.5 ? channel * channel / 3.0 : (exp((channel - c) / a) + b) / 12.0;
74}
75
76vec3 EOTF_HLG(vec3 color) {
77 return vec3(EOTF_HLG(color.r), EOTF_HLG(color.g), EOTF_HLG(color.b));
78}
79
80double OETF_sRGB(double channel) {
81 return channel <= 0.0031308 ? channel * 12.92 : (pow(channel, 1.0 / 2.4) * 1.055) - 0.055;
82}
83
84int sign(float in) {
85 return in >= 0.0 ? 1 : -1;
86}
87
88vec3 OETF_sRGB(vec3 linear) {
89 return vec3(sign(linear.r) * OETF_sRGB(linear.r), sign(linear.g) * OETF_sRGB(linear.g),
90 sign(linear.b) * OETF_sRGB(linear.b));
91}
92
Alec Mouri9bcd1d12022-04-21 22:16:56 +000093// clang-format off
94// Converts red channels to green channels, and zeroes out an existing green channel.
95static const auto kRemoveGreenAndMoveRedToGreenMat4 = mat4(0, 1, 0, 0,
96 0, 0, 0, 0,
97 0, 0, 1, 0,
98 0, 0, 0, 1);
99// clang-format on
100
Alec Mouri5a493722022-01-26 16:43:02 -0800101} // namespace
102
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800103class RenderEngineFactory {
104public:
105 virtual ~RenderEngineFactory() = default;
106
107 virtual std::string name() = 0;
Alec Mouric0aae732021-01-12 13:32:18 -0800108 virtual renderengine::RenderEngine::RenderEngineType type() = 0;
109 virtual std::unique_ptr<renderengine::RenderEngine> createRenderEngine() = 0;
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400110 virtual bool useColorManagement() const = 0;
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800111};
112
Alec Mouri0eab3e82020-12-08 18:10:27 -0800113class SkiaGLESRenderEngineFactory : public RenderEngineFactory {
114public:
Alec Mouric0aae732021-01-12 13:32:18 -0800115 std::string name() override { return "SkiaGLRenderEngineFactory"; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800116
Alec Mouric0aae732021-01-12 13:32:18 -0800117 renderengine::RenderEngine::RenderEngineType type() {
118 return renderengine::RenderEngine::RenderEngineType::SKIA_GL;
119 }
120
121 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() override {
Alec Mouri0eab3e82020-12-08 18:10:27 -0800122 renderengine::RenderEngineCreationArgs reCreationArgs =
123 renderengine::RenderEngineCreationArgs::Builder()
124 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
125 .setImageCacheSize(1)
126 .setEnableProtectedContext(false)
127 .setPrecacheToneMapperShaderOnly(false)
128 .setSupportsBackgroundBlur(true)
129 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
Alec Mouric0aae732021-01-12 13:32:18 -0800130 .setRenderEngineType(type())
Alec Mourid2bcbae2021-06-28 17:02:17 -0700131 .setUseColorManagerment(useColorManagement())
Alec Mouri0eab3e82020-12-08 18:10:27 -0800132 .build();
Alec Mouric0aae732021-01-12 13:32:18 -0800133 return renderengine::skia::SkiaGLRenderEngine::create(reCreationArgs);
Alec Mouri0eab3e82020-12-08 18:10:27 -0800134 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400135
Alec Mourid2bcbae2021-06-28 17:02:17 -0700136 bool useColorManagement() const override { return false; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800137};
138
139class SkiaGLESCMRenderEngineFactory : public RenderEngineFactory {
140public:
Alec Mouric0aae732021-01-12 13:32:18 -0800141 std::string name() override { return "SkiaGLCMRenderEngineFactory"; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800142
Alec Mouric0aae732021-01-12 13:32:18 -0800143 renderengine::RenderEngine::RenderEngineType type() {
144 return renderengine::RenderEngine::RenderEngineType::SKIA_GL;
145 }
146
147 std::unique_ptr<renderengine::RenderEngine> createRenderEngine() override {
Alec Mouri0eab3e82020-12-08 18:10:27 -0800148 renderengine::RenderEngineCreationArgs reCreationArgs =
149 renderengine::RenderEngineCreationArgs::Builder()
150 .setPixelFormat(static_cast<int>(ui::PixelFormat::RGBA_8888))
151 .setImageCacheSize(1)
152 .setEnableProtectedContext(false)
153 .setPrecacheToneMapperShaderOnly(false)
154 .setSupportsBackgroundBlur(true)
155 .setContextPriority(renderengine::RenderEngine::ContextPriority::MEDIUM)
Alec Mouric0aae732021-01-12 13:32:18 -0800156 .setRenderEngineType(type())
Alec Mourid2bcbae2021-06-28 17:02:17 -0700157 .setUseColorManagerment(useColorManagement())
Alec Mouri0eab3e82020-12-08 18:10:27 -0800158 .build();
Alec Mouric0aae732021-01-12 13:32:18 -0800159 return renderengine::skia::SkiaGLRenderEngine::create(reCreationArgs);
Alec Mouri0eab3e82020-12-08 18:10:27 -0800160 }
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400161
162 bool useColorManagement() const override { return true; }
Alec Mouri0eab3e82020-12-08 18:10:27 -0800163};
164
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800165class RenderEngineTest : public ::testing::TestWithParam<std::shared_ptr<RenderEngineFactory>> {
166public:
Alec Mouria90a5702021-04-16 16:36:21 +0000167 std::shared_ptr<renderengine::ExternalTexture> allocateDefaultBuffer() {
168 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800169 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700170 ExternalTexture>(sp<GraphicBuffer>::
171 make(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT,
172 HAL_PIXEL_FORMAT_RGBA_8888, 1,
173 GRALLOC_USAGE_SW_READ_OFTEN |
174 GRALLOC_USAGE_SW_WRITE_OFTEN |
175 GRALLOC_USAGE_HW_RENDER |
176 GRALLOC_USAGE_HW_TEXTURE,
177 "output"),
Alec Mouria90a5702021-04-16 16:36:21 +0000178 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800179 renderengine::impl::ExternalTexture::Usage::READABLE |
180 renderengine::impl::ExternalTexture::Usage::
181 WRITEABLE);
Alec Mouri6e57f682018-09-29 20:45:08 -0700182 }
183
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800184 // Allocates a 1x1 buffer to fill with a solid color
Alec Mouria90a5702021-04-16 16:36:21 +0000185 std::shared_ptr<renderengine::ExternalTexture> allocateSourceBuffer(uint32_t width,
186 uint32_t height) {
187 return std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800188 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -0700189 ExternalTexture>(sp<GraphicBuffer>::
190 make(width, height, HAL_PIXEL_FORMAT_RGBA_8888, 1,
191 GRALLOC_USAGE_SW_READ_OFTEN |
192 GRALLOC_USAGE_SW_WRITE_OFTEN |
193 GRALLOC_USAGE_HW_TEXTURE,
194 "input"),
Alec Mouria90a5702021-04-16 16:36:21 +0000195 *mRE,
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800196 renderengine::impl::ExternalTexture::Usage::READABLE |
197 renderengine::impl::ExternalTexture::Usage::
198 WRITEABLE);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800199 }
200
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700201 std::shared_ptr<renderengine::ExternalTexture> allocateAndFillSourceBuffer(uint32_t width,
202 uint32_t height,
203 ubyte4 color) {
204 const auto buffer = allocateSourceBuffer(width, height);
205 uint8_t* pixels;
206 buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
207 reinterpret_cast<void**>(&pixels));
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500208 for (uint32_t j = 0; j < height; j++) {
209 uint8_t* dst = pixels + (buffer->getBuffer()->getStride() * j * 4);
210 for (uint32_t i = 0; i < width; i++) {
211 dst[0] = color.r;
212 dst[1] = color.g;
213 dst[2] = color.b;
214 dst[3] = color.a;
215 dst += 4;
216 }
217 }
Alec Mouricdf6cbc2021-11-01 17:21:15 -0700218 buffer->getBuffer()->unlock();
219 return buffer;
220 }
221
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500222 std::shared_ptr<renderengine::ExternalTexture> allocateR8Buffer(int width, int height) {
Ady Abrahamd11bade2022-08-01 16:18:03 -0700223 const auto kUsageFlags =
224 static_cast<uint64_t>(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
225 GRALLOC_USAGE_HW_TEXTURE);
226 auto buffer =
227 sp<GraphicBuffer>::make(static_cast<uint32_t>(width), static_cast<uint32_t>(height),
228 android::PIXEL_FORMAT_R_8, 1u, kUsageFlags, "r8");
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -0500229 if (buffer->initCheck() != 0) {
230 // Devices are not required to support R8.
231 return nullptr;
232 }
233 return std::make_shared<
234 renderengine::impl::ExternalTexture>(std::move(buffer), *mRE,
235 renderengine::impl::ExternalTexture::Usage::
236 READABLE);
237 }
238
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800239 RenderEngineTest() {
240 const ::testing::TestInfo* const test_info =
241 ::testing::UnitTest::GetInstance()->current_test_info();
242 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800243 }
Alec Mouri1089aed2018-10-25 21:33:57 -0700244
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800245 ~RenderEngineTest() {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800246 if (WRITE_BUFFER_TO_FILE_ON_FAILURE && ::testing::Test::HasFailure()) {
247 writeBufferToFile("/data/texture_out_");
248 }
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800249 for (uint32_t texName : mTexNames) {
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800250 mRE->deleteTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800251 }
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800252 const ::testing::TestInfo* const test_info =
253 ::testing::UnitTest::GetInstance()->current_test_info();
254 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800255 }
256
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800257 void writeBufferToFile(const char* basename) {
258 std::string filename(basename);
259 filename.append(::testing::UnitTest::GetInstance()->current_test_info()->name());
260 filename.append(".ppm");
261 std::ofstream file(filename.c_str(), std::ios::binary);
262 if (!file.is_open()) {
263 ALOGE("Unable to open file: %s", filename.c_str());
264 ALOGE("You may need to do: \"adb shell setenforce 0\" to enable "
265 "surfaceflinger to write debug images");
266 return;
267 }
268
Alec Mouri1089aed2018-10-25 21:33:57 -0700269 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000270 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
271 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700272
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800273 file << "P6\n";
Alec Mouria90a5702021-04-16 16:36:21 +0000274 file << mBuffer->getBuffer()->getWidth() << "\n";
275 file << mBuffer->getBuffer()->getHeight() << "\n";
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800276 file << 255 << "\n";
277
Alec Mouria90a5702021-04-16 16:36:21 +0000278 std::vector<uint8_t> outBuffer(mBuffer->getBuffer()->getWidth() *
279 mBuffer->getBuffer()->getHeight() * 3);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800280 auto outPtr = reinterpret_cast<uint8_t*>(outBuffer.data());
281
Alec Mouria90a5702021-04-16 16:36:21 +0000282 for (int32_t j = 0; j < mBuffer->getBuffer()->getHeight(); j++) {
283 const uint8_t* src = pixels + (mBuffer->getBuffer()->getStride() * j) * 4;
284 for (int32_t i = 0; i < mBuffer->getBuffer()->getWidth(); i++) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800285 // Only copy R, G and B components
286 outPtr[0] = src[0];
287 outPtr[1] = src[1];
288 outPtr[2] = src[2];
289 outPtr += 3;
290
291 src += 4;
292 }
293 }
294 file.write(reinterpret_cast<char*>(outBuffer.data()), outBuffer.size());
Alec Mouria90a5702021-04-16 16:36:21 +0000295 mBuffer->getBuffer()->unlock();
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800296 }
297
298 void expectBufferColor(const Region& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
299 size_t c;
300 Rect const* rect = region.getArray(&c);
301 for (size_t i = 0; i < c; i++, rect++) {
302 expectBufferColor(*rect, r, g, b, a);
303 }
304 }
305
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -0400306 void expectBufferColor(const Point& point, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
307 uint8_t tolerance = 0) {
308 expectBufferColor(Rect(point.x, point.y, point.x + 1, point.y + 1), r, g, b, a, tolerance);
309 }
310
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800311 void expectBufferColor(const Rect& rect, uint8_t r, uint8_t g, uint8_t b, uint8_t a,
312 uint8_t tolerance = 0) {
Alec Mouri4049b532021-10-15 20:59:33 -0700313 auto generator = [=](Point) { return ubyte4(r, g, b, a); };
314 expectBufferColor(rect, generator, tolerance);
315 }
316
317 using ColorGenerator = std::function<ubyte4(Point location)>;
318
319 void expectBufferColor(const Rect& rect, ColorGenerator generator, uint8_t tolerance = 0) {
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800320 auto colorCompare = [tolerance](const uint8_t* colorA, const uint8_t* colorB) {
321 auto colorBitCompare = [tolerance](uint8_t a, uint8_t b) {
322 uint8_t tmp = a >= b ? a - b : b - a;
323 return tmp <= tolerance;
324 };
325 return std::equal(colorA, colorA + 4, colorB, colorBitCompare);
Alec Mouri1089aed2018-10-25 21:33:57 -0700326 };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800327
Alec Mouri4049b532021-10-15 20:59:33 -0700328 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800329 }
330
Alec Mouri4049b532021-10-15 20:59:33 -0700331 void expectBufferColor(const Rect& region, ColorGenerator generator,
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800332 std::function<bool(const uint8_t* a, const uint8_t* b)> colorCompare) {
333 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000334 mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
335 reinterpret_cast<void**>(&pixels));
Alec Mouri1089aed2018-10-25 21:33:57 -0700336 int32_t maxFails = 10;
337 int32_t fails = 0;
338 for (int32_t j = 0; j < region.getHeight(); j++) {
Alec Mouria90a5702021-04-16 16:36:21 +0000339 const uint8_t* src = pixels +
340 (mBuffer->getBuffer()->getStride() * (region.top + j) + region.left) * 4;
Alec Mouri1089aed2018-10-25 21:33:57 -0700341 for (int32_t i = 0; i < region.getWidth(); i++) {
Alec Mouri4049b532021-10-15 20:59:33 -0700342 const auto location = Point(region.left + i, region.top + j);
343 const ubyte4 colors = generator(location);
344 const uint8_t expected[4] = {colors.r, colors.g, colors.b, colors.a};
345 bool colorMatches = colorCompare(src, expected);
346 EXPECT_TRUE(colorMatches)
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -0400347 << GetParam()->name().c_str() << ": "
Alec Mouri4049b532021-10-15 20:59:33 -0700348 << "pixel @ (" << location.x << ", " << location.y << "): "
349 << "expected (" << static_cast<uint32_t>(colors.r) << ", "
350 << static_cast<uint32_t>(colors.g) << ", "
351 << static_cast<uint32_t>(colors.b) << ", "
352 << static_cast<uint32_t>(colors.a) << "), "
Alec Mouri1089aed2018-10-25 21:33:57 -0700353 << "got (" << static_cast<uint32_t>(src[0]) << ", "
354 << static_cast<uint32_t>(src[1]) << ", " << static_cast<uint32_t>(src[2])
355 << ", " << static_cast<uint32_t>(src[3]) << ")";
356 src += 4;
Alec Mouri4049b532021-10-15 20:59:33 -0700357 if (!colorMatches && ++fails >= maxFails) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700358 break;
359 }
360 }
361 if (fails >= maxFails) {
362 break;
363 }
364 }
Alec Mouria90a5702021-04-16 16:36:21 +0000365 mBuffer->getBuffer()->unlock();
Alec Mouri1089aed2018-10-25 21:33:57 -0700366 }
367
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800368 void expectAlpha(const Rect& rect, uint8_t a) {
Alec Mouri4049b532021-10-15 20:59:33 -0700369 auto generator = [=](Point) { return ubyte4(0, 0, 0, a); };
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800370 auto colorCompare = [](const uint8_t* colorA, const uint8_t* colorB) {
371 return colorA[3] == colorB[3];
372 };
Alec Mouri4049b532021-10-15 20:59:33 -0700373 expectBufferColor(rect, generator, colorCompare);
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800374 }
375
376 void expectShadowColor(const renderengine::LayerSettings& castingLayer,
377 const renderengine::ShadowSettings& shadow, const ubyte4& casterColor,
378 const ubyte4& backgroundColor) {
379 const Rect casterRect(castingLayer.geometry.boundaries);
380 Region casterRegion = Region(casterRect);
Vishnu Nair50c0afe2022-07-11 15:04:07 -0700381 const float casterCornerRadius = (castingLayer.geometry.roundedCornersRadius.x +
382 castingLayer.geometry.roundedCornersRadius.y) /
383 2.0;
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800384 if (casterCornerRadius > 0.0f) {
385 // ignore the corners if a corner radius is set
386 Rect cornerRect(casterCornerRadius, casterCornerRadius);
387 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.left, casterRect.top));
388 casterRegion.subtractSelf(
389 cornerRect.offsetTo(casterRect.right - casterCornerRadius, casterRect.top));
390 casterRegion.subtractSelf(
391 cornerRect.offsetTo(casterRect.left, casterRect.bottom - casterCornerRadius));
392 casterRegion.subtractSelf(cornerRect.offsetTo(casterRect.right - casterCornerRadius,
393 casterRect.bottom - casterCornerRadius));
394 }
395
396 const float shadowInset = shadow.length * -1.0f;
397 const Rect casterWithShadow =
398 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
399 const Region shadowRegion = Region(casterWithShadow).subtractSelf(casterRect);
400 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
401
402 // verify casting layer
403 expectBufferColor(casterRegion, casterColor.r, casterColor.g, casterColor.b, casterColor.a);
404
405 // verify shadows by testing just the alpha since its difficult to validate the shadow color
406 size_t c;
407 Rect const* r = shadowRegion.getArray(&c);
408 for (size_t i = 0; i < c; i++, r++) {
409 expectAlpha(*r, 255);
410 }
411
412 // verify background
413 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
414 backgroundColor.a);
415 }
416
Alec Mouribd17b3b2020-12-17 11:08:30 -0800417 void expectShadowColorWithoutCaster(const FloatRect& casterBounds,
418 const renderengine::ShadowSettings& shadow,
419 const ubyte4& backgroundColor) {
420 const float shadowInset = shadow.length * -1.0f;
421 const Rect casterRect(casterBounds);
422 const Rect shadowRect =
423 Rect(casterRect).inset(shadowInset, shadowInset, shadowInset, shadowInset);
424
425 const Region backgroundRegion =
426 Region(fullscreenRect()).subtractSelf(casterRect).subtractSelf(shadowRect);
427
428 expectAlpha(shadowRect, 255);
429 // (0, 0, 0) fill on the bounds of the layer should be ignored.
430 expectBufferColor(casterRect, 255, 255, 255, 255, 254);
431
432 // verify background
433 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
434 backgroundColor.a);
435 }
436
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800437 static renderengine::ShadowSettings getShadowSettings(const vec2& casterPos, float shadowLength,
438 bool casterIsTranslucent) {
439 renderengine::ShadowSettings shadow;
440 shadow.ambientColor = {0.0f, 0.0f, 0.0f, 0.039f};
441 shadow.spotColor = {0.0f, 0.0f, 0.0f, 0.19f};
442 shadow.lightPos = vec3(casterPos.x, casterPos.y, 0);
443 shadow.lightRadius = 0.0f;
444 shadow.length = shadowLength;
445 shadow.casterIsTranslucent = casterIsTranslucent;
446 return shadow;
447 }
448
Alec Mouri1089aed2018-10-25 21:33:57 -0700449 static Rect fullscreenRect() { return Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT); }
450
451 static Rect offsetRect() {
452 return Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
453 DEFAULT_DISPLAY_HEIGHT);
454 }
455
456 static Rect offsetRectAtZero() {
457 return Rect(DEFAULT_DISPLAY_WIDTH - DEFAULT_DISPLAY_OFFSET,
458 DEFAULT_DISPLAY_HEIGHT - DEFAULT_DISPLAY_OFFSET);
459 }
460
Sally Qi59a9f502021-10-12 18:53:23 +0000461 void invokeDraw(const renderengine::DisplaySettings& settings,
462 const std::vector<renderengine::LayerSettings>& layers) {
Patrick Williams2e9748f2022-08-09 22:48:18 +0000463 ftl::Future<FenceResult> future =
Sally Qi4cabdd02021-08-05 16:45:57 -0700464 mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +0000465 ASSERT_TRUE(future.valid());
Sally Qi59a9f502021-10-12 18:53:23 +0000466
Patrick Williams2e9748f2022-08-09 22:48:18 +0000467 auto result = future.get();
468 ASSERT_TRUE(result.ok());
Alec Mouri1089aed2018-10-25 21:33:57 -0700469
Patrick Williams2e9748f2022-08-09 22:48:18 +0000470 auto fence = result.value();
471 fence->waitForever(LOG_TAG);
Alec Mouri1089aed2018-10-25 21:33:57 -0700472 }
473
Alec Mourid43ccab2019-03-13 12:23:45 -0700474 void drawEmptyLayers() {
Alec Mouri6e57f682018-09-29 20:45:08 -0700475 renderengine::DisplaySettings settings;
Sally Qi59a9f502021-10-12 18:53:23 +0000476 std::vector<renderengine::LayerSettings> layers;
Alec Mouric0aae732021-01-12 13:32:18 -0800477 invokeDraw(settings, layers);
Alec Mouri6e57f682018-09-29 20:45:08 -0700478 }
479
Alec Mouri1089aed2018-10-25 21:33:57 -0700480 template <typename SourceVariant>
481 void fillBuffer(half r, half g, half b, half a);
482
483 template <typename SourceVariant>
484 void fillRedBuffer();
485
486 template <typename SourceVariant>
487 void fillGreenBuffer();
488
489 template <typename SourceVariant>
490 void fillBlueBuffer();
491
492 template <typename SourceVariant>
493 void fillRedTransparentBuffer();
494
495 template <typename SourceVariant>
496 void fillRedOffsetBuffer();
497
498 template <typename SourceVariant>
499 void fillBufferPhysicalOffset();
500
501 template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700502 void fillBufferCheckers(uint32_t rotation);
Alec Mouri1089aed2018-10-25 21:33:57 -0700503
504 template <typename SourceVariant>
505 void fillBufferCheckersRotate0();
506
507 template <typename SourceVariant>
508 void fillBufferCheckersRotate90();
509
510 template <typename SourceVariant>
511 void fillBufferCheckersRotate180();
512
513 template <typename SourceVariant>
514 void fillBufferCheckersRotate270();
515
516 template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800517 void fillBufferWithLayerTransform();
518
519 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700520 void fillBufferLayerTransform();
521
522 template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800523 void fillBufferWithColorTransform();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800524
525 template <typename SourceVariant>
Alec Mouri1089aed2018-10-25 21:33:57 -0700526 void fillBufferColorTransform();
527
Alec Mouri7c94edb2018-12-03 21:23:26 -0800528 template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800529 void fillBufferWithColorTransformAndSourceDataspace(const ui::Dataspace sourceDataspace);
530
531 template <typename SourceVariant>
532 void fillBufferColorTransformAndSourceDataspace();
533
534 template <typename SourceVariant>
535 void fillBufferWithColorTransformAndOutputDataspace(const ui::Dataspace outputDataspace);
536
537 template <typename SourceVariant>
538 void fillBufferColorTransformAndOutputDataspace();
539
540 template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +0800541 void fillBufferWithColorTransformZeroLayerAlpha();
542
543 template <typename SourceVariant>
544 void fillBufferColorTransformZeroLayerAlpha();
545
546 template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -0800547 void fillRedBufferWithRoundedCorners();
548
549 template <typename SourceVariant>
550 void fillBufferWithRoundedCorners();
551
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000552 template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -0800553 void fillBufferAndBlurBackground();
554
555 template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -0700556 void fillSmallLayerAndBlurBackground();
557
558 template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000559 void overlayCorners();
560
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800561 void fillRedBufferTextureTransform();
562
563 void fillBufferTextureTransform();
564
565 void fillRedBufferWithPremultiplyAlpha();
566
567 void fillBufferWithPremultiplyAlpha();
568
569 void fillRedBufferWithoutPremultiplyAlpha();
570
571 void fillBufferWithoutPremultiplyAlpha();
572
Alec Mouriac335532018-11-12 15:01:33 -0800573 void fillGreenColorBufferThenClearRegion();
574
Vishnu Nair16efdbf2019-12-10 11:55:42 -0800575 template <typename SourceVariant>
576 void drawShadow(const renderengine::LayerSettings& castingLayer,
577 const renderengine::ShadowSettings& shadow, const ubyte4& casterColor,
578 const ubyte4& backgroundColor);
579
Alec Mouribd17b3b2020-12-17 11:08:30 -0800580 void drawShadowWithoutCaster(const FloatRect& castingBounds,
581 const renderengine::ShadowSettings& shadow,
582 const ubyte4& backgroundColor);
583
Alec Mouri5a493722022-01-26 16:43:02 -0800584 // Tonemaps grey values from sourceDataspace -> Display P3 and checks that GPU and CPU
585 // implementations are identical Also implicitly checks that the injected tonemap shader
586 // compiles
587 void tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
588 std::function<vec3(vec3, float)> scaleOotf);
589
Alec Mouric0aae732021-01-12 13:32:18 -0800590 void initializeRenderEngine();
591
592 std::unique_ptr<renderengine::RenderEngine> mRE;
Alec Mouria90a5702021-04-16 16:36:21 +0000593 std::shared_ptr<renderengine::ExternalTexture> mBuffer;
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800594
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800595 std::vector<uint32_t> mTexNames;
Alec Mouri6e57f682018-09-29 20:45:08 -0700596};
597
Alec Mouric0aae732021-01-12 13:32:18 -0800598void RenderEngineTest::initializeRenderEngine() {
599 const auto& renderEngineFactory = GetParam();
Alec Mouric16974e2022-09-13 17:35:48 +0000600 mRE = renderEngineFactory->createRenderEngine();
Alec Mouria90a5702021-04-16 16:36:21 +0000601 mBuffer = allocateDefaultBuffer();
Alec Mouric0aae732021-01-12 13:32:18 -0800602}
603
Alec Mouri1089aed2018-10-25 21:33:57 -0700604struct ColorSourceVariant {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800605 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800606 RenderEngineTest* /*fixture*/) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700607 layer.source.solidColor = half3(r, g, b);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800608 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700609 }
610};
611
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800612struct RelaxOpaqueBufferVariant {
613 static void setOpaqueBit(renderengine::LayerSettings& layer) {
614 layer.source.buffer.isOpaque = false;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800615 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800616 }
617
618 static uint8_t getAlphaChannel() { return 255; }
619};
620
621struct ForceOpaqueBufferVariant {
622 static void setOpaqueBit(renderengine::LayerSettings& layer) {
623 layer.source.buffer.isOpaque = true;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800624 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800625 }
626
627 static uint8_t getAlphaChannel() {
628 // The isOpaque bit will override the alpha channel, so this should be
629 // arbitrary.
Alec Mouric0aae732021-01-12 13:32:18 -0800630 return 50;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800631 }
632};
633
634template <typename OpaquenessVariant>
635struct BufferSourceVariant {
636 static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b,
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800637 RenderEngineTest* fixture) {
Alec Mouria90a5702021-04-16 16:36:21 +0000638 const auto buf = fixture->allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800639 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800640 fixture->mRE->genTextures(1, &texName);
641 fixture->mTexNames.push_back(texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800642
643 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +0000644 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
645 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800646
Alec Mouria90a5702021-04-16 16:36:21 +0000647 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
648 uint8_t* iter = pixels + (buf->getBuffer()->getStride() * j) * 4;
649 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800650 iter[0] = uint8_t(r * 255);
651 iter[1] = uint8_t(g * 255);
652 iter[2] = uint8_t(b * 255);
653 iter[3] = OpaquenessVariant::getAlphaChannel();
654 iter += 4;
655 }
656 }
657
Alec Mouria90a5702021-04-16 16:36:21 +0000658 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800659
660 layer.source.buffer.buffer = buf;
661 layer.source.buffer.textureName = texName;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800662 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800663 OpaquenessVariant::setOpaqueBit(layer);
664 }
665};
666
Alec Mouri1089aed2018-10-25 21:33:57 -0700667template <typename SourceVariant>
668void RenderEngineTest::fillBuffer(half r, half g, half b, half a) {
669 renderengine::DisplaySettings settings;
670 settings.physicalDisplay = fullscreenRect();
671 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800672 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700673
Sally Qi59a9f502021-10-12 18:53:23 +0000674 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700675
676 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800677 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700678 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800679 SourceVariant::fillColor(layer, r, g, b, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700680 layer.alpha = a;
681
Sally Qi59a9f502021-10-12 18:53:23 +0000682 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700683
Alec Mouric0aae732021-01-12 13:32:18 -0800684 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700685}
686
687template <typename SourceVariant>
688void RenderEngineTest::fillRedBuffer() {
689 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, 1.0f);
690 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
691}
692
693template <typename SourceVariant>
694void RenderEngineTest::fillGreenBuffer() {
695 fillBuffer<SourceVariant>(0.0f, 1.0f, 0.0f, 1.0f);
696 expectBufferColor(fullscreenRect(), 0, 255, 0, 255);
697}
698
699template <typename SourceVariant>
700void RenderEngineTest::fillBlueBuffer() {
701 fillBuffer<SourceVariant>(0.0f, 0.0f, 1.0f, 1.0f);
702 expectBufferColor(fullscreenRect(), 0, 0, 255, 255);
703}
704
705template <typename SourceVariant>
706void RenderEngineTest::fillRedTransparentBuffer() {
707 fillBuffer<SourceVariant>(1.0f, 0.0f, 0.0f, .2f);
708 expectBufferColor(fullscreenRect(), 51, 0, 0, 51);
709}
710
711template <typename SourceVariant>
712void RenderEngineTest::fillRedOffsetBuffer() {
713 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800714 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700715 settings.physicalDisplay = offsetRect();
716 settings.clip = offsetRectAtZero();
717
Sally Qi59a9f502021-10-12 18:53:23 +0000718 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700719
720 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800721 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700722 layer.geometry.boundaries = offsetRectAtZero().toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800723 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700724 layer.alpha = 1.0f;
725
Sally Qi59a9f502021-10-12 18:53:23 +0000726 layers.push_back(layer);
Alec Mouric0aae732021-01-12 13:32:18 -0800727 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700728}
729
730template <typename SourceVariant>
731void RenderEngineTest::fillBufferPhysicalOffset() {
732 fillRedOffsetBuffer<SourceVariant>();
733
734 expectBufferColor(Rect(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_WIDTH,
735 DEFAULT_DISPLAY_HEIGHT),
736 255, 0, 0, 255);
737 Rect offsetRegionLeft(DEFAULT_DISPLAY_OFFSET, DEFAULT_DISPLAY_HEIGHT);
738 Rect offsetRegionTop(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_OFFSET);
739
740 expectBufferColor(offsetRegionLeft, 0, 0, 0, 0);
741 expectBufferColor(offsetRegionTop, 0, 0, 0, 0);
742}
743
744template <typename SourceVariant>
Alec Mouri5a6d8572020-03-23 23:56:15 -0700745void RenderEngineTest::fillBufferCheckers(uint32_t orientationFlag) {
Alec Mouri1089aed2018-10-25 21:33:57 -0700746 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800747 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700748 settings.physicalDisplay = fullscreenRect();
749 // Here logical space is 2x2
750 settings.clip = Rect(2, 2);
Alec Mouri5a6d8572020-03-23 23:56:15 -0700751 settings.orientation = orientationFlag;
Alec Mouri1089aed2018-10-25 21:33:57 -0700752
Sally Qi59a9f502021-10-12 18:53:23 +0000753 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700754
755 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800756 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700757 Rect rectOne(0, 0, 1, 1);
758 layerOne.geometry.boundaries = rectOne.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800759 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700760 layerOne.alpha = 1.0f;
761
762 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800763 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700764 Rect rectTwo(0, 1, 1, 2);
765 layerTwo.geometry.boundaries = rectTwo.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800766 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700767 layerTwo.alpha = 1.0f;
768
769 renderengine::LayerSettings layerThree;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800770 layerThree.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700771 Rect rectThree(1, 0, 2, 1);
772 layerThree.geometry.boundaries = rectThree.toFloatRect();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800773 SourceVariant::fillColor(layerThree, 0.0f, 0.0f, 1.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700774 layerThree.alpha = 1.0f;
775
Sally Qi59a9f502021-10-12 18:53:23 +0000776 layers.push_back(layerOne);
777 layers.push_back(layerTwo);
778 layers.push_back(layerThree);
Alec Mouri1089aed2018-10-25 21:33:57 -0700779
Alec Mouric0aae732021-01-12 13:32:18 -0800780 invokeDraw(settings, layers);
Alec Mouri1089aed2018-10-25 21:33:57 -0700781}
782
783template <typename SourceVariant>
784void RenderEngineTest::fillBufferCheckersRotate0() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700785 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_0);
Alec Mouri1089aed2018-10-25 21:33:57 -0700786 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0,
787 255);
788 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
789 DEFAULT_DISPLAY_HEIGHT / 2),
790 0, 0, 255, 255);
791 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
792 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
793 0, 0, 0, 0);
794 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
795 DEFAULT_DISPLAY_HEIGHT),
796 0, 255, 0, 255);
797}
798
799template <typename SourceVariant>
800void RenderEngineTest::fillBufferCheckersRotate90() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700801 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_90);
Alec Mouri1089aed2018-10-25 21:33:57 -0700802 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 255, 0,
803 255);
804 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
805 DEFAULT_DISPLAY_HEIGHT / 2),
806 255, 0, 0, 255);
807 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
808 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
809 0, 0, 255, 255);
810 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
811 DEFAULT_DISPLAY_HEIGHT),
812 0, 0, 0, 0);
813}
814
815template <typename SourceVariant>
816void RenderEngineTest::fillBufferCheckersRotate180() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700817 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_180);
Alec Mouri1089aed2018-10-25 21:33:57 -0700818 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0,
819 0);
820 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
821 DEFAULT_DISPLAY_HEIGHT / 2),
822 0, 255, 0, 255);
823 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
824 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
825 255, 0, 0, 255);
826 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
827 DEFAULT_DISPLAY_HEIGHT),
828 0, 0, 255, 255);
829}
830
831template <typename SourceVariant>
832void RenderEngineTest::fillBufferCheckersRotate270() {
Alec Mouri5a6d8572020-03-23 23:56:15 -0700833 fillBufferCheckers<SourceVariant>(ui::Transform::ROT_270);
Alec Mouri1089aed2018-10-25 21:33:57 -0700834 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 255,
835 255);
836 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
837 DEFAULT_DISPLAY_HEIGHT / 2),
838 0, 0, 0, 0);
839 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
840 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
841 0, 255, 0, 255);
842 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT / 2, DEFAULT_DISPLAY_WIDTH / 2,
843 DEFAULT_DISPLAY_HEIGHT),
844 255, 0, 0, 255);
845}
846
847template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800848void RenderEngineTest::fillBufferWithLayerTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700849 renderengine::DisplaySettings settings;
850 settings.physicalDisplay = fullscreenRect();
851 // Here logical space is 2x2
852 settings.clip = Rect(2, 2);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800853 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700854
Sally Qi59a9f502021-10-12 18:53:23 +0000855 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700856
857 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800858 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700859 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
860 // Translate one pixel diagonally
861 layer.geometry.positionTransform = mat4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800862 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700863 layer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
864 layer.alpha = 1.0f;
865
Sally Qi59a9f502021-10-12 18:53:23 +0000866 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700867
Alec Mouric0aae732021-01-12 13:32:18 -0800868 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800869}
Alec Mouri1089aed2018-10-25 21:33:57 -0700870
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800871template <typename SourceVariant>
872void RenderEngineTest::fillBufferLayerTransform() {
873 fillBufferWithLayerTransform<SourceVariant>();
Alec Mouri1089aed2018-10-25 21:33:57 -0700874 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2), 0, 0, 0, 0);
875 expectBufferColor(Rect(0, 0, DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
876 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2,
877 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
878 255, 0, 0, 255);
879}
880
881template <typename SourceVariant>
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800882void RenderEngineTest::fillBufferWithColorTransform() {
Alec Mouri1089aed2018-10-25 21:33:57 -0700883 renderengine::DisplaySettings settings;
884 settings.physicalDisplay = fullscreenRect();
885 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800886 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700887
Sally Qi59a9f502021-10-12 18:53:23 +0000888 std::vector<renderengine::LayerSettings> layers;
Alec Mouri1089aed2018-10-25 21:33:57 -0700889
890 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -0800891 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri1089aed2018-10-25 21:33:57 -0700892 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
Ana Krulec82ba2ec2020-11-21 13:33:20 -0800893 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouri1089aed2018-10-25 21:33:57 -0700894 layer.alpha = 1.0f;
895
896 // construct a fake color matrix
897 // annihilate green and blue channels
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800898 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
Alec Mouri1089aed2018-10-25 21:33:57 -0700899 // set red channel to red + green
900 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
901
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800902 layer.alpha = 1.0f;
903 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
904
Sally Qi59a9f502021-10-12 18:53:23 +0000905 layers.push_back(layer);
Alec Mouri1089aed2018-10-25 21:33:57 -0700906
Alec Mouric0aae732021-01-12 13:32:18 -0800907 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800908}
Alec Mouri1089aed2018-10-25 21:33:57 -0700909
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800910template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800911void RenderEngineTest::fillBufferWithColorTransformAndSourceDataspace(
912 const ui::Dataspace sourceDataspace) {
913 renderengine::DisplaySettings settings;
914 settings.physicalDisplay = fullscreenRect();
915 settings.clip = Rect(1, 1);
916 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
917
918 std::vector<renderengine::LayerSettings> layers;
919
920 renderengine::LayerSettings layer;
Sally Qi2019fd22021-11-22 10:19:04 -0800921 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
922 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
Alec Mouric16974e2022-09-13 17:35:48 +0000923 layer.sourceDataspace = sourceDataspace;
Sally Qi2019fd22021-11-22 10:19:04 -0800924 layer.alpha = 1.0f;
925
926 // construct a fake color matrix
927 // annihilate green and blue channels
928 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
929 // set red channel to red + green
930 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
931
932 layer.alpha = 1.0f;
933 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
934
935 layers.push_back(layer);
936
937 invokeDraw(settings, layers);
938}
939
940template <typename SourceVariant>
Alec Mouri0d5e1eb2018-11-10 20:40:12 -0800941void RenderEngineTest::fillBufferColorTransform() {
942 fillBufferWithColorTransform<SourceVariant>();
KaiChieh Chuang436fc192020-09-07 13:48:42 +0800943 expectBufferColor(fullscreenRect(), 172, 0, 0, 255, 1);
944}
945
946template <typename SourceVariant>
Sally Qi2019fd22021-11-22 10:19:04 -0800947void RenderEngineTest::fillBufferColorTransformAndSourceDataspace() {
948 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +0000949 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {77, 0, 0, 255};
950 dataspaceToColorMap[ui::Dataspace::BT2020] = {101, 0, 0, 255};
951 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {75, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800952 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
953 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_2 |
954 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +0000955 dataspaceToColorMap[customizedDataspace] = {61, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800956 for (const auto& [sourceDataspace, color] : dataspaceToColorMap) {
957 fillBufferWithColorTransformAndSourceDataspace<SourceVariant>(sourceDataspace);
958 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
959 }
960}
961
962template <typename SourceVariant>
963void RenderEngineTest::fillBufferWithColorTransformAndOutputDataspace(
964 const ui::Dataspace outputDataspace) {
965 renderengine::DisplaySettings settings;
966 settings.physicalDisplay = fullscreenRect();
967 settings.clip = Rect(1, 1);
968 settings.outputDataspace = outputDataspace;
969
970 std::vector<renderengine::LayerSettings> layers;
971
972 renderengine::LayerSettings layer;
973 layer.sourceDataspace = ui::Dataspace::V0_SCRGB_LINEAR;
974 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
975 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
976 layer.alpha = 1.0f;
977
978 // construct a fake color matrix
979 // annihilate green and blue channels
980 settings.colorTransform = mat4::scale(vec4(0.9f, 0, 0, 1));
981 // set red channel to red + green
982 layer.colorTransform = mat4(1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
983
984 layer.alpha = 1.0f;
985 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
986
987 layers.push_back(layer);
988
989 invokeDraw(settings, layers);
990}
991
992template <typename SourceVariant>
993void RenderEngineTest::fillBufferColorTransformAndOutputDataspace() {
994 unordered_map<ui::Dataspace, ubyte4> dataspaceToColorMap;
Alec Mouric16974e2022-09-13 17:35:48 +0000995 dataspaceToColorMap[ui::Dataspace::V0_BT709] = {198, 0, 0, 255};
996 dataspaceToColorMap[ui::Dataspace::BT2020] = {187, 0, 0, 255};
997 dataspaceToColorMap[ui::Dataspace::ADOBE_RGB] = {192, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -0800998 ui::Dataspace customizedDataspace = static_cast<ui::Dataspace>(
999 ui::Dataspace::STANDARD_BT709 | ui::Dataspace::TRANSFER_GAMMA2_6 |
1000 ui::Dataspace::RANGE_FULL);
Alec Mouric16974e2022-09-13 17:35:48 +00001001 dataspaceToColorMap[customizedDataspace] = {205, 0, 0, 255};
Sally Qi2019fd22021-11-22 10:19:04 -08001002 for (const auto& [outputDataspace, color] : dataspaceToColorMap) {
1003 fillBufferWithColorTransformAndOutputDataspace<SourceVariant>(outputDataspace);
1004 expectBufferColor(fullscreenRect(), color.r, color.g, color.b, color.a, 1);
1005 }
1006}
1007
1008template <typename SourceVariant>
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001009void RenderEngineTest::fillBufferWithColorTransformZeroLayerAlpha() {
1010 renderengine::DisplaySettings settings;
1011 settings.physicalDisplay = fullscreenRect();
1012 settings.clip = Rect(1, 1);
1013
Sally Qi59a9f502021-10-12 18:53:23 +00001014 std::vector<renderengine::LayerSettings> layers;
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001015
1016 renderengine::LayerSettings layer;
1017 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1018 SourceVariant::fillColor(layer, 0.5f, 0.25f, 0.125f, this);
1019 layer.alpha = 0;
1020
1021 // construct a fake color matrix
1022 // simple inverse color
1023 settings.colorTransform = mat4(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 1, 1, 1, 1);
1024
1025 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1026
Sally Qi59a9f502021-10-12 18:53:23 +00001027 layers.push_back(layer);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001028
Alec Mouric0aae732021-01-12 13:32:18 -08001029 invokeDraw(settings, layers);
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001030}
1031
1032template <typename SourceVariant>
1033void RenderEngineTest::fillBufferColorTransformZeroLayerAlpha() {
1034 fillBufferWithColorTransformZeroLayerAlpha<SourceVariant>();
1035 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1036}
1037
1038template <typename SourceVariant>
Alec Mouri7c94edb2018-12-03 21:23:26 -08001039void RenderEngineTest::fillRedBufferWithRoundedCorners() {
1040 renderengine::DisplaySettings settings;
1041 settings.physicalDisplay = fullscreenRect();
1042 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001043 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001044
Sally Qi59a9f502021-10-12 18:53:23 +00001045 std::vector<renderengine::LayerSettings> layers;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001046
1047 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001048 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri7c94edb2018-12-03 21:23:26 -08001049 layer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07001050 layer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Alec Mouri7c94edb2018-12-03 21:23:26 -08001051 layer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
1052 SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
1053 layer.alpha = 1.0f;
1054
Sally Qi59a9f502021-10-12 18:53:23 +00001055 layers.push_back(layer);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001056
Alec Mouric0aae732021-01-12 13:32:18 -08001057 invokeDraw(settings, layers);
Alec Mouri7c94edb2018-12-03 21:23:26 -08001058}
1059
1060template <typename SourceVariant>
1061void RenderEngineTest::fillBufferWithRoundedCorners() {
1062 fillRedBufferWithRoundedCorners<SourceVariant>();
1063 // Corners should be ignored...
1064 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
1065 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
1066 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
1067 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
1068 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1069 0, 0, 0, 0);
1070 // ...And the non-rounded portion should be red.
1071 // Other pixels may be anti-aliased, so let's not check those.
1072 expectBufferColor(Rect(5, 5, DEFAULT_DISPLAY_WIDTH - 5, DEFAULT_DISPLAY_HEIGHT - 5), 255, 0, 0,
1073 255);
1074}
1075
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001076template <typename SourceVariant>
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001077void RenderEngineTest::fillBufferAndBlurBackground() {
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001078 auto blurRadius = 50;
1079 auto center = DEFAULT_DISPLAY_WIDTH / 2;
1080
1081 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001082 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001083 settings.physicalDisplay = fullscreenRect();
1084 settings.clip = fullscreenRect();
1085
Sally Qi59a9f502021-10-12 18:53:23 +00001086 std::vector<renderengine::LayerSettings> layers;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001087
1088 renderengine::LayerSettings backgroundLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001089 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001090 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1091 SourceVariant::fillColor(backgroundLayer, 0.0f, 1.0f, 0.0f, this);
1092 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001093 layers.emplace_back(backgroundLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001094
1095 renderengine::LayerSettings leftLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001096 leftLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001097 leftLayer.geometry.boundaries =
1098 Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT).toFloatRect();
1099 SourceVariant::fillColor(leftLayer, 1.0f, 0.0f, 0.0f, this);
1100 leftLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001101 layers.emplace_back(leftLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001102
1103 renderengine::LayerSettings blurLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001104 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001105 blurLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1106 blurLayer.backgroundBlurRadius = blurRadius;
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001107 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001108 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001109 layers.emplace_back(blurLayer);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001110
Alec Mouric0aae732021-01-12 13:32:18 -08001111 invokeDraw(settings, layers);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001112
Derek Sollenbergerecb21462021-01-29 16:53:49 -05001113 // solid color
1114 expectBufferColor(Rect(0, 0, 1, 1), 255, 0, 0, 255, 0 /* tolerance */);
1115
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001116 if (mRE->supportsBackgroundBlur()) {
1117 // blurred color (downsampling should result in the center color being close to 128)
1118 expectBufferColor(Rect(center - 1, center - 5, center + 1, center + 5), 128, 128, 0, 255,
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001119 50 /* tolerance */);
Derek Sollenbergerb3998372021-02-16 15:16:56 -05001120 }
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001121}
1122
1123template <typename SourceVariant>
Alec Mourie8489fd2021-04-29 16:08:56 -07001124void RenderEngineTest::fillSmallLayerAndBlurBackground() {
1125 auto blurRadius = 50;
1126 renderengine::DisplaySettings settings;
1127 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1128 settings.physicalDisplay = fullscreenRect();
1129 settings.clip = fullscreenRect();
1130
Sally Qi59a9f502021-10-12 18:53:23 +00001131 std::vector<renderengine::LayerSettings> layers;
Alec Mourie8489fd2021-04-29 16:08:56 -07001132
1133 renderengine::LayerSettings backgroundLayer;
1134 backgroundLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1135 backgroundLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1136 SourceVariant::fillColor(backgroundLayer, 1.0f, 0.0f, 0.0f, this);
1137 backgroundLayer.alpha = 1.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001138 layers.push_back(backgroundLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001139
1140 renderengine::LayerSettings blurLayer;
1141 blurLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1142 blurLayer.geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f);
1143 blurLayer.backgroundBlurRadius = blurRadius;
1144 SourceVariant::fillColor(blurLayer, 0.0f, 0.0f, 1.0f, this);
1145 blurLayer.alpha = 0;
Sally Qi59a9f502021-10-12 18:53:23 +00001146 layers.push_back(blurLayer);
Alec Mourie8489fd2021-04-29 16:08:56 -07001147
1148 invokeDraw(settings, layers);
1149
1150 // Give a generous tolerance - the blur rectangle is very small and this test is
1151 // mainly concerned with ensuring that there's no device failure.
1152 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), 255, 0, 0, 255,
1153 40 /* tolerance */);
1154}
1155
1156template <typename SourceVariant>
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001157void RenderEngineTest::overlayCorners() {
1158 renderengine::DisplaySettings settings;
1159 settings.physicalDisplay = fullscreenRect();
1160 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001161 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001162
Sally Qi59a9f502021-10-12 18:53:23 +00001163 std::vector<renderengine::LayerSettings> layersFirst;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001164
1165 renderengine::LayerSettings layerOne;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001166 layerOne.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001167 layerOne.geometry.boundaries =
1168 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0);
1169 SourceVariant::fillColor(layerOne, 1.0f, 0.0f, 0.0f, this);
1170 layerOne.alpha = 0.2;
1171
Sally Qi59a9f502021-10-12 18:53:23 +00001172 layersFirst.push_back(layerOne);
Alec Mouric0aae732021-01-12 13:32:18 -08001173 invokeDraw(settings, layersFirst);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001174 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 51, 0, 0, 51);
1175 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1176 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1177 0, 0, 0, 0);
1178
Sally Qi59a9f502021-10-12 18:53:23 +00001179 std::vector<renderengine::LayerSettings> layersSecond;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001180 renderengine::LayerSettings layerTwo;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001181 layerTwo.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001182 layerTwo.geometry.boundaries =
1183 FloatRect(DEFAULT_DISPLAY_WIDTH / 3.0, DEFAULT_DISPLAY_HEIGHT / 3.0,
1184 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
1185 SourceVariant::fillColor(layerTwo, 0.0f, 1.0f, 0.0f, this);
1186 layerTwo.alpha = 1.0f;
1187
Sally Qi59a9f502021-10-12 18:53:23 +00001188 layersSecond.push_back(layerTwo);
Alec Mouric0aae732021-01-12 13:32:18 -08001189 invokeDraw(settings, layersSecond);
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001190
1191 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3), 0, 0, 0, 0);
1192 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 3 + 1, DEFAULT_DISPLAY_HEIGHT / 3 + 1,
1193 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
1194 0, 255, 0, 255);
1195}
1196
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001197void RenderEngineTest::fillRedBufferTextureTransform() {
1198 renderengine::DisplaySettings settings;
1199 settings.physicalDisplay = fullscreenRect();
1200 settings.clip = Rect(1, 1);
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001201 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001202
Sally Qi59a9f502021-10-12 18:53:23 +00001203 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001204
1205 renderengine::LayerSettings layer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001206 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001207 // Here will allocate a checker board texture, but transform texture
1208 // coordinates so that only the upper left is applied.
Alec Mouria90a5702021-04-16 16:36:21 +00001209 const auto buf = allocateSourceBuffer(2, 2);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001210 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001211 RenderEngineTest::mRE->genTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001212 this->mTexNames.push_back(texName);
1213
1214 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001215 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1216 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001217 // Red top left, Green top right, Blue bottom left, Black bottom right
1218 pixels[0] = 255;
1219 pixels[1] = 0;
1220 pixels[2] = 0;
1221 pixels[3] = 255;
1222 pixels[4] = 0;
1223 pixels[5] = 255;
1224 pixels[6] = 0;
1225 pixels[7] = 255;
1226 pixels[8] = 0;
1227 pixels[9] = 0;
1228 pixels[10] = 255;
1229 pixels[11] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001230 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001231
1232 layer.source.buffer.buffer = buf;
1233 layer.source.buffer.textureName = texName;
1234 // Transform coordinates to only be inside the red quadrant.
Alec Mouri4049b532021-10-15 20:59:33 -07001235 layer.source.buffer.textureTransform = mat4::scale(vec4(0.2f, 0.2f, 1.f, 1.f));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001236 layer.alpha = 1.0f;
1237 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1238
Sally Qi59a9f502021-10-12 18:53:23 +00001239 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001240
Alec Mouric0aae732021-01-12 13:32:18 -08001241 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001242}
1243
1244void RenderEngineTest::fillBufferTextureTransform() {
1245 fillRedBufferTextureTransform();
1246 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1247}
1248
1249void RenderEngineTest::fillRedBufferWithPremultiplyAlpha() {
1250 renderengine::DisplaySettings settings;
1251 settings.physicalDisplay = fullscreenRect();
1252 // Here logical space is 1x1
1253 settings.clip = Rect(1, 1);
1254
Sally Qi59a9f502021-10-12 18:53:23 +00001255 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001256
1257 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001258 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001259 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001260 RenderEngineTest::mRE->genTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001261 this->mTexNames.push_back(texName);
1262
1263 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001264 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1265 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001266 pixels[0] = 255;
1267 pixels[1] = 0;
1268 pixels[2] = 0;
1269 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001270 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001271
1272 layer.source.buffer.buffer = buf;
1273 layer.source.buffer.textureName = texName;
1274 layer.source.buffer.usePremultipliedAlpha = true;
1275 layer.alpha = 0.5f;
1276 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1277
Sally Qi59a9f502021-10-12 18:53:23 +00001278 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001279
Alec Mouric0aae732021-01-12 13:32:18 -08001280 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001281}
1282
1283void RenderEngineTest::fillBufferWithPremultiplyAlpha() {
1284 fillRedBufferWithPremultiplyAlpha();
1285 expectBufferColor(fullscreenRect(), 128, 0, 0, 128);
1286}
1287
1288void RenderEngineTest::fillRedBufferWithoutPremultiplyAlpha() {
1289 renderengine::DisplaySettings settings;
1290 settings.physicalDisplay = fullscreenRect();
1291 // Here logical space is 1x1
1292 settings.clip = Rect(1, 1);
1293
Sally Qi59a9f502021-10-12 18:53:23 +00001294 std::vector<renderengine::LayerSettings> layers;
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001295
1296 renderengine::LayerSettings layer;
Alec Mouria90a5702021-04-16 16:36:21 +00001297 const auto buf = allocateSourceBuffer(1, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001298 uint32_t texName;
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001299 RenderEngineTest::mRE->genTextures(1, &texName);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001300 this->mTexNames.push_back(texName);
1301
1302 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00001303 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1304 reinterpret_cast<void**>(&pixels));
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001305 pixels[0] = 255;
1306 pixels[1] = 0;
1307 pixels[2] = 0;
1308 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00001309 buf->getBuffer()->unlock();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001310
1311 layer.source.buffer.buffer = buf;
1312 layer.source.buffer.textureName = texName;
1313 layer.source.buffer.usePremultipliedAlpha = false;
1314 layer.alpha = 0.5f;
1315 layer.geometry.boundaries = Rect(1, 1).toFloatRect();
1316
Sally Qi59a9f502021-10-12 18:53:23 +00001317 layers.push_back(layer);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001318
Alec Mouric0aae732021-01-12 13:32:18 -08001319 invokeDraw(settings, layers);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001320}
1321
1322void RenderEngineTest::fillBufferWithoutPremultiplyAlpha() {
1323 fillRedBufferWithoutPremultiplyAlpha();
wukui16f3c0bb2020-08-05 20:35:29 +08001324 expectBufferColor(fullscreenRect(), 128, 0, 0, 128, 1);
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001325}
1326
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001327template <typename SourceVariant>
1328void RenderEngineTest::drawShadow(const renderengine::LayerSettings& castingLayer,
1329 const renderengine::ShadowSettings& shadow,
1330 const ubyte4& casterColor, const ubyte4& backgroundColor) {
1331 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001332 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001333 settings.physicalDisplay = fullscreenRect();
1334 settings.clip = fullscreenRect();
1335
Sally Qi59a9f502021-10-12 18:53:23 +00001336 std::vector<renderengine::LayerSettings> layers;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001337
1338 // add background layer
1339 renderengine::LayerSettings bgLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001340 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001341 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1342 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1343 backgroundColor.b / 255.0f, this);
1344 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001345 layers.push_back(bgLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001346
1347 // add shadow layer
1348 renderengine::LayerSettings shadowLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001349 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001350 shadowLayer.geometry.boundaries = castingLayer.geometry.boundaries;
1351 shadowLayer.alpha = castingLayer.alpha;
1352 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001353 layers.push_back(shadowLayer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001354
1355 // add layer casting the shadow
1356 renderengine::LayerSettings layer = castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001357 layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001358 SourceVariant::fillColor(layer, casterColor.r / 255.0f, casterColor.g / 255.0f,
1359 casterColor.b / 255.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001360 layers.push_back(layer);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001361
Alec Mouric0aae732021-01-12 13:32:18 -08001362 invokeDraw(settings, layers);
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001363}
1364
Alec Mouribd17b3b2020-12-17 11:08:30 -08001365void RenderEngineTest::drawShadowWithoutCaster(const FloatRect& castingBounds,
1366 const renderengine::ShadowSettings& shadow,
1367 const ubyte4& backgroundColor) {
1368 renderengine::DisplaySettings settings;
1369 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1370 settings.physicalDisplay = fullscreenRect();
1371 settings.clip = fullscreenRect();
1372
Sally Qi59a9f502021-10-12 18:53:23 +00001373 std::vector<renderengine::LayerSettings> layers;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001374
1375 // add background layer
1376 renderengine::LayerSettings bgLayer;
1377 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1378 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1379 ColorSourceVariant::fillColor(bgLayer, backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1380 backgroundColor.b / 255.0f, this);
1381 bgLayer.alpha = backgroundColor.a / 255.0f;
Sally Qi59a9f502021-10-12 18:53:23 +00001382 layers.push_back(bgLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001383
1384 // add shadow layer
1385 renderengine::LayerSettings shadowLayer;
1386 shadowLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1387 shadowLayer.geometry.boundaries = castingBounds;
Derek Sollenbergerc31985e2021-05-18 16:38:17 -04001388 shadowLayer.skipContentDraw = true;
Alec Mouribd17b3b2020-12-17 11:08:30 -08001389 shadowLayer.alpha = 1.0f;
1390 ColorSourceVariant::fillColor(shadowLayer, 0, 0, 0, this);
1391 shadowLayer.shadow = shadow;
Sally Qi59a9f502021-10-12 18:53:23 +00001392 layers.push_back(shadowLayer);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001393
Alec Mouric0aae732021-01-12 13:32:18 -08001394 invokeDraw(settings, layers);
Alec Mouribd17b3b2020-12-17 11:08:30 -08001395}
1396
Alec Mouri5a493722022-01-26 16:43:02 -08001397void RenderEngineTest::tonemap(ui::Dataspace sourceDataspace, std::function<vec3(vec3)> eotf,
1398 std::function<vec3(vec3, float)> scaleOotf) {
1399 constexpr int32_t kGreyLevels = 256;
1400
1401 const auto rect = Rect(0, 0, kGreyLevels, 1);
1402
1403 constexpr float kMaxLuminance = 750.f;
1404 constexpr float kCurrentLuminanceNits = 500.f;
1405 const renderengine::DisplaySettings display{
1406 .physicalDisplay = rect,
1407 .clip = rect,
1408 .maxLuminance = kMaxLuminance,
1409 .currentLuminanceNits = kCurrentLuminanceNits,
1410 .outputDataspace = ui::Dataspace::DISPLAY_P3,
1411 };
1412
1413 auto buf = std::make_shared<
1414 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001415 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1416 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1417 GRALLOC_USAGE_SW_READ_OFTEN |
1418 GRALLOC_USAGE_SW_WRITE_OFTEN |
1419 GRALLOC_USAGE_HW_RENDER |
1420 GRALLOC_USAGE_HW_TEXTURE,
1421 "input"),
Alec Mouri5a493722022-01-26 16:43:02 -08001422 *mRE,
1423 renderengine::impl::ExternalTexture::Usage::READABLE |
1424 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1425 ASSERT_EQ(0, buf->getBuffer()->initCheck());
1426 {
1427 uint8_t* pixels;
1428 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
1429 reinterpret_cast<void**>(&pixels));
1430
1431 uint8_t color = 0;
1432 for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) {
1433 uint8_t* dest = pixels + (buf->getBuffer()->getStride() * j * 4);
1434 for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) {
1435 dest[0] = color;
1436 dest[1] = color;
1437 dest[2] = color;
1438 dest[3] = 255;
1439 color++;
1440 dest += 4;
1441 }
1442 }
1443 buf->getBuffer()->unlock();
1444 }
1445
1446 mBuffer = std::make_shared<
1447 renderengine::impl::
Ady Abrahamd11bade2022-08-01 16:18:03 -07001448 ExternalTexture>(sp<GraphicBuffer>::make(kGreyLevels, 1,
1449 HAL_PIXEL_FORMAT_RGBA_8888, 1,
1450 GRALLOC_USAGE_SW_READ_OFTEN |
1451 GRALLOC_USAGE_SW_WRITE_OFTEN |
1452 GRALLOC_USAGE_HW_RENDER |
1453 GRALLOC_USAGE_HW_TEXTURE,
1454 "output"),
Alec Mouri5a493722022-01-26 16:43:02 -08001455 *mRE,
1456 renderengine::impl::ExternalTexture::Usage::READABLE |
1457 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
1458 ASSERT_EQ(0, mBuffer->getBuffer()->initCheck());
1459
1460 const renderengine::LayerSettings layer{.geometry.boundaries = rect.toFloatRect(),
1461 .source =
1462 renderengine::PixelSource{
1463 .buffer =
1464 renderengine::Buffer{
1465 .buffer =
1466 std::move(buf),
1467 .usePremultipliedAlpha =
1468 true,
1469 },
1470 },
1471 .alpha = 1.0f,
1472 .sourceDataspace = sourceDataspace};
1473
1474 std::vector<renderengine::LayerSettings> layers{layer};
1475 invokeDraw(display, layers);
1476
1477 ColorSpace displayP3 = ColorSpace::DisplayP3();
1478 ColorSpace bt2020 = ColorSpace::BT2020();
1479
1480 tonemap::Metadata metadata{.displayMaxLuminance = 750.0f};
1481
1482 auto generator = [=](Point location) {
1483 const double normColor = static_cast<double>(location.x) / (kGreyLevels - 1);
1484 const vec3 rgb = vec3(normColor, normColor, normColor);
1485
1486 const vec3 linearRGB = eotf(rgb);
1487
1488 const vec3 xyz = bt2020.getRGBtoXYZ() * linearRGB;
1489
1490 const vec3 scaledXYZ = scaleOotf(xyz, kCurrentLuminanceNits);
Alec Mouri196b0f22022-03-04 22:13:48 +00001491 const auto gains =
Alec Mouri5a493722022-01-26 16:43:02 -08001492 tonemap::getToneMapper()
1493 ->lookupTonemapGain(static_cast<aidl::android::hardware::graphics::common::
1494 Dataspace>(sourceDataspace),
1495 static_cast<aidl::android::hardware::graphics::common::
1496 Dataspace>(
1497 ui::Dataspace::DISPLAY_P3),
Alec Mouri196b0f22022-03-04 22:13:48 +00001498 {tonemap::
1499 Color{.linearRGB =
1500 scaleOotf(linearRGB,
1501 kCurrentLuminanceNits),
1502 .xyz = scaledXYZ}},
Alec Mouri5a493722022-01-26 16:43:02 -08001503 metadata);
Alec Mouri196b0f22022-03-04 22:13:48 +00001504 EXPECT_EQ(1, gains.size());
1505 const double gain = gains.front();
Alec Mouri5a493722022-01-26 16:43:02 -08001506 const vec3 normalizedXYZ = scaledXYZ * gain / metadata.displayMaxLuminance;
1507
1508 const vec3 targetRGB = OETF_sRGB(displayP3.getXYZtoRGB() * normalizedXYZ) * 255;
1509 return ubyte4(static_cast<uint8_t>(targetRGB.r), static_cast<uint8_t>(targetRGB.g),
1510 static_cast<uint8_t>(targetRGB.b), 255);
1511 };
1512
1513 expectBufferColor(Rect(kGreyLevels, 1), generator, 2);
1514}
1515
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001516INSTANTIATE_TEST_SUITE_P(PerRenderEngineType, RenderEngineTest,
Alec Mouric16974e2022-09-13 17:35:48 +00001517 testing::Values(std::make_shared<SkiaGLESRenderEngineFactory>(),
Alec Mouri0eab3e82020-12-08 18:10:27 -08001518 std::make_shared<SkiaGLESCMRenderEngineFactory>()));
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001519
1520TEST_P(RenderEngineTest, drawLayers_noLayersToDraw) {
Alec Mouric0aae732021-01-12 13:32:18 -08001521 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001522 drawEmptyLayers();
1523}
1524
Sally Qi1fed86e2022-06-23 15:33:52 -07001525TEST_P(RenderEngineTest, drawLayers_fillRedBufferAndEmptyBuffer) {
Sally Qi1fed86e2022-06-23 15:33:52 -07001526 initializeRenderEngine();
1527 renderengine::DisplaySettings settings;
1528 settings.physicalDisplay = fullscreenRect();
1529 settings.clip = fullscreenRect();
1530 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1531
1532 // add a red layer
1533 renderengine::LayerSettings layerOne{
1534 .geometry.boundaries = fullscreenRect().toFloatRect(),
1535 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
1536 .alpha = 1.f,
1537 };
1538
1539 std::vector<renderengine::LayerSettings> layersFirst{layerOne};
1540 invokeDraw(settings, layersFirst);
1541 expectBufferColor(fullscreenRect(), 255, 0, 0, 255);
1542
1543 // re-draw with an empty layer above it, and we get a transparent black one
1544 std::vector<renderengine::LayerSettings> layersSecond;
1545 invokeDraw(settings, layersSecond);
1546 expectBufferColor(fullscreenRect(), 0, 0, 0, 0);
1547}
1548
Ana Krulec07b98df2021-01-07 14:38:40 -08001549TEST_P(RenderEngineTest, drawLayers_withoutBuffers_withColorTransform) {
Alec Mouria90a5702021-04-16 16:36:21 +00001550 initializeRenderEngine();
Ana Krulec07b98df2021-01-07 14:38:40 -08001551
1552 renderengine::DisplaySettings settings;
1553 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1554 settings.physicalDisplay = fullscreenRect();
1555 settings.clip = fullscreenRect();
1556
1557 // 255, 255, 255, 255 is full opaque white.
Alec Mouri4049b532021-10-15 20:59:33 -07001558 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
1559 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Ana Krulec07b98df2021-01-07 14:38:40 -08001560 // Create layer with given color.
1561 renderengine::LayerSettings bgLayer;
1562 bgLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
1563 bgLayer.geometry.boundaries = fullscreenRect().toFloatRect();
1564 bgLayer.source.solidColor = half3(backgroundColor.r / 255.0f, backgroundColor.g / 255.0f,
1565 backgroundColor.b / 255.0f);
1566 bgLayer.alpha = backgroundColor.a / 255.0f;
1567 // Transform the red color.
1568 bgLayer.colorTransform = mat4(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
1569
Sally Qi59a9f502021-10-12 18:53:23 +00001570 std::vector<renderengine::LayerSettings> layers;
1571 layers.push_back(bgLayer);
Ana Krulec07b98df2021-01-07 14:38:40 -08001572
Alec Mouric0aae732021-01-12 13:32:18 -08001573 invokeDraw(settings, layers);
Ana Krulec07b98df2021-01-07 14:38:40 -08001574
1575 // Expect to see full opaque pixel (with inverted red from the transform).
Alec Mouric0aae732021-01-12 13:32:18 -08001576 expectBufferColor(Rect(0, 0, 10, 10), 0.f, backgroundColor.g, backgroundColor.b,
Ana Krulec07b98df2021-01-07 14:38:40 -08001577 backgroundColor.a);
1578}
1579
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001580TEST_P(RenderEngineTest, drawLayers_nullOutputBuffer) {
Alec Mouric0aae732021-01-12 13:32:18 -08001581 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001582
Alec Mourid43ccab2019-03-13 12:23:45 -07001583 renderengine::DisplaySettings settings;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001584 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Sally Qi59a9f502021-10-12 18:53:23 +00001585 std::vector<renderengine::LayerSettings> layers;
Alec Mourid43ccab2019-03-13 12:23:45 -07001586 renderengine::LayerSettings layer;
1587 layer.geometry.boundaries = fullscreenRect().toFloatRect();
1588 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
Sally Qi59a9f502021-10-12 18:53:23 +00001589 layers.push_back(layer);
Patrick Williams2e9748f2022-08-09 22:48:18 +00001590 ftl::Future<FenceResult> future =
Sally Qi4cabdd02021-08-05 16:45:57 -07001591 mRE->drawLayers(settings, layers, nullptr, true, base::unique_fd());
Alec Mourid43ccab2019-03-13 12:23:45 -07001592
Patrick Williams2e9748f2022-08-09 22:48:18 +00001593 ASSERT_TRUE(future.valid());
1594 auto result = future.get();
1595 ASSERT_FALSE(result.ok());
1596 ASSERT_EQ(BAD_VALUE, result.error());
Alec Mourid43ccab2019-03-13 12:23:45 -07001597}
1598
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001599TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001600 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001601 fillRedBuffer<ColorSourceVariant>();
1602}
1603
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001604TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001605 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001606 fillGreenBuffer<ColorSourceVariant>();
1607}
1608
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001609TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001610 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001611 fillBlueBuffer<ColorSourceVariant>();
1612}
1613
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001614TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001615 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001616 fillRedTransparentBuffer<ColorSourceVariant>();
1617}
1618
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001619TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001620 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001621 fillBufferPhysicalOffset<ColorSourceVariant>();
1622}
1623
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001624TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001625 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001626 fillBufferCheckersRotate0<ColorSourceVariant>();
1627}
1628
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001629TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001630 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001631 fillBufferCheckersRotate90<ColorSourceVariant>();
1632}
1633
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001634TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001635 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001636 fillBufferCheckersRotate180<ColorSourceVariant>();
1637}
1638
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001639TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001640 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001641 fillBufferCheckersRotate270<ColorSourceVariant>();
1642}
1643
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001644TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001645 initializeRenderEngine();
Alec Mouri1089aed2018-10-25 21:33:57 -07001646 fillBufferLayerTransform<ColorSourceVariant>();
1647}
1648
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001649TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001650 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001651 fillBufferColorTransform<ColorSourceVariant>();
1652}
1653
Sally Qi2019fd22021-11-22 10:19:04 -08001654TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_sourceDataspace) {
1655 const auto& renderEngineFactory = GetParam();
1656 // skip for non color management
1657 if (!renderEngineFactory->useColorManagement()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001658 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001659 }
1660
1661 initializeRenderEngine();
1662 fillBufferColorTransformAndSourceDataspace<ColorSourceVariant>();
1663}
1664
1665TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_outputDataspace) {
1666 const auto& renderEngineFactory = GetParam();
1667 // skip for non color management
1668 if (!renderEngineFactory->useColorManagement()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001669 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001670 }
1671
1672 initializeRenderEngine();
1673 fillBufferColorTransformAndOutputDataspace<ColorSourceVariant>();
1674}
1675
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001676TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001677 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001678 fillBufferWithRoundedCorners<ColorSourceVariant>();
1679}
1680
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001681TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001682 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001683 fillBufferColorTransformZeroLayerAlpha<ColorSourceVariant>();
1684}
1685
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001686TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001687 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001688 fillBufferAndBlurBackground<ColorSourceVariant>();
1689}
1690
Alec Mourie8489fd2021-04-29 16:08:56 -07001691TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_colorSource) {
1692 initializeRenderEngine();
1693 fillSmallLayerAndBlurBackground<ColorSourceVariant>();
1694}
1695
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001696TEST_P(RenderEngineTest, drawLayers_overlayCorners_colorSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001697 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001698 overlayCorners<ColorSourceVariant>();
1699}
1700
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001701TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001702 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001703 fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1704}
1705
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001706TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001707 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001708 fillGreenBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1709}
1710
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001711TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001712 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001713 fillBlueBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1714}
1715
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001716TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001717 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001718 fillRedTransparentBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1719}
1720
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001721TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001722 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001723 fillBufferPhysicalOffset<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1724}
1725
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001726TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001727 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001728 fillBufferCheckersRotate0<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1729}
1730
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001731TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001732 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001733 fillBufferCheckersRotate90<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1734}
1735
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001736TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001737 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001738 fillBufferCheckersRotate180<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1739}
1740
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001741TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001742 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001743 fillBufferCheckersRotate270<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1744}
1745
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001746TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001747 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001748 fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1749}
1750
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001751TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001752 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001753 fillBufferColorTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1754}
1755
Sally Qi2019fd22021-11-22 10:19:04 -08001756TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_opaqueBufferSource) {
1757 const auto& renderEngineFactory = GetParam();
1758 // skip for non color management
1759 if (!renderEngineFactory->useColorManagement()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001760 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001761 }
1762
1763 initializeRenderEngine();
1764 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1765}
1766
1767TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_opaqueBufferSource) {
1768 const auto& renderEngineFactory = GetParam();
1769 // skip for non color management
1770 if (!renderEngineFactory->useColorManagement()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001771 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001772 }
1773
1774 initializeRenderEngine();
1775 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1776}
1777
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001778TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001779 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001780 fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1781}
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001782
Alec Mouric0aae732021-01-12 13:32:18 -08001783TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_opaqueBufferSource) {
1784 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001785 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1786}
Alec Mouri7c94edb2018-12-03 21:23:26 -08001787
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001788TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001789 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001790 fillBufferAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1791}
1792
Alec Mourie8489fd2021-04-29 16:08:56 -07001793TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_opaqueBufferSource) {
1794 initializeRenderEngine();
1795 fillSmallLayerAndBlurBackground<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1796}
1797
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001798TEST_P(RenderEngineTest, drawLayers_overlayCorners_opaqueBufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001799 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001800 overlayCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
1801}
1802
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001803TEST_P(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001804 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001805 fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1806}
1807
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001808TEST_P(RenderEngineTest, drawLayers_fillGreenBuffer_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001809 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001810 fillGreenBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1811}
1812
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001813TEST_P(RenderEngineTest, drawLayers_fillBlueBuffer_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001814 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001815 fillBlueBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1816}
1817
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001818TEST_P(RenderEngineTest, drawLayers_fillRedTransparentBuffer_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001819 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001820 fillRedTransparentBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1821}
1822
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001823TEST_P(RenderEngineTest, drawLayers_fillBufferPhysicalOffset_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001824 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001825 fillBufferPhysicalOffset<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1826}
1827
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001828TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate0_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001829 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001830 fillBufferCheckersRotate0<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1831}
1832
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001833TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate90_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001834 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001835 fillBufferCheckersRotate90<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1836}
1837
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001838TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate180_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001839 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001840 fillBufferCheckersRotate180<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1841}
1842
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001843TEST_P(RenderEngineTest, drawLayers_fillBufferCheckersRotate270_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001844 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001845 fillBufferCheckersRotate270<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1846}
1847
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001848TEST_P(RenderEngineTest, drawLayers_fillBufferLayerTransform_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001849 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001850 fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1851}
1852
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001853TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransform_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001854 initializeRenderEngine();
KaiChieh Chuang436fc192020-09-07 13:48:42 +08001855 fillBufferColorTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1856}
1857
Sally Qi2019fd22021-11-22 10:19:04 -08001858TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndSourceDataspace_bufferSource) {
1859 const auto& renderEngineFactory = GetParam();
1860 // skip for non color management
1861 if (!renderEngineFactory->useColorManagement()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001862 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001863 }
1864
1865 initializeRenderEngine();
1866 fillBufferColorTransformAndSourceDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1867}
1868
1869TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformAndOutputDataspace_bufferSource) {
1870 const auto& renderEngineFactory = GetParam();
1871 // skip for non color management
1872 if (!renderEngineFactory->useColorManagement()) {
Alec Mouric16974e2022-09-13 17:35:48 +00001873 GTEST_SKIP();
Sally Qi2019fd22021-11-22 10:19:04 -08001874 }
1875
1876 initializeRenderEngine();
1877 fillBufferColorTransformAndOutputDataspace<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1878}
1879
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001880TEST_P(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001881 initializeRenderEngine();
Alec Mouri7c94edb2018-12-03 21:23:26 -08001882 fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1883}
1884
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001885TEST_P(RenderEngineTest, drawLayers_fillBufferColorTransformZeroLayerAlpha_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001886 initializeRenderEngine();
KaiChieh Chuangda2845c2020-12-14 16:49:38 +08001887 fillBufferColorTransformZeroLayerAlpha<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1888}
1889
Nathaniel Nifong53494f32021-04-30 14:05:39 -04001890TEST_P(RenderEngineTest, drawLayers_fillBufferAndBlurBackground_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001891 initializeRenderEngine();
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08001892 fillBufferAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1893}
1894
Alec Mourie8489fd2021-04-29 16:08:56 -07001895TEST_P(RenderEngineTest, drawLayers_fillSmallLayerAndBlurBackground_bufferSource) {
1896 initializeRenderEngine();
1897 fillSmallLayerAndBlurBackground<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1898}
1899
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001900TEST_P(RenderEngineTest, drawLayers_overlayCorners_bufferSource) {
Alec Mouric0aae732021-01-12 13:32:18 -08001901 initializeRenderEngine();
Alec Mourie7d1d4a2019-02-05 01:13:46 +00001902 overlayCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
1903}
1904
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001905TEST_P(RenderEngineTest, drawLayers_fillBufferTextureTransform) {
Alec Mouric0aae732021-01-12 13:32:18 -08001906 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001907 fillBufferTextureTransform();
1908}
1909
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001910TEST_P(RenderEngineTest, drawLayers_fillBuffer_premultipliesAlpha) {
Alec Mouric0aae732021-01-12 13:32:18 -08001911 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001912 fillBufferWithPremultiplyAlpha();
1913}
1914
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001915TEST_P(RenderEngineTest, drawLayers_fillBuffer_withoutPremultiplyingAlpha) {
Alec Mouric0aae732021-01-12 13:32:18 -08001916 initializeRenderEngine();
Alec Mouri0d5e1eb2018-11-10 20:40:12 -08001917 fillBufferWithoutPremultiplyAlpha();
1918}
1919
Alec Mouribd17b3b2020-12-17 11:08:30 -08001920TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) {
Alec Mouric0aae732021-01-12 13:32:18 -08001921 initializeRenderEngine();
Alec Mouribd17b3b2020-12-17 11:08:30 -08001922
Alec Mouri4049b532021-10-15 20:59:33 -07001923 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
1924 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Alec Mouribd17b3b2020-12-17 11:08:30 -08001925 const float shadowLength = 5.0f;
1926 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
1927 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
1928 renderengine::ShadowSettings settings =
1929 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
1930 false /* casterIsTranslucent */);
1931
1932 drawShadowWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
1933 expectShadowColorWithoutCaster(casterBounds.toFloatRect(), settings, backgroundColor);
1934}
1935
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001936TEST_P(RenderEngineTest, drawLayers_fillShadow_casterLayerMinSize) {
Alec Mouric0aae732021-01-12 13:32:18 -08001937 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001938
Alec Mouri4049b532021-10-15 20:59:33 -07001939 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
1940 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
1941 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
1942 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001943 const float shadowLength = 5.0f;
1944 Rect casterBounds(1, 1);
1945 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
1946 renderengine::LayerSettings castingLayer;
1947 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
1948 castingLayer.alpha = 1.0f;
1949 renderengine::ShadowSettings settings =
1950 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
1951 false /* casterIsTranslucent */);
1952
1953 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
1954 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
1955}
1956
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001957TEST_P(RenderEngineTest, drawLayers_fillShadow_casterColorLayer) {
Alec Mouric0aae732021-01-12 13:32:18 -08001958 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001959
Alec Mouri4049b532021-10-15 20:59:33 -07001960 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
1961 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
1962 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
1963 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001964 const float shadowLength = 5.0f;
1965 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
1966 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
1967 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001968 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001969 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
1970 castingLayer.alpha = 1.0f;
1971 renderengine::ShadowSettings settings =
1972 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
1973 false /* casterIsTranslucent */);
1974
1975 drawShadow<ColorSourceVariant>(castingLayer, settings, casterColor, backgroundColor);
1976 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
1977}
1978
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001979TEST_P(RenderEngineTest, drawLayers_fillShadow_casterOpaqueBufferLayer) {
Alec Mouric0aae732021-01-12 13:32:18 -08001980 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08001981
Alec Mouri4049b532021-10-15 20:59:33 -07001982 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
1983 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
1984 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
1985 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001986 const float shadowLength = 5.0f;
1987 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
1988 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
1989 renderengine::LayerSettings castingLayer;
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08001990 castingLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Vishnu Nair16efdbf2019-12-10 11:55:42 -08001991 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
1992 castingLayer.alpha = 1.0f;
1993 renderengine::ShadowSettings settings =
1994 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
1995 false /* casterIsTranslucent */);
1996
1997 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
1998 backgroundColor);
1999 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2000}
2001
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002002TEST_P(RenderEngineTest, drawLayers_fillShadow_casterWithRoundedCorner) {
Alec Mouric0aae732021-01-12 13:32:18 -08002003 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002004
Alec Mouri4049b532021-10-15 20:59:33 -07002005 const ubyte4 casterColor(static_cast<uint8_t>(255), static_cast<uint8_t>(0),
2006 static_cast<uint8_t>(0), static_cast<uint8_t>(255));
2007 const ubyte4 backgroundColor(static_cast<uint8_t>(255), static_cast<uint8_t>(255),
2008 static_cast<uint8_t>(255), static_cast<uint8_t>(255));
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002009 const float shadowLength = 5.0f;
2010 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2011 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2012 renderengine::LayerSettings castingLayer;
2013 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002014 castingLayer.geometry.roundedCornersRadius = {3.0f, 3.0f};
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002015 castingLayer.geometry.roundedCornersCrop = casterBounds.toFloatRect();
2016 castingLayer.alpha = 1.0f;
2017 renderengine::ShadowSettings settings =
2018 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2019 false /* casterIsTranslucent */);
2020
2021 drawShadow<BufferSourceVariant<ForceOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2022 backgroundColor);
2023 expectShadowColor(castingLayer, settings, casterColor, backgroundColor);
2024}
2025
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002026TEST_P(RenderEngineTest, drawLayers_fillShadow_translucentCasterWithAlpha) {
Alec Mouric0aae732021-01-12 13:32:18 -08002027 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002028
Vishnu Nair16efdbf2019-12-10 11:55:42 -08002029 const ubyte4 casterColor(255, 0, 0, 255);
2030 const ubyte4 backgroundColor(255, 255, 255, 255);
2031 const float shadowLength = 5.0f;
2032 Rect casterBounds(DEFAULT_DISPLAY_WIDTH / 3.0f, DEFAULT_DISPLAY_HEIGHT / 3.0f);
2033 casterBounds.offsetBy(shadowLength + 1, shadowLength + 1);
2034 renderengine::LayerSettings castingLayer;
2035 castingLayer.geometry.boundaries = casterBounds.toFloatRect();
2036 castingLayer.alpha = 0.5f;
2037 renderengine::ShadowSettings settings =
2038 getShadowSettings(vec2(casterBounds.left, casterBounds.top), shadowLength,
2039 true /* casterIsTranslucent */);
2040
2041 drawShadow<BufferSourceVariant<RelaxOpaqueBufferVariant>>(castingLayer, settings, casterColor,
2042 backgroundColor);
2043
2044 // verify only the background since the shadow will draw behind the caster
2045 const float shadowInset = settings.length * -1.0f;
2046 const Rect casterWithShadow =
2047 Rect(casterBounds).inset(shadowInset, shadowInset, shadowInset, shadowInset);
2048 const Region backgroundRegion = Region(fullscreenRect()).subtractSelf(casterWithShadow);
2049 expectBufferColor(backgroundRegion, backgroundColor.r, backgroundColor.g, backgroundColor.b,
2050 backgroundColor.a);
2051}
2052
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002053TEST_P(RenderEngineTest, cleanupPostRender_cleansUpOnce) {
Alec Mouric0aae732021-01-12 13:32:18 -08002054 initializeRenderEngine();
Ana Krulec82ba2ec2020-11-21 13:33:20 -08002055
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002056 renderengine::DisplaySettings settings;
2057 settings.physicalDisplay = fullscreenRect();
2058 settings.clip = fullscreenRect();
Ana Krulecaa2fe7f2020-11-24 15:06:36 -08002059 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002060
Sally Qi59a9f502021-10-12 18:53:23 +00002061 std::vector<renderengine::LayerSettings> layers;
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002062 renderengine::LayerSettings layer;
2063 layer.geometry.boundaries = fullscreenRect().toFloatRect();
2064 BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
2065 layer.alpha = 1.0;
Sally Qi59a9f502021-10-12 18:53:23 +00002066 layers.push_back(layer);
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002067
Patrick Williams2e9748f2022-08-09 22:48:18 +00002068 ftl::Future<FenceResult> futureOne =
Sally Qi4cabdd02021-08-05 16:45:57 -07002069 mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd());
Patrick Williams2e9748f2022-08-09 22:48:18 +00002070 ASSERT_TRUE(futureOne.valid());
2071 auto resultOne = futureOne.get();
2072 ASSERT_TRUE(resultOne.ok());
2073 auto fenceOne = resultOne.value();
Sally Qi4cabdd02021-08-05 16:45:57 -07002074
Patrick Williams2e9748f2022-08-09 22:48:18 +00002075 ftl::Future<FenceResult> futureTwo =
2076 mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd(fenceOne->dup()));
2077 ASSERT_TRUE(futureTwo.valid());
2078 auto resultTwo = futureTwo.get();
2079 ASSERT_TRUE(resultTwo.ok());
2080 auto fenceTwo = resultTwo.value();
2081 fenceTwo->waitForever(LOG_TAG);
Derek Sollenbergerec411212021-08-25 10:54:47 -04002082
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002083 // Only cleanup the first time.
Derek Sollenbergerd3f60652021-06-11 15:34:36 -04002084 EXPECT_FALSE(mRE->canSkipPostRenderCleanup());
2085 mRE->cleanupPostRender();
2086 EXPECT_TRUE(mRE->canSkipPostRenderCleanup());
Lingfeng Yang2e4fef62020-04-24 14:48:43 +00002087}
2088
Ana Krulecf9a15d92020-12-11 08:35:00 -08002089TEST_P(RenderEngineTest, testRoundedCornersCrop) {
Alec Mouric0aae732021-01-12 13:32:18 -08002090 initializeRenderEngine();
Ana Krulecf9a15d92020-12-11 08:35:00 -08002091
2092 renderengine::DisplaySettings settings;
2093 settings.physicalDisplay = fullscreenRect();
2094 settings.clip = fullscreenRect();
2095 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2096
Sally Qi59a9f502021-10-12 18:53:23 +00002097 std::vector<renderengine::LayerSettings> layers;
Ana Krulecf9a15d92020-12-11 08:35:00 -08002098
2099 renderengine::LayerSettings redLayer;
2100 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2101 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002102 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
2103
Ana Krulecf9a15d92020-12-11 08:35:00 -08002104 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2105 // Red background.
2106 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2107 redLayer.alpha = 1.0f;
2108
Sally Qi59a9f502021-10-12 18:53:23 +00002109 layers.push_back(redLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002110
2111 // Green layer with 1/3 size.
2112 renderengine::LayerSettings greenLayer;
2113 greenLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2114 greenLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002115 greenLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Ana Krulecf9a15d92020-12-11 08:35:00 -08002116 // Bottom right corner is not going to be rounded.
2117 greenLayer.geometry.roundedCornersCrop =
2118 Rect(DEFAULT_DISPLAY_WIDTH / 3, DEFAULT_DISPLAY_HEIGHT / 3, DEFAULT_DISPLAY_HEIGHT,
2119 DEFAULT_DISPLAY_HEIGHT)
2120 .toFloatRect();
2121 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2122 greenLayer.alpha = 1.0f;
2123
Sally Qi59a9f502021-10-12 18:53:23 +00002124 layers.push_back(greenLayer);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002125
Alec Mouric0aae732021-01-12 13:32:18 -08002126 invokeDraw(settings, layers);
Ana Krulecf9a15d92020-12-11 08:35:00 -08002127
2128 // Corners should be ignored...
2129 // Screen size: width is 128, height is 256.
2130 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
2131 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
2132 expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
2133 // Bottom right corner is kept out of the clipping, and it's green.
2134 expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
2135 DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
2136 0, 255, 0, 255);
2137}
2138
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002139TEST_P(RenderEngineTest, testRoundedCornersParentCrop) {
2140 initializeRenderEngine();
2141
2142 renderengine::DisplaySettings settings;
2143 settings.physicalDisplay = fullscreenRect();
2144 settings.clip = fullscreenRect();
2145 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2146
Sally Qi59a9f502021-10-12 18:53:23 +00002147 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002148
2149 renderengine::LayerSettings redLayer;
2150 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2151 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002152 redLayer.geometry.roundedCornersRadius = {5.0f, 5.0f};
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002153 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2154 // Red background.
2155 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2156 redLayer.alpha = 1.0f;
2157
Sally Qi59a9f502021-10-12 18:53:23 +00002158 layers.push_back(redLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002159
2160 // Green layer with 1/2 size with parent crop rect.
2161 renderengine::LayerSettings greenLayer = redLayer;
2162 greenLayer.geometry.boundaries =
2163 FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT / 2);
2164 greenLayer.source.solidColor = half3(0.0f, 1.0f, 0.0f);
2165
Sally Qi59a9f502021-10-12 18:53:23 +00002166 layers.push_back(greenLayer);
Derek Sollenberger8e8b3bf2021-04-29 15:35:28 -04002167
2168 invokeDraw(settings, layers);
2169
2170 // Due to roundedCornersRadius, the corners are untouched.
2171 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2172 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2173 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2174 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2175
2176 // top middle should be green and the bottom middle red
2177 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 0), 0, 255, 0, 255);
2178 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2179
2180 // the bottom edge of the green layer should not be rounded
2181 expectBufferColor(Point(0, (DEFAULT_DISPLAY_HEIGHT / 2) - 1), 0, 255, 0, 255);
2182}
2183
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002184TEST_P(RenderEngineTest, testRoundedCornersParentCropSmallBounds) {
2185 initializeRenderEngine();
2186
2187 renderengine::DisplaySettings settings;
2188 settings.physicalDisplay = fullscreenRect();
2189 settings.clip = fullscreenRect();
2190 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2191
Sally Qi59a9f502021-10-12 18:53:23 +00002192 std::vector<renderengine::LayerSettings> layers;
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002193
2194 renderengine::LayerSettings redLayer;
2195 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2196 redLayer.geometry.boundaries = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 32);
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002197 redLayer.geometry.roundedCornersRadius = {64.0f, 64.0f};
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002198 redLayer.geometry.roundedCornersCrop = FloatRect(0, 0, DEFAULT_DISPLAY_WIDTH, 128);
2199 // Red background.
2200 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2201 redLayer.alpha = 1.0f;
2202
Sally Qi59a9f502021-10-12 18:53:23 +00002203 layers.push_back(redLayer);
Derek Sollenberger547d0a62021-07-27 14:09:17 -04002204 invokeDraw(settings, layers);
2205
2206 // Due to roundedCornersRadius, the top corners are untouched.
2207 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2208 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2209
2210 // ensure that the entire height of the red layer was clipped by the rounded corners crop.
2211 expectBufferColor(Point(0, 31), 0, 0, 0, 0);
2212 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 31), 0, 0, 0, 0);
2213
2214 // the bottom middle should be red
2215 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, 31), 255, 0, 0, 255);
2216}
2217
Vishnu Nair50c0afe2022-07-11 15:04:07 -07002218TEST_P(RenderEngineTest, testRoundedCornersXY) {
2219 if (GetParam()->type() != renderengine::RenderEngine::RenderEngineType::SKIA_GL) {
2220 GTEST_SKIP();
2221 }
2222
2223 initializeRenderEngine();
2224
2225 renderengine::DisplaySettings settings;
2226 settings.physicalDisplay = fullscreenRect();
2227 settings.clip = fullscreenRect();
2228 settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2229
2230 std::vector<renderengine::LayerSettings> layers;
2231
2232 renderengine::LayerSettings redLayer;
2233 redLayer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR;
2234 redLayer.geometry.boundaries = fullscreenRect().toFloatRect();
2235 redLayer.geometry.roundedCornersRadius = {5.0f, 20.0f};
2236 redLayer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
2237 // Red background.
2238 redLayer.source.solidColor = half3(1.0f, 0.0f, 0.0f);
2239 redLayer.alpha = 1.0f;
2240
2241 layers.push_back(redLayer);
2242
2243 invokeDraw(settings, layers);
2244
2245 // Due to roundedCornersRadius, the corners are untouched.
2246 expectBufferColor(Point(0, 0), 0, 0, 0, 0);
2247 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 0), 0, 0, 0, 0);
2248 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2249 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1), 0, 0, 0, 0);
2250
2251 // Y-axis draws a larger radius, check that its untouched as well
2252 expectBufferColor(Point(0, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2253 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 5), 0, 0, 0, 0);
2254 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH - 1, 5), 0, 0, 0, 0);
2255 expectBufferColor(Point(0, 5), 0, 0, 0, 0);
2256
2257 // middle should be red
2258 expectBufferColor(Point(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT / 2), 255, 0, 0, 255);
2259}
2260
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002261TEST_P(RenderEngineTest, testClear) {
2262 initializeRenderEngine();
2263
2264 const auto rect = fullscreenRect();
2265 const renderengine::DisplaySettings display{
2266 .physicalDisplay = rect,
2267 .clip = rect,
2268 };
2269
2270 const renderengine::LayerSettings redLayer{
2271 .geometry.boundaries = rect.toFloatRect(),
2272 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2273 .alpha = 1.0f,
2274 };
2275
2276 // This mimics prepareClearClientComposition. This layer should overwrite
2277 // the redLayer, so that the buffer is transparent, rather than red.
2278 const renderengine::LayerSettings clearLayer{
2279 .geometry.boundaries = rect.toFloatRect(),
2280 .source.solidColor = half3(0.0f, 0.0f, 0.0f),
2281 .alpha = 0.0f,
2282 .disableBlending = true,
2283 };
2284
Sally Qi59a9f502021-10-12 18:53:23 +00002285 std::vector<renderengine::LayerSettings> layers{redLayer, clearLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002286 invokeDraw(display, layers);
2287 expectBufferColor(rect, 0, 0, 0, 0);
2288}
2289
2290TEST_P(RenderEngineTest, testDisableBlendingBuffer) {
2291 initializeRenderEngine();
2292
2293 const auto rect = Rect(0, 0, 1, 1);
2294 const renderengine::DisplaySettings display{
2295 .physicalDisplay = rect,
2296 .clip = rect,
2297 };
2298
2299 const renderengine::LayerSettings redLayer{
2300 .geometry.boundaries = rect.toFloatRect(),
2301 .source.solidColor = half3(1.0f, 0.0f, 0.0f),
2302 .alpha = 1.0f,
2303 };
2304
2305 // The next layer will overwrite redLayer with a GraphicBuffer that is green
2306 // applied with a translucent alpha.
Alec Mouria90a5702021-04-16 16:36:21 +00002307 const auto buf = allocateSourceBuffer(1, 1);
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002308 {
2309 uint8_t* pixels;
Alec Mouria90a5702021-04-16 16:36:21 +00002310 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2311 reinterpret_cast<void**>(&pixels));
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002312 pixels[0] = 0;
2313 pixels[1] = 255;
2314 pixels[2] = 0;
2315 pixels[3] = 255;
Alec Mouria90a5702021-04-16 16:36:21 +00002316 buf->getBuffer()->unlock();
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002317 }
2318
2319 const renderengine::LayerSettings greenLayer{
2320 .geometry.boundaries = rect.toFloatRect(),
2321 .source =
2322 renderengine::PixelSource{
2323 .buffer =
2324 renderengine::Buffer{
2325 .buffer = buf,
2326 .usePremultipliedAlpha = true,
2327 },
2328 },
2329 .alpha = 0.5f,
2330 .disableBlending = true,
2331 };
2332
Sally Qi59a9f502021-10-12 18:53:23 +00002333 std::vector<renderengine::LayerSettings> layers{redLayer, greenLayer};
Leon Scroggins IIIcf3d95c2021-03-19 13:06:32 -04002334 invokeDraw(display, layers);
2335 expectBufferColor(rect, 0, 128, 0, 128);
2336}
2337
Tianhao Yao67dd7122022-02-22 17:48:33 +00002338TEST_P(RenderEngineTest, testBorder) {
2339 if (GetParam()->type() != renderengine::RenderEngine::RenderEngineType::SKIA_GL) {
2340 GTEST_SKIP();
2341 }
2342
2343 if (!GetParam()->useColorManagement()) {
2344 GTEST_SKIP();
2345 }
2346
2347 initializeRenderEngine();
2348
2349 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
2350
2351 const auto displayRect = Rect(1080, 2280);
2352 renderengine::DisplaySettings display{
2353 .physicalDisplay = displayRect,
2354 .clip = displayRect,
2355 .outputDataspace = dataspace,
2356 };
2357 display.borderInfoList.clear();
2358 renderengine::BorderRenderInfo info;
2359 info.combinedRegion = Region(Rect(99, 99, 199, 199));
Tianhao Yao10cea3c2022-03-30 01:37:22 +00002360 info.width = 20.0f;
2361 info.color = half4{1.0f, 128.0f / 255.0f, 0.0f, 1.0f};
Tianhao Yao67dd7122022-02-22 17:48:33 +00002362 display.borderInfoList.emplace_back(info);
2363
2364 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2365 const renderengine::LayerSettings greenLayer{
2366 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2367 .source =
2368 renderengine::PixelSource{
2369 .buffer =
2370 renderengine::Buffer{
2371 .buffer = greenBuffer,
2372 .usePremultipliedAlpha = true,
2373 },
2374 },
2375 .alpha = 1.0f,
2376 .sourceDataspace = dataspace,
2377 .whitePointNits = 200.f,
2378 };
2379
2380 std::vector<renderengine::LayerSettings> layers;
2381 layers.emplace_back(greenLayer);
2382 invokeDraw(display, layers);
2383
2384 expectBufferColor(Rect(99, 99, 101, 101), 255, 128, 0, 255, 1);
2385}
2386
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002387TEST_P(RenderEngineTest, testDimming) {
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002388 initializeRenderEngine();
2389
Alec Mouri85065692022-03-18 00:58:26 +00002390 const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB_LINEAR;
2391
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002392 const auto displayRect = Rect(3, 1);
2393 const renderengine::DisplaySettings display{
2394 .physicalDisplay = displayRect,
2395 .clip = displayRect,
Alec Mouri85065692022-03-18 00:58:26 +00002396 .outputDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002397 .targetLuminanceNits = 1000.f,
2398 };
2399
2400 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2401 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2402 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2403
2404 const renderengine::LayerSettings greenLayer{
2405 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2406 .source =
2407 renderengine::PixelSource{
2408 .buffer =
2409 renderengine::Buffer{
2410 .buffer = greenBuffer,
2411 .usePremultipliedAlpha = true,
2412 },
2413 },
2414 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002415 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002416 .whitePointNits = 200.f,
2417 };
2418
2419 const renderengine::LayerSettings blueLayer{
2420 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2421 .source =
2422 renderengine::PixelSource{
2423 .buffer =
2424 renderengine::Buffer{
2425 .buffer = blueBuffer,
2426 .usePremultipliedAlpha = true,
2427 },
2428 },
2429 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002430 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002431 .whitePointNits = 1000.f / 51.f,
2432 };
2433
2434 const renderengine::LayerSettings redLayer{
2435 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2436 .source =
2437 renderengine::PixelSource{
2438 .buffer =
2439 renderengine::Buffer{
2440 .buffer = redBuffer,
2441 .usePremultipliedAlpha = true,
2442 },
2443 },
2444 .alpha = 1.0f,
Alec Mouri85065692022-03-18 00:58:26 +00002445 .sourceDataspace = dataspace,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002446 // When the white point is not set for a layer, just ignore it and treat it as the same
2447 // as the max layer
2448 .whitePointNits = -1.f,
2449 };
2450
2451 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2452 invokeDraw(display, layers);
2453
2454 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2455 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 5, 255, 1);
2456 expectBufferColor(Rect(2, 0, 3, 1), 51, 0, 0, 255, 1);
2457}
2458
Alec Mouri85065692022-03-18 00:58:26 +00002459TEST_P(RenderEngineTest, testDimming_inGammaSpace) {
Alec Mouri85065692022-03-18 00:58:26 +00002460 initializeRenderEngine();
2461
2462 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2463 ui::Dataspace::TRANSFER_GAMMA2_2 |
2464 ui::Dataspace::RANGE_FULL);
2465
2466 const auto displayRect = Rect(3, 1);
2467 const renderengine::DisplaySettings display{
2468 .physicalDisplay = displayRect,
2469 .clip = displayRect,
2470 .outputDataspace = dataspace,
2471 .targetLuminanceNits = 1000.f,
2472 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2473 };
2474
2475 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2476 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2477 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2478
2479 const renderengine::LayerSettings greenLayer{
2480 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2481 .source =
2482 renderengine::PixelSource{
2483 .buffer =
2484 renderengine::Buffer{
2485 .buffer = greenBuffer,
2486 .usePremultipliedAlpha = true,
2487 },
2488 },
2489 .alpha = 1.0f,
2490 .sourceDataspace = dataspace,
2491 .whitePointNits = 200.f,
2492 };
2493
2494 const renderengine::LayerSettings blueLayer{
2495 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2496 .source =
2497 renderengine::PixelSource{
2498 .buffer =
2499 renderengine::Buffer{
2500 .buffer = blueBuffer,
2501 .usePremultipliedAlpha = true,
2502 },
2503 },
2504 .alpha = 1.0f,
2505 .sourceDataspace = dataspace,
2506 .whitePointNits = 1000.f / 51.f,
2507 };
2508
2509 const renderengine::LayerSettings redLayer{
2510 .geometry.boundaries = FloatRect(2.f, 0.f, 3.f, 1.f),
2511 .source =
2512 renderengine::PixelSource{
2513 .buffer =
2514 renderengine::Buffer{
2515 .buffer = redBuffer,
2516 .usePremultipliedAlpha = true,
2517 },
2518 },
2519 .alpha = 1.0f,
2520 .sourceDataspace = dataspace,
2521 // When the white point is not set for a layer, just ignore it and treat it as the same
2522 // as the max layer
2523 .whitePointNits = -1.f,
2524 };
2525
2526 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer, redLayer};
2527 invokeDraw(display, layers);
2528
2529 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2530 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 42, 255, 1);
2531 expectBufferColor(Rect(2, 0, 3, 1), 122, 0, 0, 255, 1);
2532}
2533
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002534TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform) {
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002535 initializeRenderEngine();
2536
2537 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2538 ui::Dataspace::TRANSFER_GAMMA2_2 |
2539 ui::Dataspace::RANGE_FULL);
2540
2541 const auto displayRect = Rect(3, 1);
2542 const renderengine::DisplaySettings display{
2543 .physicalDisplay = displayRect,
2544 .clip = displayRect,
2545 .outputDataspace = dataspace,
2546 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2547 .targetLuminanceNits = 1000.f,
2548 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2549 };
2550
2551 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2552 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2553 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2554
2555 const renderengine::LayerSettings greenLayer{
2556 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2557 .source =
2558 renderengine::PixelSource{
2559 .buffer =
2560 renderengine::Buffer{
2561 .buffer = greenBuffer,
2562 .usePremultipliedAlpha = true,
2563 },
2564 },
2565 .alpha = 1.0f,
2566 .sourceDataspace = dataspace,
2567 .whitePointNits = 200.f,
2568 };
2569
2570 const renderengine::LayerSettings redLayer{
2571 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2572 .source =
2573 renderengine::PixelSource{
2574 .buffer =
2575 renderengine::Buffer{
2576 .buffer = redBuffer,
2577 .usePremultipliedAlpha = true,
2578 },
2579 },
2580 .alpha = 1.0f,
2581 .sourceDataspace = dataspace,
2582 // When the white point is not set for a layer, just ignore it and treat it as the same
2583 // as the max layer
2584 .whitePointNits = -1.f,
2585 };
2586
2587 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2588 invokeDraw(display, layers);
2589
2590 expectBufferColor(Rect(1, 1), 0, 0, 0, 255, 1);
2591 expectBufferColor(Rect(1, 0, 2, 1), 0, 122, 0, 255, 1);
2592}
2593
2594TEST_P(RenderEngineTest, testDimming_inGammaSpace_withDisplayColorTransform_deviceHandles) {
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002595 initializeRenderEngine();
2596
2597 const ui::Dataspace dataspace = static_cast<ui::Dataspace>(ui::Dataspace::STANDARD_BT709 |
2598 ui::Dataspace::TRANSFER_GAMMA2_2 |
2599 ui::Dataspace::RANGE_FULL);
2600
2601 const auto displayRect = Rect(3, 1);
2602 const renderengine::DisplaySettings display{
2603 .physicalDisplay = displayRect,
2604 .clip = displayRect,
2605 .outputDataspace = dataspace,
2606 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
2607 .deviceHandlesColorTransform = true,
2608 .targetLuminanceNits = 1000.f,
2609 .dimmingStage = aidl::android::hardware::graphics::composer3::DimmingStage::GAMMA_OETF,
2610 };
2611
2612 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2613 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2614 const auto redBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(255, 0, 0, 255));
2615
2616 const renderengine::LayerSettings greenLayer{
2617 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2618 .source =
2619 renderengine::PixelSource{
2620 .buffer =
2621 renderengine::Buffer{
2622 .buffer = greenBuffer,
2623 .usePremultipliedAlpha = true,
2624 },
2625 },
2626 .alpha = 1.0f,
2627 .sourceDataspace = dataspace,
2628 .whitePointNits = 200.f,
2629 };
2630
2631 const renderengine::LayerSettings redLayer{
2632 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2633 .source =
2634 renderengine::PixelSource{
2635 .buffer =
2636 renderengine::Buffer{
2637 .buffer = redBuffer,
2638 .usePremultipliedAlpha = true,
2639 },
2640 },
2641 .alpha = 1.0f,
2642 .sourceDataspace = dataspace,
2643 // When the white point is not set for a layer, just ignore it and treat it as the same
2644 // as the max layer
2645 .whitePointNits = -1.f,
2646 };
2647
2648 std::vector<renderengine::LayerSettings> layers{greenLayer, redLayer};
2649 invokeDraw(display, layers);
2650
2651 expectBufferColor(Rect(1, 1), 0, 122, 0, 255, 1);
2652 expectBufferColor(Rect(1, 0, 2, 1), 122, 0, 0, 255, 1);
2653}
2654
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002655TEST_P(RenderEngineTest, testDimming_withoutTargetLuminance) {
2656 initializeRenderEngine();
Alec Mouricdf6cbc2021-11-01 17:21:15 -07002657
2658 const auto displayRect = Rect(2, 1);
2659 const renderengine::DisplaySettings display{
2660 .physicalDisplay = displayRect,
2661 .clip = displayRect,
2662 .outputDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2663 .targetLuminanceNits = -1.f,
2664 };
2665
2666 const auto greenBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 255, 0, 255));
2667 const auto blueBuffer = allocateAndFillSourceBuffer(1, 1, ubyte4(0, 0, 255, 255));
2668
2669 const renderengine::LayerSettings greenLayer{
2670 .geometry.boundaries = FloatRect(0.f, 0.f, 1.f, 1.f),
2671 .source =
2672 renderengine::PixelSource{
2673 .buffer =
2674 renderengine::Buffer{
2675 .buffer = greenBuffer,
2676 .usePremultipliedAlpha = true,
2677 },
2678 },
2679 .alpha = 1.0f,
2680 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2681 .whitePointNits = 200.f,
2682 };
2683
2684 const renderengine::LayerSettings blueLayer{
2685 .geometry.boundaries = FloatRect(1.f, 0.f, 2.f, 1.f),
2686 .source =
2687 renderengine::PixelSource{
2688 .buffer =
2689 renderengine::Buffer{
2690 .buffer = blueBuffer,
2691 .usePremultipliedAlpha = true,
2692 },
2693 },
2694 .alpha = 1.0f,
2695 .sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR,
2696 .whitePointNits = 1000.f,
2697 };
2698
2699 std::vector<renderengine::LayerSettings> layers{greenLayer, blueLayer};
2700 invokeDraw(display, layers);
2701
2702 expectBufferColor(Rect(1, 1), 0, 51, 0, 255, 1);
2703 expectBufferColor(Rect(1, 0, 2, 1), 0, 0, 255, 255);
2704}
2705
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002706TEST_P(RenderEngineTest, test_isOpaque) {
2707 initializeRenderEngine();
2708
2709 const auto rect = Rect(0, 0, 1, 1);
2710 const renderengine::DisplaySettings display{
2711 .physicalDisplay = rect,
2712 .clip = rect,
2713 .outputDataspace = ui::Dataspace::DISPLAY_P3,
2714 };
2715
2716 // Create an unpremul buffer that is green with no alpha. Using isOpaque
2717 // should make the green show.
2718 const auto buf = allocateSourceBuffer(1, 1);
2719 {
2720 uint8_t* pixels;
2721 buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2722 reinterpret_cast<void**>(&pixels));
2723 pixels[0] = 0;
2724 pixels[1] = 255;
2725 pixels[2] = 0;
2726 pixels[3] = 0;
2727 buf->getBuffer()->unlock();
2728 }
2729
2730 const renderengine::LayerSettings greenLayer{
2731 .geometry.boundaries = rect.toFloatRect(),
2732 .source =
2733 renderengine::PixelSource{
2734 .buffer =
2735 renderengine::Buffer{
2736 .buffer = buf,
2737 // Although the pixels are not
2738 // premultiplied in practice, this
2739 // matches the input we see.
2740 .usePremultipliedAlpha = true,
2741 .isOpaque = true,
2742 },
2743 },
2744 .alpha = 1.0f,
2745 };
2746
Sally Qi59a9f502021-10-12 18:53:23 +00002747 std::vector<renderengine::LayerSettings> layers{greenLayer};
Leon Scroggins IIIc4e0cbd2021-05-25 10:25:20 -04002748 invokeDraw(display, layers);
2749
2750 if (GetParam()->useColorManagement()) {
2751 expectBufferColor(rect, 117, 251, 76, 255);
2752 } else {
2753 expectBufferColor(rect, 0, 255, 0, 255);
2754 }
2755}
Alec Mouri4049b532021-10-15 20:59:33 -07002756
Alec Mouri4049b532021-10-15 20:59:33 -07002757TEST_P(RenderEngineTest, test_tonemapPQMatches) {
2758 if (!GetParam()->useColorManagement()) {
Alec Mouri5a493722022-01-26 16:43:02 -08002759 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002760 }
2761
Alec Mouri4049b532021-10-15 20:59:33 -07002762 initializeRenderEngine();
2763
Alec Mouri5a493722022-01-26 16:43:02 -08002764 tonemap(
2765 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 |
2766 HAL_DATASPACE_TRANSFER_ST2084 | HAL_DATASPACE_RANGE_FULL),
2767 [](vec3 color) { return EOTF_PQ(color); },
2768 [](vec3 color, float) {
2769 static constexpr float kMaxPQLuminance = 10000.f;
2770 return color * kMaxPQLuminance;
2771 });
2772}
Alec Mouri4049b532021-10-15 20:59:33 -07002773
Alec Mouri5a493722022-01-26 16:43:02 -08002774TEST_P(RenderEngineTest, test_tonemapHLGMatches) {
2775 if (!GetParam()->useColorManagement()) {
2776 GTEST_SKIP();
Alec Mouri4049b532021-10-15 20:59:33 -07002777 }
2778
Alec Mouri5a493722022-01-26 16:43:02 -08002779 initializeRenderEngine();
Alec Mouri4049b532021-10-15 20:59:33 -07002780
Alec Mouri5a493722022-01-26 16:43:02 -08002781 tonemap(
2782 static_cast<ui::Dataspace>(HAL_DATASPACE_STANDARD_BT2020 | HAL_DATASPACE_TRANSFER_HLG |
2783 HAL_DATASPACE_RANGE_FULL),
2784 [](vec3 color) { return EOTF_HLG(color); },
2785 [](vec3 color, float currentLuminaceNits) {
2786 static constexpr float kMaxHLGLuminance = 1000.f;
Alec Mouri7a577452022-03-04 23:41:38 +00002787 return color * kMaxHLGLuminance;
Alec Mouri5a493722022-01-26 16:43:02 -08002788 });
Alec Mouri4049b532021-10-15 20:59:33 -07002789}
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002790
2791TEST_P(RenderEngineTest, r8_behaves_as_mask) {
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002792 initializeRenderEngine();
2793
2794 const auto r8Buffer = allocateR8Buffer(2, 1);
2795 if (!r8Buffer) {
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05002796 GTEST_SKIP() << "Test is only necessary on devices that support r8";
Leon Scroggins III2c1d9ef2022-01-21 13:46:56 -05002797 return;
2798 }
2799 {
2800 uint8_t* pixels;
2801 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2802 reinterpret_cast<void**>(&pixels));
2803 // This will be drawn on top of a green buffer. We'll verify that 255
2804 // results in keeping the original green and 0 results in black.
2805 pixels[0] = 0;
2806 pixels[1] = 255;
2807 r8Buffer->getBuffer()->unlock();
2808 }
2809
2810 const auto rect = Rect(0, 0, 2, 1);
2811 const renderengine::DisplaySettings display{
2812 .physicalDisplay = rect,
2813 .clip = rect,
2814 .outputDataspace = ui::Dataspace::SRGB,
2815 };
2816
2817 const auto greenBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(0, 255, 0, 255));
2818 const renderengine::LayerSettings greenLayer{
2819 .geometry.boundaries = rect.toFloatRect(),
2820 .source =
2821 renderengine::PixelSource{
2822 .buffer =
2823 renderengine::Buffer{
2824 .buffer = greenBuffer,
2825 },
2826 },
2827 .alpha = 1.0f,
2828 };
2829 const renderengine::LayerSettings r8Layer{
2830 .geometry.boundaries = rect.toFloatRect(),
2831 .source =
2832 renderengine::PixelSource{
2833 .buffer =
2834 renderengine::Buffer{
2835 .buffer = r8Buffer,
2836 },
2837 },
2838 .alpha = 1.0f,
2839 };
2840
2841 std::vector<renderengine::LayerSettings> layers{greenLayer, r8Layer};
2842 invokeDraw(display, layers);
2843
2844 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
2845 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
2846}
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05002847
2848TEST_P(RenderEngineTest, r8_respects_color_transform) {
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05002849 initializeRenderEngine();
2850
2851 const auto r8Buffer = allocateR8Buffer(2, 1);
2852 if (!r8Buffer) {
2853 GTEST_SKIP() << "Test is only necessary on devices that support r8";
2854 return;
2855 }
2856 {
2857 uint8_t* pixels;
2858 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2859 reinterpret_cast<void**>(&pixels));
2860 pixels[0] = 0;
2861 pixels[1] = 255;
2862 r8Buffer->getBuffer()->unlock();
2863 }
2864
2865 const auto rect = Rect(0, 0, 2, 1);
2866 const renderengine::DisplaySettings display{
2867 .physicalDisplay = rect,
2868 .clip = rect,
2869 .outputDataspace = ui::Dataspace::SRGB,
2870 // Verify that the R8 layer respects the color transform when
2871 // deviceHandlesColorTransform is false. This transform converts
2872 // pure red to pure green. That will occur when the R8 buffer is
2873 // 255. When the R8 buffer is 0, it will still change to black, as
2874 // with r8_behaves_as_mask.
Alec Mouri9bcd1d12022-04-21 22:16:56 +00002875 .colorTransform = kRemoveGreenAndMoveRedToGreenMat4,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05002876 .deviceHandlesColorTransform = false,
2877 };
2878
2879 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
2880 const renderengine::LayerSettings redLayer{
2881 .geometry.boundaries = rect.toFloatRect(),
2882 .source =
2883 renderengine::PixelSource{
2884 .buffer =
2885 renderengine::Buffer{
2886 .buffer = redBuffer,
2887 },
2888 },
2889 .alpha = 1.0f,
2890 };
2891 const renderengine::LayerSettings r8Layer{
2892 .geometry.boundaries = rect.toFloatRect(),
2893 .source =
2894 renderengine::PixelSource{
2895 .buffer =
2896 renderengine::Buffer{
2897 .buffer = r8Buffer,
2898 },
2899 },
2900 .alpha = 1.0f,
2901 };
2902
2903 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
2904 invokeDraw(display, layers);
2905
2906 expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 255);
2907 expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
2908}
2909
2910TEST_P(RenderEngineTest, r8_respects_color_transform_when_device_handles) {
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05002911 initializeRenderEngine();
2912
2913 const auto r8Buffer = allocateR8Buffer(2, 1);
2914 if (!r8Buffer) {
2915 GTEST_SKIP() << "Test is only necessary on devices that support r8";
2916 return;
2917 }
2918 {
2919 uint8_t* pixels;
2920 r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
2921 reinterpret_cast<void**>(&pixels));
2922 pixels[0] = 0;
2923 pixels[1] = 255;
2924 r8Buffer->getBuffer()->unlock();
2925 }
2926
2927 const auto rect = Rect(0, 0, 2, 1);
2928 const renderengine::DisplaySettings display{
2929 .physicalDisplay = rect,
2930 .clip = rect,
2931 .outputDataspace = ui::Dataspace::SRGB,
2932 // If deviceHandlesColorTransform is true, pixels where the A8
2933 // buffer is opaque are unaffected. If the colorTransform is
2934 // invertible, pixels where the A8 buffer are transparent have the
2935 // inverse applied to them so that the DPU will convert them back to
2936 // black. Test with an arbitrary, invertible matrix.
2937 .colorTransform = mat4(1, 0, 0, 2,
2938 3, 1, 2, 5,
2939 0, 5, 3, 0,
2940 0, 1, 0, 2),
2941 .deviceHandlesColorTransform = true,
2942 };
2943
2944 const auto redBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(255, 0, 0, 255));
2945 const renderengine::LayerSettings redLayer{
2946 .geometry.boundaries = rect.toFloatRect(),
2947 .source =
2948 renderengine::PixelSource{
2949 .buffer =
2950 renderengine::Buffer{
2951 .buffer = redBuffer,
2952 },
2953 },
2954 .alpha = 1.0f,
2955 };
2956 const renderengine::LayerSettings r8Layer{
2957 .geometry.boundaries = rect.toFloatRect(),
2958 .source =
2959 renderengine::PixelSource{
2960 .buffer =
2961 renderengine::Buffer{
2962 .buffer = r8Buffer,
2963 },
2964 },
2965 .alpha = 1.0f,
2966 };
2967
2968 std::vector<renderengine::LayerSettings> layers{redLayer, r8Layer};
2969 invokeDraw(display, layers);
2970
2971 expectBufferColor(Rect(1, 0, 2, 1), 255, 0, 0, 255); // Still red.
2972 expectBufferColor(Rect(0, 0, 1, 1), 0, 70, 0, 255);
2973}
Leon Scroggins III45be9182022-04-27 10:37:11 -04002974
2975TEST_P(RenderEngineTest, primeShaderCache) {
Leon Scroggins III45be9182022-04-27 10:37:11 -04002976 initializeRenderEngine();
2977
2978 auto fut = mRE->primeCache();
2979 if (fut.valid()) {
2980 fut.wait();
2981 }
2982
2983 const int minimumExpectedShadersCompiled = GetParam()->useColorManagement() ? 60 : 30;
2984 ASSERT_GT(static_cast<skia::SkiaGLRenderEngine*>(mRE.get())->reportShadersCompiled(),
2985 minimumExpectedShadersCompiled);
2986}
Derek Sollenbergerd3f60652021-06-11 15:34:36 -04002987} // namespace renderengine
Alec Mouri6e57f682018-09-29 20:45:08 -07002988} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08002989
2990// TODO(b/129481165): remove the #pragma below and fix conversion issues
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01002991#pragma clang diagnostic pop // ignored "-Wconversion -Wextra"